logback将日志内容输出到不同文件

38 阅读2分钟

1. 纯JAVA代码实现方式

优点:写一次,到处用。 缺点:文件名写在代码中。

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import ch.qos.logback.core.util.FileSize;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyLoggerFactory {
    private MyLoggerFactory() {}
    private static LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    private static PatternLayoutEncoder encoder = new PatternLayoutEncoder();

    static {
        encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%15.15t] [trace : %X{trace}] [%5.20logger{39}] : %m%n");
        encoder.setCharset(StandardCharsets.UTF_8);
        encoder.setContext(loggerContext);
        encoder.setOutputPatternAsHeader(false);
        encoder.start();
    }

    public static Logger getLogger(String moduleName) {
        //控制台输出
        ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>();
        if(!consoleAppender.isStarted()) {
            consoleAppender.setContext(loggerContext);
            consoleAppender.setName(moduleName+"_console");
            consoleAppender.setEncoder(encoder);
            consoleAppender.start();
        }
        //文件输出
        String logPath = "logs/api/";
        RollingFileAppender<ILoggingEvent> rollingFileAppender =  new RollingFileAppender<>();
        if(!rollingFileAppender.isStarted()) {
            rollingFileAppender.setContext(loggerContext);
            rollingFileAppender.setAppend(true);
            rollingFileAppender.setName(moduleName+"_rollingFile");
            rollingFileAppender.setFile(logPath + moduleName +"_" + new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".log");

            TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>();
            rollingPolicy.setFileNamePattern(logPath + moduleName + "_%d{yyyy-MM-dd}.log");
            rollingPolicy.setCleanHistoryOnStart(true);
            rollingPolicy.setMaxHistory(7);
            rollingPolicy.setContext(loggerContext);
            rollingPolicy.setTotalSizeCap(FileSize.valueOf("10gb"));
            rollingPolicy.setParent(rollingFileAppender);
            rollingPolicy.start();
            rollingFileAppender.setRollingPolicy(rollingPolicy);

            SizeBasedTriggeringPolicy triggeringPolicy= new SizeBasedTriggeringPolicy<>();
            triggeringPolicy.setMaxFileSize(FileSize.valueOf("1mb"));
            triggeringPolicy.start();
            rollingFileAppender.setTriggeringPolicy(triggeringPolicy);

            rollingFileAppender.setEncoder(encoder);
            rollingFileAppender.start();
        }
        Logger rootLogger = loggerContext.getLogger(moduleName);
        rootLogger.detachAndStopAllAppenders();
        rootLogger.addAppender(consoleAppender);
        rootLogger.addAppender(rollingFileAppender);
        rootLogger.setLevel(Level.DEBUG);
        rootLogger.setAdditive(false);
        return rootLogger;
    }
}

2. 接口+xml配置

优点:文件名可随时修改。 缺点:每个文件都要复制一套代码。

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

public interface WriteLog {
    Logger api1 =  LoggerFactory.getLogger("api1");
    Logger api2 =  LoggerFactory.getLogger("api2");
}
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--打印到控制台-->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%15.15t] [trace : %X{trace}] [%5.20logger{39}] : %m%n</pattern>
        </encoder>
    </appender>
    <appender name="api1" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志保存到此,根据fileNamePattern进行保存,新的日志继续保存到该文件-->
        <file>logs/api1/api1.log</file>
        <!--按天轮转-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--一整天归档文件名称,%d{yyyy-MM-dd}代表日期-->
            <fileNamePattern>logs/api1/api1.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!--文件最大保存天数-->
            <maxHistory>7</maxHistory>
            <!--单个日志最大容量,至少10MB才能看出来-->
            <maxFileSize>100MB</maxFileSize>
            <!--所有日志最多占多大容量-->
            <totalSizeCap>2GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <!--日志的输入格式-->
            <pattern>%d %-5level [%-18.18thread] - [%X{requestId:-SYSTEM}]:====== %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <appender name="api2" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/api2/api2.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>logs/api2/api2.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>7</maxHistory>
            <maxFileSize>100MB</maxFileSize>
            <totalSizeCap>2GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d %-5level [%-18.18thread] - [%X{requestId:-SYSTEM}]:====== %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--    如果appender里没有限定日志如何区分,那么root可以统一设置,如果不配置那么控制台和文件不会输出任何日志,这里root的level不做限制-->
    <root level="INFO">
        <appender-ref ref="stdout"/>
    </root>


    <!--api1日志-->
    <logger name="api1" level="DEBUG" additivity="false">
        <!--        输出到文件-->
        <appender-ref ref="api1"/>
        <!--        允许控制台输出-->
        <appender-ref ref="stdout"/>
    </logger>
    <!--api2日志-->
    <logger name="api2" level="DEBUG" additivity="false">
        <!--        输出到文件-->
        <appender-ref ref="api2"/>
        <!--        允许控制台输出-->
        <appender-ref ref="stdout"/>
    </logger>

</configuration>
WriteLog.api1.info("XXDDDSS" + System.currentTimeMillis());