一、日志配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 尽量别用绝对路径,如果带参数不同容器路径解释可能不同,以下配置参数在pom.xml里 -->
    <property name="log.root.level" value="${log.root.level}" /> <!-- 日志级别 -->
    <property name="log.other.level" value="${log.other.level}" /> <!-- 其他日志级别 -->
    <property name="log.base" value="/usr/local/tomcat/logs" /> <!-- 日志路径,这里是相对路径,web项目eclipse下会输出到eclipse的安装目录下,如果部署到linux上的tomcat下,会输出到tomcat/bin目录 下 -->
    <property name="log.moduleName" value="xxx" />  <!-- 模块名称, 影响日志配置名,日志文件名,统一使用工程名 -->
    <property name="log.max.size" value="100MB" /> <!-- 日志文件大小,超过这个大小将被压缩 -->

    <!--控制台输出 -->
    <appender name="STDOUT-APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</Pattern>
        </encoder>
    </appender>

    <!-- 用来保存输出所有级别的日志 -->
    <appender name="DEFAULT-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

        <File>${log.base}/${log.moduleName}-default.log</File>

        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            <FileNamePattern>${log.base}/history/default/${log.moduleName}- default-%d{yyyy-MM-dd}.%i.log</FileNamePattern>

            <!-- 文件输出日志 (文件大小策略进行文件输出,超过指定大小对文件备份) -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>

        </rollingPolicy>

        <!-- 日志输出的文件的格式 -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
        </layout>

    </appender>

    <!-- 只用保存输出ERROR级别的日志 -->
    <appender name="ERROR-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

        <File>${log.base}/${log.moduleName}-error.log</File>

        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/history/error/${log.moduleName}- error-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
        </layout>

        <!-- 下面为配置只输出error级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

    </appender>

    <!-- 只用保存输出WARN级别的日志 -->
    <appender name="WARN-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

        <File>${log.base}/${log.moduleName}-warn.log</File>

        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/history/warn/${log.moduleName}-warn-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
        </layout>

        <!-- 下面为配置只输出warn级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

    </appender>

    <!-- 只用保存输出DEBUG级别的日志 -->
    <appender name="DEBUG-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

        <File>${log.base}/${log.moduleName}-debug.log</File>

        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/history/debug/${log.moduleName}- debug-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
        </layout>

        <!-- 下面为配置只输出debug级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

    </appender>

    <!-- 只用保存输出INFO级别的日志 -->
    <appender name="INFO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

        <File>${log.base}/${log.moduleName}-info.log</File>

        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/history/info/${log.moduleName}-info-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
        </layout>

        <!-- 下面为配置只输出info级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

    </appender>

    <!-- 只用保存输出TRACE级别的日志 -->
    <appender name="TRACE-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

        <File>${log.base}/${log.moduleName}-trace.log</File>

        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/history/trace/${log.moduleName}- trace-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
        </layout>

        <!-- 下面为配置只输出trace级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>TRACE</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

    </appender>

    <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
    <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
    <!-- 添加附加的appender,最多只能添加一个 -->
    <appender name="ASYNC-DEFAULT-APPENDER" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>256</queueSize>
        <includeCallerData>true</includeCallerData>
        <appender-ref ref="DEFAULT-APPENDER" />
    </appender>

    <!-- 为某个包下的所有类的指定Appender 这里也可以指定类名称例如:com.xinniu -->
    <logger name="com.xinniu" additivity="false">
        <level value="${log.other.level}" />
        <appender-ref ref="STDOUT-APPENDER" />
        <appender-ref ref="ASYNC-DEFAULT-APPENDER" />
        <appender-ref ref="ERROR-APPENDER" />
        <appender-ref ref="WARN-APPENDER" />
        ${log.appender.xniniu}
        <appender-ref ref="DEFAULT-APPENDER" />
    </logger>

    <!-- root将级别为${log.root.level}及大于${log.root.level}的日志信息交给已经配置好的名为“Console”的appender处理,“Console”appender将信息打印到Console,其它同理 -->
    <root level="${log.root.level}">
        <appender-ref ref="STDOUT-APPENDER" />
        <appender-ref ref="ASYNC-DEFAULT-APPENDER" />
        <appender-ref ref="ERROR-APPENDER" />
        <appender-ref ref="WARN-APPENDER" />
        ${log.appender.root}
        <appender-ref ref="DEFAULT-APPENDER" />
    </root>

</configuration>

PS:此配置文件除了会按照日志级别分别打印到${log.moduleName}-error.log、${log.moduleName}-info.log等日志文件中,同时为了方便线下环境控制台查看日志,定位问题,该配置也会在控制台打印一份日志,建议线上环境关闭掉控制台日志。

 

二、日志使用

1、日志打印统一使用logback

2、开发环境、测试环境和灰度环境日志级别可以根据需要配置成info或debug级别,线上环境需要配置成info级别。

3、将不同级别的日志分别打印到不同的日志文件中${log.moduleName}-error.log、${log.moduleName}-warn.log、${log.moduleName}-info.log、${log.moduleName}-debug.log等。

4、本系统对外的接口入参、出参必须打印出来,日志级别为info。

5、本系统中调用本系统外接口时必须打印入参、出参,日志级别为info。

6、系统中关键逻辑、容易出错的逻辑处需要打印日志,方便开发和线上环境排查问题,日志级别为info。

7、所有try…catch的地方都需要打印错误日志。

8、错误日志打印时一定要把堆栈打印出来(没有堆栈时可不打印,另外自定义的异常不要打印堆栈信息),方便排查问题时定位原因。例如

LOGGER.error("服务端接口: 根据合同ID获取交易流水列表getListByContractId,params:{} 异常为:", contractId, e);

9、日志打印时要将敏感字段脱敏或加密。

10、除错误日志以外(错误日志请参考第7、8条),其他日志打印用花括号{}占位符,不要用加号+的形式拼接字符串。例如

LOGGER.info("服务端接口: 根据合同ID获取交易流水列表getListByContractId,params:{}", contractId);

11、不要使用e.printStackTrace();

12、除测试代码外严禁使用System.out.println()、System.gc()

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐