【问题标题】:How to programmatically setup slf4j logger with SLF4JBridgeHandler如何使用 SLF4JBridgeHandler 以编程方式设置 slf4j 记录器
【发布时间】:2017-03-20 19:26:43
【问题描述】:

我正在尝试设置 slf4j 来拦截所有日志记录语句,然后根据特定条件以编程方式添加处理程序。我的代码是:

private void init()
{
    SLF4JBridgeHandler.removeHandlersForRootLogger();
    SLF4JBridgeHandler.install();

    if(condition1)
        appendHandler(console, Level.DEBUG);
    if(condition2)
        appendHandler(logfile1, Level.INFO);
    ...
}

如何编写appendHandler 方法的代码?我刚刚花了几个小时试图通读文档但找不到解决方案。有很多关于如何在配置文件中而不是在代码中执行此操作的参考资料。

我是否也正确,因为这段代码拦截了所有不同日志框架的所有日志语句?

【问题讨论】:

  • 查看link
  • 基本上SLF4JBridgeHandler 只是将所有 JUL 日志记录路由到 SLF4J API。所以首先代码不会拦截所有不同的日志框架,而只会拦截java.util.logging。还调用SLF4JBridgeHandler.install();为你添加了一个handler,那么你需要什么样的handler呢?

标签: java logging slf4j


【解决方案1】:

我是否也正确,因为这段代码拦截了所有不同日志框架的所有日志语句?

SLF4JBridgeHandler 是一个java.util.logging (JUL) 日志桥,它将“拦截”JUL 日志语句并将它们路由到 SLF4J。

其他可用的网桥是jcl-over-slf4j(Jakarta Commons Logging => SL4J)和log4j-over-slf4j(Log4J => SL4J)(以及它们的 SLF4J => X 对应物)。

根据您的代码中使用的日志框架(直接或间接),您可能希望包含其中的部分或全部, 捕获所有的日志记录语句,详见here

如何编写 appendHandler 方法的代码?

使用 SLF4J(例如 Logback)作为您的主要日志框架

一旦你设置了你的网桥,你就可以用通常的方式配置你的 SLF4J 实现了。

以下是如何为Logback 执行此操作的示例:

//Install the JUL Bridge
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();

//Obtain an instance of LoggerContext
LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory();

//Create a new FileAppender
FileAppender<ILoggingEvent> file = new FileAppender<ILoggingEvent>();
file.setName("FileLogger");
file.setFile("error.log");
file.setContext(context);
file.setAppend(true);

//Filter out anything < WARN
ThresholdFilter warningFilter = new ThresholdFilter();
warningFilter.setLevel("WARN");
warningFilter.setContext(context);
warningFilter.start();
file.addFilter(warningFilter);

//Message Encoder
PatternLayoutEncoder ple = new PatternLayoutEncoder();
ple.setContext(context);
ple.setPattern("%date %level [%thread] %logger{10} %msg%n");
ple.start();
file.setEncoder(ple);

file.start();

//Get ROOT logger, and add appender to it
Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME);
root.setLevel(Level.DEBUG);
root.addAppender(file);

使用 JUL 作为主要的日志框架

如果你想要使用 JUL (java.util.logging) 作为你的主要日志框架, 您根本不需要注册 SLF4JBridgeHandler

只需像往常一样配置 JUL 处理程序,并将 slf4j-jdk14(即 SLF4J => JUL)桥添加到您的依赖项列表中。

//Create a new Handler
Handler fh = new FileHandler("error.log");
fh.setLevel(Level.WARNING);

//Register it with the ROOT logger
Logger.getLogger("").addHandler(fh);

//Log some messages
Logger.getLogger("scratchpad").info("Info !");
Logger.getLogger("scratchpad").warning("Warning !");
Logger.getLogger("scratchpad").severe("Severe !");

//Log some messages via SL4J 
LoggerFactory.getLogger("scratchpad").error("sl4j message");

这样,任何 SL4J 日志语句都将被重定向到适当的 JUL 处理程序(您可能还想在混合中添加 jcl-over-slf4jlog4j-over-sl4j) .

【讨论】:

  • 最后两行对我不起作用。 Logger 接口不提供这两种方法。 root.setLevel(Level.DEBUG); root.addAppender(file);
  • @RichardBurkhardt 确保您已导入“ch.qos.logback.classic.Logger”(Logback 实现类)而不是 SL4J Logger(“org.sl4j.Logger”)(或只需使用 FQN 类名)。
猜你喜欢
  • 2012-02-16
  • 2020-11-30
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-22
  • 1970-01-01
相关资源
最近更新 更多