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

Java logback:如何设置每个线程的日志记录级别?,java,multithreading,logback,Java,Multithreading,Logback,我有一个多线程Java应用程序,每个线程都是一个扩展基类的类,扩展线程。其中一个线程偶尔会向基类中的方法提供大量机器生成的数据,而其他线程只提供少量人工类型的数据。我想在比机器数据更高的日志级别上记录这些人工输入的消息,但是由于基类是所有线程的一部分,我无法在代码中区分这一点 一种解决方案是通知扩展类中的基类登录到另一个级别,但是我必须将这些知识硬编码到应用程序中,这很难看 我想做的是通过logback.xml配置“引导”这一点 我写了一个小型复制机: package x.y.z; import

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

一种解决方案是通知扩展类中的基类登录到另一个级别,但是我必须将这些知识硬编码到应用程序中,这很难看

我想做的是通过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>
。。。我想说应该有一种方法来配置我的logback.xml,让“bye”线程只登录info或更高版本,而“hi”线程从trace或更高版本登录?我花了半天的时间在谷歌上搜索和阅读logback文档,我尝试了筛选器、正则表达式过滤器和许多其他示例,但它们显然都只是在传递信息。这意味着一个解决方案可能是在消息中出现一个神奇的字符串并将其过滤掉,但这也会很难看


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

在这种情况下,我认为您需要声明另一个带有阈值信息的appender&logger。因为appender本身不知道从什么线程调用它。

我认为可以使用MDC和TurboFilter来实现这一目的

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

public void run(){
put(“threadname”,this.getName());
logSomething();
}
如果您希望“bye”线程只登录info或更高版本,而“hi”线程只登录trace或更高版本,则必须将DynamicThresholdFilter的定义添加到
logback.xml


螺纹名称
查出
再见
信息
你好
查出
......

但是appender模式中有一个%线程,它可以工作(请参阅我问题中的模式和日志输出),所以它必须知道线程,对吗?这就是我的希望主要基于的…这听起来是一个使用标记的很好的例子。
            <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