强制slf4j使用logback

问题描述 投票:0回答:3

有没有办法强制 slf4j 使用特定的日志记录提供程序(在我的例子中是 logback)?正如他们的文档中所示:

在类路径上发现多个绑定

SLF4J API 旨在一次与一个且仅一个底层日志框架绑定。如果类路径上存在多个绑定,SLF4J 将发出警告,列出这些绑定的位置。 当类路径上有多个绑定可用时,请选择一个且仅一个您要使用的绑定,并删除其他绑定。例如,如果类路径上有 slf4j->simple-1.6.6.jar 和 slf4j-nop-1.6.6.jar,并且您希望使用 nop(>no-operation)绑定,则删除 slf4j-来自类路径的 simple-1.6.6.jar。如果无法删除多余的绑定,SLF4J 仍将与一个日志框架/实现绑定。从版本 1.6.6 开始,SLF4J 将命名它实际绑定到的框架/实现类。

注意 SLF4J 发出的警告只是一个警告。

就我而言,我有

log4j.jar
slf4j-log4j12.jar
log4j-over-slf4j.jar
以及类路径中的所有 logback jar。我知道将
slf4j-log4j12.jar
log4j-over-slf4j.jar
放在一起是错误的,但是我的项目非常大,查找和排除 Maven 依赖项并不总是那么简单。在这种情况下,slf4j 甚至没有打印任何警告,因为我们只使用 logback 配置。我花了一天时间才理解这个罐子地狱。

我想要的只是通过 JVM 参数强制 slf4j 使用 logback,这样它就可以打印警告,并且我可以在将来排除 jar。

logging log4j slf4j logback
3个回答
36
投票

通常您自己的代码位于类路径的开头。因此,一种方法是创建您自己的 org.slf4j.impl.StaticLoggerBinder 类:

package org.slf4j.impl;

import org.slf4j.ILoggerFactory;
import org.slf4j.spi.LoggerFactoryBinder;

/**
 * Force tests to use JDK14 for logging.
 */
@SuppressWarnings("UnusedDeclaration")
public class StaticLoggerBinder implements LoggerFactoryBinder {
    private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();

    public static String REQUESTED_API_VERSION = "1.6";

    public static final StaticLoggerBinder getSingleton() {
      return SINGLETON;
    }

    private StaticLoggerBinder() {
    }

    @Override
    public ILoggerFactory getLoggerFactory() {
        return new JDK14LoggerFactory();
    }

    @Override
    public String getLoggerFactoryClassStr() {
        return "org.slf4j.impl.JDK14LoggerFactory";
    }
}

19
投票

除了清理类路径之外,没有办法强制 SLF4J 与给定的实现绑定。

更新:从 SLF4J 版本 2.0.9 开始,您可以通过“slf4j.provider”系统属性显式指定提供程序类。这绕过了寻找提供者的服务加载器机制,并可能缩短 SLF4J 初始化时间。


3
投票

我相信,如果您将 logback JAR 放在类路径的开头(或在包含 slf4j impl 的其他 JAR 之前),那么它将被使用。

但是,如果 slf4j 支持指定包含 impl 的 JAR 的 JVM 参数,并覆盖在类路径中查找,那就太好了,这样您就不必对类路径中的 JAR 进行排序以确保您想要的是使用过。

© www.soinside.com 2019 - 2024. All rights reserved.