在 slf4j 中设置运行时消息的日志级别

2022-08-31 08:54:45

使用 log4j 时,该方法可用,可用于在运行时确定的日志级别记录消息。我们正在使用这个事实和这个技巧将stderr重定向到特定日志级别的记录器。Logger.log(Priority p, Object message)

slf4j没有我能找到的通用方法。这是否意味着没有办法实现上述内容?log()


答案 1

没有办法用slf4j 1.x做到这一点。

我想缺少此功能的原因是,几乎不可能为slf4j构造一个可以有效地映射到外观后面所有可能的日志记录实现中使用的(或等效)类型的类型。或者,设计人员认为您的用例太不寻常,无法证明支持它的开销是合理的。LevelLevel

关于@ripper234用例(单元测试),我认为务实的解决方案是修改单元测试,以硬连线了解slf4j门面后面的日志记录系统......运行单元测试时。


更新

他们打算在slf4j 2.0中实现日志记录事件(具有动态日志记录级别)的零碎构造;见 https://jira.qos.ch/browse/SLF4J-124。根据@Ceki(参见注释),它是在2.0.0-alpha2版本中实现的。


答案 2

理查德·费恩(Richard Fearn)的想法是正确的,所以我根据他的骨架代码编写了完整的课程。希望它足够短,可以在这里发布。复制和粘贴以享受。我可能还应该添加一些神奇的咒语:“此代码已发布到公共领域”

import org.slf4j.Logger;

public class LogLevel {

    /**
     * Allowed levels, as an enum. Import using "import [package].LogLevel.Level"
     * Every logging implementation has something like this except SLF4J.
     */

    public static enum Level {
        TRACE, DEBUG, INFO, WARN, ERROR
    }

    /**
     * This class cannot be instantiated, why would you want to?
     */

    private LogLevel() {
        // Unreachable
    }

    /**
     * Log at the specified level. If the "logger" is null, nothing is logged.
     * If the "level" is null, nothing is logged. If the "txt" is null,
     * behaviour depends on the SLF4J implementation.
     */

    public static void log(Logger logger, Level level, String txt) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(txt);
                break;
            case DEBUG:
                logger.debug(txt);
                break;
            case INFO:
                logger.info(txt);
                break;
            case WARN:
                logger.warn(txt);
                break;
            case ERROR:
                logger.error(txt);
                break;
            }
        }
    }

    /**
     * Log at the specified level. If the "logger" is null, nothing is logged.
     * If the "level" is null, nothing is logged. If the "format" or the "argArray"
     * are null, behaviour depends on the SLF4J-backing implementation.
     */

    public static void log(Logger logger, Level level, String format, Object[] argArray) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(format, argArray);
                break;
            case DEBUG:
                logger.debug(format, argArray);
                break;
            case INFO:
                logger.info(format, argArray);
                break;
            case WARN:
                logger.warn(format, argArray);
                break;
            case ERROR:
                logger.error(format, argArray);
                break;
            }
        }
    }

    /**
     * Log at the specified level, with a Throwable on top. If the "logger" is null,
     * nothing is logged. If the "level" is null, nothing is logged. If the "format" or
     * the "argArray" or the "throwable" are null, behaviour depends on the SLF4J-backing
     * implementation.
     */

    public static void log(Logger logger, Level level, String txt, Throwable throwable) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(txt, throwable);
                break;
            case DEBUG:
                logger.debug(txt, throwable);
                break;
            case INFO:
                logger.info(txt, throwable);
                break;
            case WARN:
                logger.warn(txt, throwable);
                break;
            case ERROR:
                logger.error(txt, throwable);
                break;
            }
        }
    }

    /**
     * Check whether a SLF4J logger is enabled for a certain loglevel. 
     * If the "logger" or the "level" is null, false is returned.
     */

    public static boolean isEnabledFor(Logger logger, Level level) {
        boolean res = false;
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                res = logger.isTraceEnabled();
                break;
            case DEBUG:
                res = logger.isDebugEnabled();
                break;
            case INFO:
                res = logger.isInfoEnabled();
                break;
            case WARN:
                res = logger.isWarnEnabled();
                break;
            case ERROR:
                res = logger.isErrorEnabled();
                break;
            }
        }
        return res;
    }
}

推荐