Logback

Stella981
• 阅读 692

1. 作用

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

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

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

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

2. 使用SiftingAppender

slf4j的配置文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true">
    <property name="pattern" value="%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level  %msg%n"/>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <target>System.out</target>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
        <!--discriminator鉴别器,根据taskId这个key对应的value鉴别日志事件,然后委托给具体appender写日志-->
        <discriminator>
            <key>taskId</key>
            <defaultValue>default</defaultValue>
        </discriminator>
        <sift>
            <!--具体的写日志appender,每一个taskId创建一个文件-->
            <appender name="File-${taskId}" class="ch.qos.logback.core.FileAppender">
                <file>d:/log/${taskId}/info.log</file>
                <append>true</append>
                <encoder charset="UTF-8">
                    <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5level %logger{35} - %msg%n</pattern>
                </encoder>
            </appender>
        </sift>
    </appender>

    <!--应用于该包路径的日志-->
    <logger name="com.github.thinwonton.showcase.java.slf4j.task" level="INFO">
        <appender-ref ref="SIFT"/>
    </logger>

    <root level="INFO">
        <level>info</level>
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

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

package com.github.thinwonton.showcase.java.slf4j.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

// 任务类
public class MyTask implements Runnable {
    private static Logger LOG = LoggerFactory.getLogger(MyTask.class);

    private String taskId;

    public MyTask(String taskId) {
        this.taskId = taskId;
    }

    public void run() {
        try {
            /* 上面logback.xml中discriminator根据taskId这个key的value来决定,taskId的value通过这种方式设置,
             这里设置的key-value对是保存在一个ThreadLocal<Map>中的,所以不会对其他线程中的taskId这个key产生影响
            */
            MDC.put("taskId", taskId);
            for (; ; ) {
                // 写日志,使用SiftingAppender,由于当前调用线程taskId的value是对应this.taskId(假设是task-0),
                // 所以会输出到task-0这个文件中
                LOG.info("taskId={}, threadNo={}", taskId, Thread.currentThread());
                Thread.sleep(2000);
            }
        } catch (Exception e) {
        } finally {
            MDC.remove(taskId);
        }
    }
}

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

执行类:

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

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

Logback

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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
Dax Dax
3年前
jQuery 的事件绑定和事件委托(事件代理)
简单以jQuery的on()方法为例说明:API:1.on(events,selector,data,handler) 如果on()方法的selector参数为空,事件处理程序就被称为直接绑定。每当在被绑定元素上(如下例中被绑定的document元素,译者注)发生事件时,无论这个事件发生在这个元素上还是从内层元素经冒泡而
执键写春秋 执键写春秋
3年前
MyBatis进阶使用(日志管理、动态SQL、二级缓存、多表联级、Pagehelper分页、批处理)
MyBatis进阶使用日志管理依赖使用Logback进行日志管理:<dependency<groupIdch.qos.logback</groupId<artifactIdlogbackclassic</artifactId<version1.3.0alpha5</version</dependency
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
jdk
系列文章已完成,目录如下:jdklogging、log4j、logback日志介绍及原理(http://my.oschina.net/pingpangkuangmo/blog/406618)commonslogging与jdklogging、log4j1、log4j2、logback的集成原理(http://my.osch
Wesley13 Wesley13
3年前
java日志框架系列(6):logback框架encoder详解
1.Encoder1.encoder功能Encoder负责两件事,一是把事件转换为字节数组,二是把字节数组写入输出流。注意:在logback0.9.19版之前没有encoder。在之前的版本里,多数appender依靠layout来把事件转换成字符串并用java.io.Writ
Wesley13 Wesley13
3年前
C#委托和事件
0\.前言事件和委托是C中的高级特性,也是C中很有意思的一部分。出现事件的地方,必然有委托出现;而委托则不一定会有事件出现。那为什么会出现这样的关系呢?这就需要从事件和委托的定义出发,了解其中的内在。1\.委托说起委托,就不得不回忆一下之前在Linq篇中介绍的匿名方法,其中提到了Func和Action这两个类型
Stella981 Stella981
3年前
Spring boot——logback 基础使用篇(一)
1简单日志配置springboot内部使用CommonsLogging来记录日志,但也保留外部接口可以让一些日志框架来进行实现,例如JavaUtilLogging,Log4J2还有Logback。如果你想用某一种日志框架来进行实现的话,就必须先配置,默认情况下,springboot使用Logback作为日志实现的框架。1
Wesley13 Wesley13
3年前
Unity事件系统
\1.前言Unity中事件/委托有着广泛的应用,本文通过封装一个简易的事件的系统,来统一管理消息的传递。此功能在简易应用或者事件较少的体现不出太好的作用,但是对于事件应用较多时,可以减少脚本之间的耦合。通过此事件系统架起不同脚本之间的桥梁,对于大量应用事件场景中具有良好的效果。\2.事件系统\2.1事件管理类管理事件的
Stella981 Stella981
3年前
Noark入门之异步事件
引入异步事件主要是为了各模块的解耦,每当完成一个动作时,向系统发布一个事件,由关心的模块自己监听处理,可选择同步处理,异步处理,延迟处理。何时发布事件,当其他模块关心此动作时<br比如获得道具时,任务系统模块要判定完成进度,BI模块需要上报等等都可以监听此事件,已达模块解耦0x00事件源一个实现xyz.noark.core.event