HADOOP-18653. LogLevel servlet to determine log impl before using setLevel (#5456)
The log level can only be set on Log4J log implementations; probes are used to downgrade to a warning when other logging back ends are used Contributed by Viraj Jasani
This commit is contained in:
parent
09469bf47d
commit
aff840c59c
|
@ -34,6 +34,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.apache.hadoop.classification.VisibleForTesting;
|
||||
import org.apache.hadoop.thirdparty.com.google.common.base.Charsets;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.hadoop.HadoopIllegalArgumentException;
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
|
@ -44,6 +46,7 @@ import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
|
|||
import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
|
||||
import org.apache.hadoop.security.ssl.SSLFactory;
|
||||
import org.apache.hadoop.util.GenericOptionsParser;
|
||||
import org.apache.hadoop.util.GenericsUtil;
|
||||
import org.apache.hadoop.util.ServletUtil;
|
||||
import org.apache.hadoop.util.Tool;
|
||||
import org.apache.hadoop.util.ToolRunner;
|
||||
|
@ -338,14 +341,18 @@ public class LogLevel {
|
|||
out.println(MARKER
|
||||
+ "Submitted Class Name: <b>" + logName + "</b><br />");
|
||||
|
||||
Logger log = Logger.getLogger(logName);
|
||||
org.slf4j.Logger log = LoggerFactory.getLogger(logName);
|
||||
out.println(MARKER
|
||||
+ "Log Class: <b>" + log.getClass().getName() +"</b><br />");
|
||||
if (level != null) {
|
||||
out.println(MARKER + "Submitted Level: <b>" + level + "</b><br />");
|
||||
}
|
||||
|
||||
process(log, level, out);
|
||||
if (GenericsUtil.isLog4jLogger(logName)) {
|
||||
process(Logger.getLogger(logName), level, out);
|
||||
} else {
|
||||
out.println("Sorry, setting log level is only supported for log4j loggers.<br />");
|
||||
}
|
||||
}
|
||||
|
||||
out.println(FORMS);
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.hadoop.util;
|
|||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
|
@ -33,6 +34,14 @@ import org.slf4j.LoggerFactory;
|
|||
@InterfaceStability.Unstable
|
||||
public class GenericsUtil {
|
||||
|
||||
private static final String SLF4J_LOG4J_ADAPTER_CLASS = "org.slf4j.impl.Log4jLoggerAdapter";
|
||||
|
||||
/**
|
||||
* Set to false only if log4j adapter class is not found in the classpath. Once set to false,
|
||||
* the utility method should not bother re-loading class again.
|
||||
*/
|
||||
private static final AtomicBoolean IS_LOG4J_LOGGER = new AtomicBoolean(true);
|
||||
|
||||
/**
|
||||
* Returns the Class object (of type <code>Class<T></code>) of the
|
||||
* argument of type <code>T</code>.
|
||||
|
@ -87,12 +96,27 @@ public class GenericsUtil {
|
|||
if (clazz == null) {
|
||||
return false;
|
||||
}
|
||||
Logger log = LoggerFactory.getLogger(clazz);
|
||||
return isLog4jLogger(clazz.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the log of the given logger is of Log4J implementation.
|
||||
*
|
||||
* @param logger the logger name, usually class name as string.
|
||||
* @return true if the logger uses Log4J implementation.
|
||||
*/
|
||||
public static boolean isLog4jLogger(String logger) {
|
||||
if (logger == null || !IS_LOG4J_LOGGER.get()) {
|
||||
return false;
|
||||
}
|
||||
Logger log = LoggerFactory.getLogger(logger);
|
||||
try {
|
||||
Class log4jClass = Class.forName("org.slf4j.impl.Log4jLoggerAdapter");
|
||||
Class<?> log4jClass = Class.forName(SLF4J_LOG4J_ADAPTER_CLASS);
|
||||
return log4jClass.isInstance(log);
|
||||
} catch (ClassNotFoundException e) {
|
||||
IS_LOG4J_LOGGER.set(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ public class TestGenericsUtil {
|
|||
|
||||
@Test
|
||||
public void testIsLog4jLogger() throws Exception {
|
||||
assertFalse("False if clazz is null", GenericsUtil.isLog4jLogger(null));
|
||||
assertFalse("False if clazz is null", GenericsUtil.isLog4jLogger((Class<?>) null));
|
||||
assertTrue("The implementation is Log4j",
|
||||
GenericsUtil.isLog4jLogger(TestGenericsUtil.class));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue