欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

logback 的详细配置与需要注意的细节

程序员文章站 2022-07-03 16:07:14
...

logback是在java中是用得非常多的日志框架。网上相关介绍也非常多。本篇意不在于logback如何配置,在于提醒在配置过程中容易出现的错误。

如何配置也唠叨一下吧:

1、导包,用1.2.3的版本

<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.2.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
    <scope>test</scope>
</dependency>

这里多唠叨几句,有几个配置的bug在以下版本得意修复:

maxHistory不生效,最低修复该bug的版本为1.1.7

totalSizeCap不生效,最低修复该bug的版本为1.1.8

totalSizeCap不能超过2G缺陷,最低修复该bug的版本为1.2.0

但貌似实际totalSizeCap在1.2.3版本仍然会有问题。logback官方说是在1.3.0修复这个问题。但目前1.3.0还没有正式版本。

 

现在进入主题,怎么配logback

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" debug="false">
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <!--注意该配置文件是至上而下解析的,要使用其它元素必须往前摆放 -->
    <property name="LOG_PATH" value="logs"/>
    <property name="MAX_HISTORY" value="1"/>
    <!-- 日志打印级别 -->
    <springProperty scop="context" name="SYS_LOG_LEVEL" source="sys.log.level" defaultValue="INFO"/>
    <springProperty scop="context" name="SYS_APPLICATION_LOG_LEVEL" source="sys.application.log.level"
                    defaultValue="INFO"/>
    <!-- 有新日志写入,立马将日志写入到磁盘的文件中。当日志很多,这种频繁操作文件显然性能很低下,所以设置为false,先缓存,等一定量后在写入文件,提高性能 -->
    <springProperty scop="context" name="IMMEDIATE_FLUSH" source="log.immediate.flush" defaultValue="false"/>
    <springProperty scop="context" name="QUEUE_SIZE" source="log.queue.size" defaultValue="1024"/>

    <!-- 日志打印格式 -->
    <springProperty name="CONSOLE_LOG_PATTERN" source="console.log.pattern"
                    defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{50} - %msg%n"/>
    <springProperty name="FILE_LOG_PATTERN" source="file.log.pattern"
                    defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{50} - %msg%n"/>

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

    <!--application日志-->
    <property name="PATH_APPLICATION" value="${LOG_PATH}/application/application.log"/>
    <appender name="APPLICATION" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${PATH_APPLICATION}</file>
        <encoder>
            <immediateFlush>${IMMEDIATE_FLUSH}</immediateFlush>
            <!-- 日志打印格式 -->
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--%d %i 两个参数不可少,如果没有%i,那么同一时间区间达到大小条件后,如果没有这个i%,系统是不知道怎么区分文件序号的 -->
            <fileNamePattern>${PATH_APPLICATION}.%d{yyyy-MM-dd}.%i</fileNamePattern>
            <!--每个文件的大小限制-->
            <MaxFileSize>1GB</MaxFileSize>
            <!--保留的最大文件数-->
            <maxHistory>${MAX_HISTORY}</maxHistory>
            <!--总共最多40GB,防止磁盘被撑满-->
            <totalSizeCap>40GB</totalSizeCap>
            <!--重启清理日志文件-->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--日志级别 -->
            <level>${SYS_APPLICATION_LOG_LEVEL}</level>
        </filter>
    </appender>
    <!-- 异步配置 -->
    <appender name="ASYNC_APPLICATION" class="ch.qos.logback.classic.AsyncAppender">
        <!-- neverBlock=true。队列满了也不阻塞线程 -->
        <neverBlock>true</neverBlock>
        <!-- 默认情况下,当BlockingQueue还有20%容量,他将丢弃TRACE、DEBUG和INFO级别的event,只保留WARN和ERROR级别的event。为了保持所有的events,设置该值为0。 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- blockingQueue长度决定了队列能放多少信息,在默认的配置下,如果blockingQueue放满了,后续想要输出日志的线程会被阻塞,如果neverBlock=true,则会直接丢弃 -->
        <queueSize>${QUEUE_SIZE}</queueSize>
        <appender-ref ref="APPLICATION"/>
    </appender>

    <!-- 区分环境 -->
    <springProfile name="dev">
        <!-- 避免重复打印日志,浪费磁盘空间,设置additivity=false -->
        <logger name="com." level="debug" additivity="false">
            <appender-ref ref="CONSOLE"/>
        </logger>

        <root level="${sys_log_level}">
            <appender-ref ref="async_application"/>
        </root>
    </springProfile>

    <!--未指定的情况下,所有数据会再root的appender输出 -->
    <springProfile name="prod">
        <root level="${sys_log_level}">
            <appender-ref ref="async_application"/>
        </root>
    </springProfile>


</configuration>

需要注意的几个点:

1、MaxHistory 这个属性是指日志文件保留的最大数量,而不是天数。

清理的周期maxHistory是和配置的fileNamePattern日期的最小粒度单位保持一致

比如


<fileNamePattern>${PATH_APPLICATION}.%d{yyyy-MM-dd}.%i</fileNamePattern>
<!--保留的最大文件数-->
<maxHistory>8</maxHistory>

 那么就是保存8份日志,也就是对应最近八天。所以很多人错认为是指时间,实际是指数量。

以此类推:


<fileNamePattern>${PATH_APPLICATION}.%d{yyyy-MM-dd-HH}.%i</fileNamePattern>
<!--保留的最大文件数-->
<maxHistory>8</maxHistory>

那么就是保存最近8个小时。

 

2、%d %i 两个参数不可少

%d 表示时间,会以这个配置做时间切割。

%i很重要,特别实用SizeAndTimeBasedRollingPolicy策略时,这个参数不能少,如果没有这个i%,同一时间区间达到大小切割条件后,系统是不知道怎么区分文件序号的,直接就会报错

 

3、后缀以".zip"或".gz"结尾,则开启日志文件压缩

<fileNamePattern>${PATH_APPLICATION}.%d{yyyy-MM-dd-HH}.%i.gz</fileNamePattern>

建议使用gz。压缩比会更高一些

4、看看就行

<timeBasedFileNamingAndTriggeringPolicy
        class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    <!--文件达到 最大1GB时会被压缩和切割 -->
    <maxFileSize>1GB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>

旧版本的logback里可以在TimeBasedRollingPolicy这个rollingPolicy下配置一个timeBasedFileNamingAndTriggeringPolicy(实现类为SizeAndTimeBasedFNATP)达到同时配置时间和文件大小的滚动策略;

而在新版本里其实使用SizeAndTimeBasedRollingPolicy就可以同时满足两个需求了。

相关标签: JAVA