001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.http.log; 019 020import java.io.BufferedReader; 021import java.io.IOException; 022import java.io.InputStreamReader; 023import java.io.PrintWriter; 024import java.net.URL; 025import java.net.URLConnection; 026import java.util.regex.Pattern; 027import javax.servlet.ServletException; 028import javax.servlet.http.HttpServlet; 029import javax.servlet.http.HttpServletRequest; 030import javax.servlet.http.HttpServletResponse; 031import org.apache.commons.logging.impl.Jdk14Logger; 032import org.apache.commons.logging.impl.Log4JLogger; 033import org.apache.hadoop.hbase.http.HttpServer; 034import org.apache.hadoop.util.ServletUtil; 035import org.apache.log4j.LogManager; 036import org.apache.yetus.audience.InterfaceAudience; 037import org.apache.yetus.audience.InterfaceStability; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040import org.slf4j.impl.Log4jLoggerAdapter; 041 042/** 043 * Change log level in runtime. 044 */ 045@InterfaceAudience.Private 046public final class LogLevel { 047 public static final String USAGES = "\nUsage: General options are:\n" 048 + "\t[-getlevel <host:httpPort> <name>]\n" 049 + "\t[-setlevel <host:httpPort> <name> <level>]\n"; 050 051 /** 052 * A command line implementation 053 */ 054 public static void main(String[] args) { 055 if (args.length == 3 && "-getlevel".equals(args[0])) { 056 process("http://" + args[1] + "/logLevel?log=" + args[2]); 057 return; 058 } 059 else if (args.length == 4 && "-setlevel".equals(args[0])) { 060 process("http://" + args[1] + "/logLevel?log=" + args[2] 061 + "&level=" + args[3]); 062 return; 063 } 064 065 System.err.println(USAGES); 066 System.exit(-1); 067 } 068 069 private static void process(String urlstring) { 070 try { 071 URL url = new URL(urlstring); 072 System.out.println("Connecting to " + url); 073 URLConnection connection = url.openConnection(); 074 connection.connect(); 075 try (InputStreamReader streamReader = new InputStreamReader(connection.getInputStream()); 076 BufferedReader bufferedReader = new BufferedReader(streamReader)) { 077 for(String line; (line = bufferedReader.readLine()) != null; ) { 078 if (line.startsWith(MARKER)) { 079 System.out.println(TAG.matcher(line).replaceAll("")); 080 } 081 } 082 } 083 } catch (IOException ioe) { 084 System.err.println("" + ioe); 085 } 086 } 087 088 static final String MARKER = "<!-- OUTPUT -->"; 089 static final Pattern TAG = Pattern.compile("<[^>]*>"); 090 091 /** 092 * A servlet implementation 093 */ 094 @InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"}) 095 @InterfaceStability.Unstable 096 public static class Servlet extends HttpServlet { 097 private static final long serialVersionUID = 1L; 098 099 @Override 100 public void doGet(HttpServletRequest request, HttpServletResponse response 101 ) throws ServletException, IOException { 102 103 // Do the authorization 104 if (!HttpServer.hasAdministratorAccess(getServletContext(), request, 105 response)) { 106 return; 107 } 108 109 PrintWriter out = ServletUtil.initHTML(response, "Log Level"); 110 String logName = ServletUtil.getParameter(request, "log"); 111 String level = ServletUtil.getParameter(request, "level"); 112 113 if (logName != null) { 114 out.println("<br /><hr /><h3>Results</h3>"); 115 out.println(MARKER 116 + "Submitted Log Name: <b>" + logName + "</b><br />"); 117 118 Logger log = LoggerFactory.getLogger(logName); 119 out.println(MARKER 120 + "Log Class: <b>" + log.getClass().getName() +"</b><br />"); 121 if (level != null) { 122 out.println(MARKER + "Submitted Level: <b>" + level + "</b><br />"); 123 } 124 125 if (log instanceof Log4JLogger) { 126 process(((Log4JLogger)log).getLogger(), level, out); 127 } else if (log instanceof Jdk14Logger) { 128 process(((Jdk14Logger)log).getLogger(), level, out); 129 } else if (log instanceof Log4jLoggerAdapter) { 130 process(LogManager.getLogger(logName), level, out); 131 } else { 132 out.println("Sorry, " + log.getClass() + " not supported.<br />"); 133 } 134 } 135 136 out.println(FORMS); 137 out.println(ServletUtil.HTML_TAIL); 138 } 139 140 static final String FORMS = "\n<br /><hr /><h3>Get / Set</h3>" 141 + "\n<form>Log: <input type='text' size='50' name='log' /> " 142 + "<input type='submit' value='Get Log Level' />" 143 + "</form>" 144 + "\n<form>Log: <input type='text' size='50' name='log' /> " 145 + "Level: <input type='text' name='level' /> " 146 + "<input type='submit' value='Set Log Level' />" 147 + "</form>"; 148 149 private static void process(org.apache.log4j.Logger log, String level, 150 PrintWriter out) throws IOException { 151 if (level != null) { 152 if (!level.equals(org.apache.log4j.Level.toLevel(level).toString())) { 153 out.println(MARKER + "Bad level : <b>" + level + "</b><br />"); 154 } else { 155 log.setLevel(org.apache.log4j.Level.toLevel(level)); 156 out.println(MARKER + "Setting Level to " + level + " ...<br />"); 157 } 158 } 159 out.println(MARKER 160 + "Effective level: <b>" + log.getEffectiveLevel() + "</b><br />"); 161 } 162 163 private static void process(java.util.logging.Logger log, String level, 164 PrintWriter out) throws IOException { 165 if (level != null) { 166 log.setLevel(java.util.logging.Level.parse(level)); 167 out.println(MARKER + "Setting Level to " + level + " ...<br />"); 168 } 169 170 java.util.logging.Level lev; 171 for(; (lev = log.getLevel()) == null; log = log.getParent()); 172 out.println(MARKER + "Effective level: <b>" + lev + "</b><br />"); 173 } 174 } 175 176 private LogLevel() {} 177}