1. 程式人生 > >logback實現每個執行緒一個獨立的日誌檔案

logback實現每個執行緒一個獨立的日誌檔案

本文介紹如何使用logback的Mapped Diagnostic Context (MDC) 和SiftingAppender實現每個執行緒一個獨立的日誌檔案。

MDC 參考手冊http://logback.qos.ch/manual/mdc.html

本文使用logback的版本為1.1.7

1、logback.xml配置檔案示例

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <jmxConfigurator/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </layout>
    </appender>

    <!-- This is MDC value -->
    <!-- We will assign a value to 'logFileName' via Java code -->
    <appender name="FILE-THREAD" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>logFileName</key>
            <defaultValue>logback</defaultValue>
        </discriminator>
        <sift>
            <!-- A standard RollingFileAppender, the log file is based on 'logFileName' at runtime  -->
            <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>logs/${logFileName}.log</file>
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                    <Pattern>
                        %d{yyyy-MM-dd HH:mm:ss.SSS} %mdc [%thread] %-5level %logger{36} - %msg%n
                    </Pattern>
                </encoder>
                <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
                    <FileNamePattern>logback.log.%i.bak</FileNamePattern>
                    <MinIndex>1</MinIndex>
                    <MaxIndex>12</MaxIndex>
                </rollingPolicy>
                <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                    <MaxFileSize>100MB</MaxFileSize>
                </triggeringPolicy>
            </appender>
        </sift>
    </appender>

    <logger name="com.yangyi" level="INFO" />

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

2.java執行緒程式碼示例

此處通過簡單的MDC put與remove來實現每個執行緒log檔名獨立。

package com.yangyi;

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

/**
 * Created by yangjinfeng02 on 2016/6/4.
 */
public class Counter implements Runnable {

    private Logger logger = LoggerFactory.getLogger(Counter.class);

    private String counterName;

    public Counter(String counterName) {
        this.counterName = counterName;
    }

    public void run() {
        MDC.put("logFileName", counterName);
        logger.info("start counter {}", counterName);
        MDC.remove("logFileName");
    }
}
package com.yangyi;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by yangjinfeng02 on 2016/6/4.
 */
public class Application {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; ++i) {
            executorService.execute(new Counter(String.valueOf(i)));
        }
        executorService.shutdown();
    }
}



PS:利用logback的MDC特性,實際專案中,可以實現按請求url、使用者、host等粒度進行日誌檔案的獨立分隔。,如web專案中,可通過攔截器將session id注入到MDC,實現按session分隔日誌,或者簡單的將session呈現到log資訊中。