Как настроить Logback с кодом Java для установки уровня журнала? - PullRequest
9 голосов
/ 01 ноября 2011

Я хочу использовать конфигурацию SLF4J + Logback по умолчанию, кроме настройки org.springframework.data.document.mongodb уровня ведения журнала на DEBUG.

Как я могу сделать это с помощью кода Java?

Я не использую XML, и это решение принято во время выполнения.

Ответы [ 2 ]

10 голосов
/ 02 ноября 2011

Следующее работает для меня, но, как правило, это не очень хорошая идея. Ваш код будет зависеть от 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");
5 голосов
/ 18 апреля 2013

В зависимости от logback-classic не очень хорошая идея, как сказал @palacsint. Вы можете достичь того, чего хотите, используя 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 .

...