【问题标题】:How to use Logback directly without going through SLF4J如何不经过SLF4J直接使用Logback
【发布时间】:2012-04-12 19:15:21
【问题描述】:

我正在尝试调整一些 logback 功能(自定义 Appender 等)。为了测试它,我想配置 Logback 并直接调用它的日志记录方法而不通过 sl4j。

这个奇怪要求的原因是能够在其他 SLF4J 桥可用的环境中测试 logback 功能。

所以我想做invoking JoranConfigurator directly 时描述的东西,而不参考 SLF4J。

【问题讨论】:

    标签: java testing logging slf4j logback


    【解决方案1】:

    有办法找出来。

    这是如何配置 LOGBack 的示例

    // Here we create context
    LoggerContext loggerContext = new LoggerContext();
    // Initializer is used to enrich context with details
    ContextInitializer contextInitializer = new ContextInitializer(loggerContext);
    try {
        // Get a configuration file from classpath
        URL configurationUrl = Thread.currentThread().getContextClassLoader().getResource("custom-logback-configuration.xml");
        if (configurationUrl == null) {
            throw new IllegalStateException("Unable to find custom logback configuration file");
        }
        // Ask context initializer to load configuration into context
        contextInitializer.configureByResource(configurationUrl);
        // Here we get logger from context
        logger = loggerContext.getLogger(LogReporter.class);
    } catch (JoranException e) {
        throw new RuntimeException("Unable to configure logger", e);
    }
    

    一般而言,如果您想了解任何 SLF4J 后端的工作原理,您可能只需查看该后端的 org.slf4j.impl.StaticLoggerBinder 类源代码。

    【讨论】:

    • 这在我需要明确设置 Logback '环境'(上下文)而不依赖 SLF4J 绑定的类似上下文中非常适合我(因为 SLF4J 已经绑定到 log4j 而我没有t 有权访问类路径,以便能够通过使用各种 SLF4J 桥或类似物来更改它)。
    【解决方案2】:

    不幸的是,我认为这是不可能的。如果您查看Logback Logger source(或其他类),您会发现它依赖于 slf4j。

    这不好,恕我直言,因为 logback 应该不知道 slf4j。

    【讨论】:

    • 其实它可能不依赖于 slf4j。它可能只是对 slf4j 接口的静态绑定。 NATIVE IMPLEMENTATION There are also SLF4J bindings external to the SLF4J project, e.g. logback which implements SLF4J natively. Logback's ch.qos.logback.classic.Logger class is a direct implementation of SLF4J's org.slf4j.Logger interface. Thus, using SLF4J in conjunction with logback involves strictly zero memory and computational overhead.slf4j.org/manual.html
    【解决方案3】:

    没试过,但看起来是对的,也许会有所帮助:

    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    ch.qos.logback.classic.Logger log = lc.getLogger(foo.Bar.class);
    

    ch.qos.logback.classic.Logger 实现了org.slf4j.Logger,但您可以直接使用它。您可能需要以不同方式获取LoggerContext

    【讨论】:

    • LoggerFactory 是 slf4j 的一部分,它使用了各种桥接实现附带的类 StaticLoggerBinder,所以我仍然使用 slf4j 的绑定机制。
    • @JensSchauder:简单地创建 new LoggerContext() 并完全避免 SLF4J API 怎么样?
    • 我正在开发一个 API,我根本无法使用 SLF4j,是否可以单独使用 logback?
    • LoggerContext logCtx = new LoggerContext(); 为我工作。为什么 java 必须让日志成为一个活生生的地狱?!
    【解决方案4】:

    我正在尝试调整一些 logback 功能(自定义 Appender 等)。为了测试它,我想配置 Logback 并直接调用它的日志记录方法而不通过 sl4j。

    我需要做同样的事情。看了logback-classic和core之后,我认为正确的答案是:

    // although in the slf4j package, this class is part of logback-classic
    ILoggerFactory factory =
          org.slf4j.impl.StaticLoggerBinder.getSingleton().getLoggerFactory();
    

    如果您查看 logback-classic 包含的 StaticLoggerBinder.init(),您可以看到它调用:

    new ContextInitializer(defaultLoggerContext).autoConfig();
    

    这会找到配置文件,加载它等等。

    注意:org.slf4j.impl.StaticLoggerBinder 也在 slf4j jar 中,因此如果您同时测试两者,则需要确保 logback 在类路径上位于 slf4j 之前。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      • 2017-05-06
      • 2015-02-04
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多