使用 log4j 时, Logger.log(Priority p, Object message)
方法可用,可用于在运行时确定的日志级别记录消息。我们正在使用这个事实和 这个技巧 将 stderr 重定向到特定日志级别的记录器。
slf4j 没有我能找到的通用 log()
方法。这是否意味着没有办法实现上述内容?
原文由 Edward Dale 发布,翻译遵循 CC BY-SA 4.0 许可协议
使用 log4j 时, Logger.log(Priority p, Object message)
方法可用,可用于在运行时确定的日志级别记录消息。我们正在使用这个事实和 这个技巧 将 stderr 重定向到特定日志级别的记录器。
slf4j 没有我能找到的通用 log()
方法。这是否意味着没有办法实现上述内容?
原文由 Edward Dale 发布,翻译遵循 CC BY-SA 4.0 许可协议
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;
}
}
原文由 David Tonhofer 发布,翻译遵循 CC BY-SA 3.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
使用 slf4j 1.x 无法做到这一点。
我想这个功能缺失的原因是几乎不可能为 slf4j 构造一个
Level
类型,它可以有效地映射到Level
(或等效)类型使用在外观背后的所有可能的日志记录实现中。或者,设计人员认为 您的用例太不寻常,无法证明支持它的开销是合理的。关于 @ripper234 的 用例(单元测试),我认为实用的解决方案是修改单元测试以硬连线了解 slf4j 外观背后的日志系统……在运行单元测试时。
更新
他们打算在 slf4j 2.0 中实现日志事件的零碎构建(具有动态日志级别);请参阅 https://jira.qos.ch/browse/SLF4J-124 。根据@Ceki(见评论),它在 2.0.0-alpha2 版本中实现。