【问题标题】:Wrapping the slf4j API包装 slf4j API
【发布时间】:2010-08-16 08:52:56
【问题描述】:

我想将带有 Logback 的 slf4j 改造为旧版应用程序。好消息是,遗留应用程序有自己的日志框架。所以我所要做的就是改变日志框架以记录到 slf4j 而不是 log4j。

它像梦一样工作。我很高兴,直到我注意到 Logback 为每个日志事件记录的位置:

Logger.java:...

哎呀!在尝试找出日志事件的来源时,这对我的开发人员同伴帮助不大。

我如何告诉 Logback 在堆栈中向上查找几级以找到要记录的实际位置?

记录器类是一个实用类,其方法如下:

public static void debug(String clazz, String message) {
    org.slf4j.Logger logger = LoggerFactory.getLogger(clazz);
    logger.debug(message);
}

【问题讨论】:

  • 在使用 log4j 的时候有这个工作吗?我认为由于您更新了现有的日志记录类,因此您没有向调用堆栈添加额外的帧,因此 log4j 版本应该出现同样的问题。
  • log4j 在其公共 API 中公开了一个日志方法,该方法在堆栈中查找额外的帧,而 slf4j 没有。所以是的,它适用于 log4j。

标签: java legacy logback slf4j


【解决方案1】:

查看jcl-over-slf4j 的来源找到了解决方案。 slf4j 的大多数实现(包括 logback)使用实现 LocationAwareLogger 的记录器,它有一个 log 方法,期望包装记录器类的完全限定类名作为它的参数之一:

private static final String FQCN = Logger.class.getName();


public static void debug(String clazz, String message) {
    org.slf4j.Logger logger = LoggerFactory.getLogger(clazz);
    if (logger instanceof LocationAwareLogger) {
        ((LocationAwareLogger) logger).log(null, FQCN, LocationAwareLogger.DEBUG_INT, message, null, null);
    } else {
        logger.debug(message);
    }
}

【讨论】:

  • 很好的答案。我正在寻找 log4j 绑定的解决方案并找到了 Log4jLoggerAdapter。太糟糕了,包装器不支持消息格式。
【解决方案2】:

请参阅各种 XXX-over-slf4j 实现以了解如何操作。

基本上你想替换你当前的记录器框架。不换行 slf4j。

编辑:

另一种方法可能是编写自己的布局子类化您现在使用的布局,它对 %m、%l 等字段的含义进行了修改,从而跳过了额外的堆栈帧。

【讨论】:

  • 我考虑过那个解决方案,但目前没有预算来替换分散在 50 多个项目中的 10000 多个日志语句。
  • 您不需要更改日志语句,但它调用的代码(希望在库中)
  • 记录器框架有 10000 多个来自所有项目的方法调用。那么如果我替换了记录器框架,我是否也必须替换所有对它的方法调用?
  • 如果您将记录器框架替换为另一个行为相同(提供相同接口、类和方法)但行为类似于 slf4j 的其他仿真器框架之一的记录器框架,它应该为您提供所需的行为。否则创建您自己的布局 - 请参阅更新的答案。
猜你喜欢
  • 2015-09-17
  • 2019-12-08
  • 1970-01-01
  • 2012-12-11
  • 2018-12-12
  • 2012-12-06
  • 1970-01-01
  • 2016-03-12
  • 2014-05-18
相关资源
最近更新 更多