gpt4 book ai didi

java - logback:如何设置每个线程的日志记录级别?

转载 作者:行者123 更新时间:2023-11-30 08:13:09 35 4
gpt4 key购买 nike

我有一个多线程 Java 应用程序,每个线程都是一个扩展基类的类,该基类扩展 Thread。其中一个线程偶尔会为基类中的方法提供大量机器生成的数据,而其他线程则只提供少量人工输入的数据。我想在比机器数据更高的日志级别上记录这些人工输入的消息,但由于基类是所有线程的一部分,我无法在代码中区分它。

一个解决方案是通知扩展类的基类在不同的级别上登录,但是我必须将这些知识硬编码到应用程序中,这很丑陋。

我想做的是通过我的 logback.xml 配置“引导”它。

我写了一个小复制器:

package x.y.z;
import org.slf4j.*;

public class Quickie {
static final Logger LOG = LoggerFactory.getLogger(Quickie.class);

public static void main(String[] args) throws Exception {

MyThread t1 = new MyThread("hi");
MyThread t2 = new MyThread("bye");

t1.start(); t2.start();
}
}

class MyThread extends Thread {
static final Logger LOG = LoggerFactory.getLogger(MyThread.class);

public MyThread(final String name) { this.setName(name); }

public void run() { logSomething(); }

public void logSomething() {
LOG.trace(getName()); LOG.error(getName());
}
}

这是 logback 配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{HH:mm:ss} %-6level %-10([%thread]) %logger{1}.%method:%line %message%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
</appender>

<root level="TRACE">
<appender-ref ref="STDOUT" />
</root>
</configuration>

最重要的是,编码器模式是:

            <pattern>%date{HH:mm:ss} %-6level %-10([%thread]) %logger{1}.%method:%line %message%n</pattern>

因为这清楚地显示了线程:

11:16:09 TRACE  [bye]      c.t.k.t.MyThread.logSomething:24 bye
11:16:09 TRACE [hi] c.t.k.t.MyThread.logSomething:24 hi
11:16:09 ERROR [bye] c.t.k.t.MyThread.logSomething:24 bye
11:16:09 ERROR [hi] c.t.k.t.MyThread.logSomething:24 hi

...我想说应该有一种方法可以配置我的 logback.xml,让“bye”线程只登录信息或更高级别,而“hi”线程从跟踪或更高级别登录?我花了半天的时间在谷歌上搜索和阅读 logback 文档,我尝试了 sifters 和正则表达式过滤器以及许多其他示例,但显然它们都只是继续处理消息。这意味着一种解决方案可能是在消息中出现一个神奇的字符串并将其过滤掉,但这也很丑陋。

那么,有没有一种方法可以从日志配置中控制每个线程的日志级别,而无需将“专用代码”注入(inject)应用程序?

最佳答案

我认为您可以为此目的使用 MDC 和 TurboFilter。

run() 方法中添加对 MDC.put() 的调用,如下所示:

public void run() {
MDC.put("threadname", this.getName());
logSomething();
}

如果你想让“bye”线程只记录 info 或更高级别的日志,而“hi”线程从 trace 或更高级别的日志记录,你必须将 DynamicThresholdFilter 的定义添加到 logback.xml:

<configuration>
<turboFilter class="ch.qos.logback.classic.turbo.DynamicThresholdFilter">
<Key>threadname</Key>
<!-- You can set default threshold as you like -->
<DefaultThreshold>TRACE</DefaultThreshold>
<MDCValueLevelPair>
<value>bye</value>
<level>info</level>
</MDCValueLevelPair>
<MDCValueLevelPair>
<value>hi</value>
<level>trace</level>
</MDCValueLevelPair>
</turboFilter>
......
</configuration>

关于java - logback:如何设置每个线程的日志记录级别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114303/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com