如何用Java代码配置Logback来设置日志级别?

发布于 2024-12-13 00:14:03 字数 158 浏览 3 评论 0原文

我想使用默认的 SLF4J + Logback 配置,除了将 org.springframework.data.document.mongodb 日志级别设置为 DEBUG 之外。

我怎样才能用Java代码做到这一点?

我没有使用 XML,并且这个决定是在运行时做出的。

I want to use default SLF4J + Logback configuration except setting org.springframework.data.document.mongodb logging level to DEBUG.

How can I do it with Java code?

I'm not using XML, and this decision made at runtime.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

就此别过 2024-12-20 00:14:03

以下内容对我有用,但通常这不是一个好主意。您的代码将依赖于 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");

The following works for me but generally this is not a good idea. Your code will depend on Logback (you can't choose another logging framework behind 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");
小霸王臭丫头 2024-12-20 00:14:03

正如 @palacsint 所说,依赖 logback-classic 并不是一个好主意。您可以使用 Java 的 Reflection API 来实现您想要的目的。请注意,由于使用了反射,这种方法会给您的程序带来一些开销。

用法:

LogbackUtils.setLogLevel("com.stackoverflow.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

Depending to logback-classic is not a good idea as @palacsint stated. You can achieve what you want using Java's Reflection API. Note that this approach puts some overhead to your program because of use of reflection.

Usage:

LogbackUtils.setLogLevel("com.stackoverflow.sample", "DEBUG")

Code:

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.

Full code including tests: Github Gist.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文