我有一个多线程Java应用程序,每个线程都是一个扩展一个扩展Thread的基类的类。其中一个线程偶尔会在基类中为方法提供大量机器生成的数据,而其他线程只提供人类数据的小涓涓细流。我想在比计算机数据更高的loglevel上记录那些人类型消息,但由于基类是所有线程的一部分,我无法在代码中区分它。
一种解决方案是从扩展类通知基类登录到不同的级别,但是我必须将这些知识硬编码到应用程序中,这很难看。
我想做的是通过我的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让“再见”线程只登录信息或更高,而“hi”线程从跟踪或更高的日志?我花了半天谷歌搜索和阅读logback文档,我尝试了sifters和正则表达式过滤器和许多其他示例,但他们都只是继续消息,显然。这意味着一个解决方案可能是在消息中显示一个神奇的字符串并将其过滤掉,但这也很难看。
那么,有没有办法在日志配置中引导每个线程的日志级别而不必将“专用代码”注入应用程序?
答案 0 :(得分:3)
我认为您可以将MDC和TurboFilter用于此目的。
在MDC.put()
方法中添加run()
来电,如下所示:
public void run() {
MDC.put("threadname", this.getName());
logSomething();
}
如果你想要&#34; bye&#34;线程只登录信息或更高,&#34; hi&#34;来自跟踪或更高级别的线程日志,您必须将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>
答案 1 :(得分:0)
在这种情况下,我认为你需要声明另一个appender&amp;带有阈值信息的记录器。因为appender本身不知道它将被调用什么线程。