【发布时间】:2015-07-18 19:22:33
【问题描述】:
我有一个多线程 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 让“再见”线程只登录信息或更高版本,而“嗨”线程从跟踪或更高版本记录?我花了半天时间在谷歌上搜索和阅读 logback 文档,并尝试了 sifters 和 regex 过滤器以及许多其他示例,但显然它们都只是在传递信息。这意味着一种解决方案可能是在消息中出现一个神奇的字符串并将其过滤掉,但这也很丑陋。
那么,有没有一种方法可以在日志配置中控制每个线程的日志级别,而无需将“专用代码”注入应用程序?
【问题讨论】:
-
这听起来是一个使用标记的好案例。
标签: java multithreading logback