public
Last active

Changing log level for logback-classic using reflection if it is present in the classpath without depending to the JAR.

  • Download Gist
LogbackUtils.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.MessageFormat;
 
/**
* Contains methods to access and manipulate logback framework dynamically at run-time. Here 'dynamically' means without
* referencing the logback JAR, but using it if found in the classpath.
*
* @author Muhammed Demirbas
* @since 19 Mar 2013
*/
public final class LogbackUtils
{
public static final String LOGBACK_CLASSIC = "ch.qos.logback.classic";
public static final String LOGBACK_CLASSIC_LOGGER = "ch.qos.logback.classic.Logger";
public static final String LOGBACK_CLASSIC_LEVEL = "ch.qos.logback.classic.Level";
private static final Logger logger = LoggerFactory.getLogger(LogbackUtils.class);
 
private LogbackUtils()
{
// Prevent instance creation
}
 
/**
* Dynamically sets the logback log level for the given class to the specified level.
*
* @param loggerName Name of the logger to set its log level. If blank, root logger will be used.
* @param logLevel One of the supported log levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL,
* OFF. {@code null} value is considered as 'OFF'.
*/
public static boolean setLogLevel(String loggerName, String logLevel)
{
String logLevelUpper = (logLevel == null) ? "OFF" : logLevel.toUpperCase();
 
try
{
Package logbackPackage = Package.getPackage(LOGBACK_CLASSIC);
if (logbackPackage == null)
{
logger.info("Logback is not in the classpath!");
return false;
}
 
// Use ROOT logger if given logger name is blank.
if ((loggerName == null) || loggerName.trim().isEmpty())
{
loggerName = (String) getFieldVaulue(LOGBACK_CLASSIC_LOGGER, "ROOT_LOGGER_NAME");
}
 
// Obtain logger by the name
Logger loggerObtained = LoggerFactory.getLogger(loggerName);
if (loggerObtained == null)
{
// I don't know if this case occurs
logger.warn("No logger for the name: {}", loggerName);
return false;
}
 
Object logLevelObj = getFieldVaulue(LOGBACK_CLASSIC_LEVEL, logLevelUpper);
if (logLevelObj == null)
{
logger.warn("No such log level: {}", logLevelUpper);
return false;
}
 
Class<?>[] paramTypes = { logLevelObj.getClass() };
Object[] params = { logLevelObj };
 
Class<?> clz = Class.forName(LOGBACK_CLASSIC_LOGGER);
Method method = clz.getMethod("setLevel", paramTypes);
method.invoke(loggerObtained, params);
 
logger.debug("Log level set to {} for the logger '{}'", logLevelUpper, loggerName);
return true;
}
catch (Exception e)
{
logger.warn("Couldn't set log level to {} for the logger '{}'", logLevelUpper, loggerName, e);
return false;
}
}
 
private static Object getFieldVaulue(String fullClassName, String fieldName)
{
try
{
Class<?> clazz = Class.forName(fullClassName);
Field field = clazz.getField(fieldName);
return field.get(null);
}
catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | NoSuchFieldException |
SecurityException ignored)
{
return null;
}
}
}
LogbackUtilsTest.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
import org.junit.Test;
 
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
 
public final class LogbackUtilsTest
{
@Test
public void testSetLogLevel() throws Throwable
{
assertEquals(true, LogbackUtils.setLogLevel(null, null)); // Set ROOT logger level to 'OFF'
assertEquals(true, LogbackUtils.setLogLevel(null, "TRACE")); // Set ROOT logger level to TRACE
assertEquals(true, LogbackUtils.setLogLevel(".", "DEBUG"));
assertEquals(true, LogbackUtils.setLogLevel(null, "INFO"));
assertEquals(true, LogbackUtils.setLogLevel(null, "WARN"));
assertEquals(false, LogbackUtils.setLogLevel(null, "WARNING")); // No such log level
assertEquals(false, LogbackUtils.setLogLevel(null, "")); // No such log level
assertEquals(false, LogbackUtils.setLogLevel(null, "-")); // No such log level
assertEquals(true, LogbackUtils.setLogLevel("org.", "DEBUG"));
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.