Logback

1. 作用

Logback将写日志事件的任务委托给appender组件完成,SiftingAppender顾名思义就是筛选日志事件,具体点就是:

对于Logback委托给它的日志事件,SiftingAppender会对日志事件做一些区分,然后不同的事件SiftingAppender会委托不同的appender去完成真正的写操作。

假设有这么一个场景:
有一个Task类完成成一些特定的任务,每一个Task实例都有一个编号,运行时期会不停的输出任务状态的日志。现在我们需要每个任务按照编号把日志输出到一个特定的日志文件中。

接下来,借助 slf4j 的 SiftingAppender。一起完成这样一个场景。

2. 使用SiftingAppender

slf4j的配置文件如下:

1<?xml version="1.0" encoding="UTF-8" ?> 2<configuration debug="true"> 3 <property name="pattern" value="%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n"/> 4 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 5 <target>System.out</target> 6 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 7 <pattern>${pattern}</pattern> 8 </encoder> 9 </appender> 10 11 <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"> 12 <!--discriminator鉴别器,根据taskId这个key对应的value鉴别日志事件,然后委托给具体appender写日志--> 13 <discriminator> 14 <key>taskId</key> 15 <defaultValue>default</defaultValue> 16 </discriminator> 17 <sift> 18 <!--具体的写日志appender,每一个taskId创建一个文件--> 19 <appender name="File-${taskId}" class="ch.qos.logback.core.FileAppender"> 20 <file>d:/log/${taskId}/info.log</file> 21 <append>true</append> 22 <encoder charset="UTF-8"> 23 <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5level %logger{35} - %msg%n</pattern> 24 </encoder> 25 </appender> 26 </sift> 27 </appender> 28 29 <!--应用于该包路径的日志--> 30 <logger name="com.github.thinwonton.showcase.java.slf4j.task" level="INFO"> 31 <appender-ref ref="SIFT"/> 32 </logger> 33 34 <root level="INFO"> 35 <level>info</level> 36 <appender-ref ref="STDOUT"/> 37 </root> 38</configuration>

有个task类,在里面完成一些特定的业务功能。

1package com.github.thinwonton.showcase.java.slf4j.task; 2 3import org.slf4j.Logger; 4import org.slf4j.LoggerFactory; 5import org.slf4j.MDC; 6 7// 任务类 8public class MyTask implements Runnable { 9 private static Logger LOG = LoggerFactory.getLogger(MyTask.class); 10 11 private String taskId; 12 13 public MyTask(String taskId) { 14 this.taskId = taskId; 15 } 16 17 public void run() { 18 try { 19 /* 上面logback.xml中discriminator根据taskId这个key的value来决定,taskId的value通过这种方式设置, 20 这里设置的key-value对是保存在一个ThreadLocal<Map>中的,所以不会对其他线程中的taskId这个key产生影响 21 */ 22 MDC.put("taskId", taskId); 23 for (; ; ) { 24 // 写日志,使用SiftingAppender,由于当前调用线程taskId的value是对应this.taskId(假设是task-0), 25 // 所以会输出到task-0这个文件中 26 LOG.info("taskId={}, threadNo={}", taskId, Thread.currentThread()); 27 Thread.sleep(2000); 28 } 29 } catch (Exception e) { 30 } finally { 31 MDC.remove(taskId); 32 } 33 } 34}

MDC.put("taskId", taskId); 是关键

执行类:

1public class SiftingAppenderTest { 2 public static void main(String[] args) { 3 ExecutorService taskExecutors = Executors.newCachedThreadPool(); 4 // 运行10个task,启动了10个线程 5 for (int i = 0; i < 10; ++i) { 6 taskExecutors.submit(new MyTask("task-" + i)); 7 } 8 taskExecutors.shutdown(); 9 } 10}

运行程序后,task的日志将会按照它的ID写入到不同的文件夹中。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

jQuery 的事件绑定和事件委托(事件代理)

简单以jQuery的on()方法为例说明:API:1.on(events,selector,data,handler) 如果on()方法的selector参数为空,事件处理程序就被称为直接绑定。每当在被绑定元素上(如下例中被绑定的document元素,译者注)发生事件时,无论这个事件发生在这个元素上还是从内层元素经冒泡而

jdk

系列文章已完成,目录如下:jdklogging、log4j、logback日志介绍及原理(http://my.oschina.net/pingpangkuangmo/blog/406618)commonslogging与jdklogging、log4j1、log4j2、logback的集成原理(http://my.osch

MyBatis进阶使用(日志管理、动态SQL、二级缓存、多表联级、Pagehelper分页、批处理)

MyBatis进阶使用日志管理依赖使用Logback进行日志管理:<dependency<groupIdch.qos.logback</groupId<artifactIdlogbackclassic</artifactId<version1.3.0alpha5</version</dependency