3

日志最佳实践探究

 2 years ago
source link: https://www.diguage.com/post/logging-best-practices/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

日志框架选型

slf4j + logback

Jar 包选择

Slf4j 桥接其他日志框架
Figure 1. Slf4j 桥接其他日志框架
基于 slf4j + logback 的日志框架依赖
<properties>
    <slf4j.version>1.7.30</slf4j.version>
    <log4j.version>2.13.3</log4j.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j-over-slf4j</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jul-to-slf4j</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-to-slf4j</artifactId>
        <version>${log4j.version}</version>
    </dependency>
</dependencies>
logback 日志配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 将 JUL 的日志级别映射为 logback 的日志级别 -->
    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
        <resetJUL>true</resetJUL>
    </contextListener>

    <!-- 日志文件目录 -->
    <property name="log.location" value="/export/Logs/loan.ledger.jd.local"/>
    <!-- 日志样式 -->
    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80}[%L] - %msg%n"/>

    <!-- 控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 如果使用 Spring Boot 发布应用,则需要配置该 Appender。 -->
    <!-- 如果使用 Tomcat 发布应用,则不需要配置该 Appender。 -->
    <appender name="CATALINA" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 如果配置了该 Appender,则在 digger 中只需要添加该日志文件路径即可。 -->
        <file>${log.location}/catalina.log</file>
        <append>true</append>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.location}/catalina.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>100</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="SYS_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.location}/system_info.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.location}/system_info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>100</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="SYS_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.location}/system_warn.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.location}/system_warn.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>100</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="SYS_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.location}/system_error.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.location}/system_error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>100</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="APP_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.location}/app_info.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.location}/app_info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>100</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="APP_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.location}/app_warn.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.location}/app_warn.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>100</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="APP_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.location}/app_error.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.location}/app_error.%d{yyyy-MM-dd}.%i.log
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>100</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 注意 additivity="false"。不加该配置项,这些日志还会在默认 root 日志中输出。 -->
    <logger name="com.jd" level="INFO" additivity="false">
        <!-- 下面两个二选一即可。 -->
        <!-- 如果使用 Tomcat 发布,则留下 CONSOLE。 -->
        <!-- 如果使用 Spring Boot 发布,则留下 CATALINA; -->
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="CATALINA"/>
        <appender-ref ref="APP_INFO"/>
        <appender-ref ref="APP_WARN"/>
        <appender-ref ref="APP_ERROR"/>
    </logger>

    <root level="INFO">
        <!-- 下面两个二选一即可。 -->
        <!-- 如果使用 Tomcat 发布,则留下 CONSOLE。 -->
        <!-- 如果使用 Spring Boot 发布,则留下 CATALINA; -->
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="CATALINA"/>
        <appender-ref ref="SYS_INFO"/>
        <appender-ref ref="SYS_WARN"/>
        <appender-ref ref="SYS_ERROR"/>
    </root>
</configuration>

slf4j + log4j 2

log4j 2 的优势

Jar 包选择

log4j 2 桥接其他日志框架
Figure 2. log4j 2 桥接其他日志框架
基于 slf4j + log4j 2 的日志框架依赖
<properties>
    <slf4j.version>1.7.30</slf4j.version>
    <log4j.version>2.13.3</log4j.version>
</properties>


<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-1.2-api</artifactId>
        <version>${log4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>${log4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-jcl</artifactId>
        <version>${log4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-jul</artifactId>
        <version>${log4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>${log4j.version}</version>
    </dependency>
</dependencies>
logback 日志配置
// TODO

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK