如何使用 Java 代码配置 Logback 以设置日志级别?
Posted
技术标签:
【中文标题】如何使用 Java 代码配置 Logback 以设置日志级别?【英文标题】:How to configure Logback with Java code to set log level? 【发布时间】:2011-12-19 12:15:49 【问题描述】:我想使用默认的 SLF4J + Logback 配置,除了将 org.springframework.data.document.mongodb
日志级别设置为 DEBUG
。
如何用 Java 代码做到这一点?
我没有使用 XML,这个决定是在运行时做出的。
【问题讨论】:
我希望会有更好的答案:这也适用于单元/功能/集成测试,人们经常希望在测试期间抑制噪音。不得不使用配置文件有点痛苦。 【参考方案1】:以下内容对我有用,但通常这不是一个好主意。您的代码将依赖于 Logback(您不能选择 SLF4J 之后的其他日志框架)。
final org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger("test.package");
if (!(logger instanceof ch.qos.logback.classic.Logger))
return;
ch.qos.logback.classic.Logger logbackLogger =
(ch.qos.logback.classic.Logger) logger;
logbackLogger.setLevel(ch.qos.logback.classic.Level.TRACE);
logger.trace("some log");
【讨论】:
如果你使用类名而不是包,上述方法将不起作用,因为获取的记录器是不同的实例。但是在使用包时,它是可以的,因为日志级别会传播给子级。【参考方案2】:正如@palacsint 所说,依赖于logback-classic
并不是一个好主意。您可以使用 Java 的反射 API 实现您想要的。请注意,由于使用反射,这种方法会给您的程序带来一些开销。
用法:
LogbackUtils.setLogLevel("com.***.sample", "DEBUG")
代码:
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);
/**
* 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) getFieldValue(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 = getFieldValue(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;
// getFieldValue() method omitted for bravity from here,
// but available at GitHub link below.
包含测试的完整代码:Github Gist。
【讨论】:
以上是关于如何使用 Java 代码配置 Logback 以设置日志级别?的主要内容,如果未能解决你的问题,请参考以下文章