1. 如其名, SiftingAppender能按照给定的运行时属性, 对记录进行分离或筛选。例如, SiftingAppender能根据用户会话对记录事件进行分离, 这样, 每个用户生成的记录会进入不同的记录文件, 一个用户一个文件。
2. SiftingAppender内置并且管理多个appender, 这些appender是按照区别值(discriminating value)而动态构建的。在配置文件里的SiftingAppender定义的内部, 指定构建好的appender。默认情况下, SiftingAppender用MDC的键/值对作为鉴别器(discriminator)。
3. SiftingAppender配置
<appender name="sift" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<Key>userid</Key>
<DefaultValue>unknown</DefaultValue>
</discriminator>
<sift class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
<appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender">
<File>${userid}.log</File>
<Append>true</Append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%-4relative [%thread] %-5level - %msg%n</Pattern>
</encoder>
</appender>
</sift>
</appender>
4. 如果没有指定class属性, 则默认为"MDCBasedDiscriminator"(ch.qos.logback.classic.sift.MDCBasedDiscriminator), 它用"Key"属性关联的MDC值作为鉴别器。如果值为null, 则使用"DefaultValue"关联的值。
5. SiftingAppender是唯一能够引用和配置嵌套appender的appender。在上面的例子里, 在SiftingAppender里有嵌套的FileAppender实例, 每个实例都用MDC键"userid"所关联的值作标识。每当MDC键"userid"关联一个新值时, 就会从头创建一个新的FileAppender实例。SiftingAppender监视被它创建的appender, 如果appender在30分钟内没被使用, 则会被自动关闭和丢弃。仅拥有不同的appender实例是不够得, 每个实例还必须输出到不同的资源。为实现这种差异, 在嵌套appender(上面的FileAppender)里, 传递给鉴别器的键(上面的"userid")变成了变量。所以, 这个变量可用来区分嵌套appender所使用的实际资源。
6. 例子
6.1. 新建一个名为SiftingAppender的Java项目, 同时添加相关jar包
6.2. 在src目录下新建logback.xml
<configuration debug="true">
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-4relative [%thread] %-5level - %msg%n</pattern>
</encoder>
</appender>
<appender name="sift" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<Key>userid</Key>
<DefaultValue>unknown</DefaultValue>
</discriminator>
<sift class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
<appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender">
<File>${userid}.log</File>
<Append>true</Append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%-4relative [%thread] %-5level - %msg%n</Pattern>
</encoder>
</appender>
</sift>
</appender>
<root level="debug">
<appender-ref ref="stdout" />
<appender-ref ref="sift" />
</root>
</configuration>
6.3. 新建Sifting.java
package com.fj;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
public class Sifting {
private static final Logger logger = LoggerFactory.getLogger(Sifting.class);
public static void main(String[] args) {
logger.error("如其名, SiftingAppender能按照给定的运行时属性, 对记录进行分离或筛选。");
logger.warn("例如, SiftingAppender能根据用户会话对记录事件进行分离, ");
logger.info("这样, 每个用户生成的记录会进入不同的记录文件, 一个用户一个文件。");
logger.debug("SiftingAppender内置并且管理多个appender");
MDC.put("userid", "100001");
logger.error("这些appender是按照区别值(discriminating value)而动态构建的。");
logger.warn("在配置文件里的SiftingAppender定义的内部, 指定构建好的appender。");
logger.info("默认情况下, SiftingAppender用MDC的键/值对作为鉴别器(discriminator)。");
logger.debug("如果没有指定class属性, 则默认为\\\"MDCBasedDiscriminator\\\"");
MDC.put("userid", "100002");
logger.error("(ch.qos.logback.classic.sift.MDCBasedDiscriminator)");
logger.warn("它用\\\"Key\\\"属性关联的MDC值作为鉴别器。");
logger.info("如果值为null, 则使用\"DefaultValue\"关联的值。");
logger.debug("SiftingAppender是唯一能够引用和配置嵌套appender的appender。");
}
}
6.4. 运行项目控制台输出
6.5. 同时生成了unknown.log、100001.log和100002.log三个日志文件