• springboot+logback日志规范


    当前问题

    项目采用springboot的框架集成了logback的日志配置方式,但是在使用中遇到了很多问题,同时也基于“立刻方能用好”的原则,对于logback与springboot的配置做了一些了解和其它项目的配置对比,结合当前项目的需求,及需要解决的问题的方案,记录于此。

    1. logback的日志配置统一采用/home/logs目录,但是基于本地测试时,Mac电脑没有权限写文件到/home目录,同时也不想写日志文件到本机
    2. 本地调试项目,需要将日志输出到终端查看接口执行流程,但是其它环境不能将日志输出到终端,频繁更改配置容易上线时疏漏
    3. 线上日志输出需要采用info级别,但是其他环境(dohko,pre)可能需要做debug输出,获取更多的日志信息,频繁更改日志级别容易导致上线时疏忽检查导致线上日志文件很大
    4. mybatis的sql输出只有在debug模式下才能输出,但是线上日志都是info级别,如何做到info级别的日志也能输出mybatis的sql日志
    5. 同一日志级别下,需要过滤项目依赖其它包的日志输出,或将其日志级别调低,甚至不输出

    配置示例

    logback-spring.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
     
        <!--
           说明:
           1、日志级别及文件
               日志记录采用分级记录,级别与日志文件名相对应,不同级别的日志信息记录到不同的日志文件中
               例如:error级别记录到{log.context.name}_error.log(该文件为当前记录的日志文件),而{log.context.name}__error.log为归档日志,
               日志文件按日期记录,每天的日志不再拆分
               例如log-level-2013-12-21.log
               其它级别的日志也是如此。
           2、文件路径
               统一输出到/home/logs
           3、Appender
               FILEERROR对应error级别,文件名以{log.context.name}_xxx_error.log形式命名
               FILEWARN对应warn级别,文件名以{log.context.name}_xxx_error.log形式命名
               FILEINFO对应info级别,文件名以{log.context.name}_xxx_error.log形式命名
               FILEDEBUG对应debug级别,文件名以{log.context.name}_xxx_error.log形式命名
               默认输出级别为debug,不明确指定情况下文件名以{log.context.name}.log形式命名
               stdout将日志信息输出到控制上,为方便开发测试使用
        -->
     
        <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
        <property name="log.directory" value="/home/logs/" />
        <!--项目名称,也是存储日志的具体目录-->
        <property name="log.context.name" value="shop-crm-service21" />
        <!--日志的字符编码-->
        <property name="log.charset" value="UTF-8" />
        <!--历史记录最大保存天数-->
        <property name="log.maxHistory" value="30" />
        <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
        <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS}$$[%thread]$$%-5level{}$$shop-crm-service$$%msg%n" />
        <!--日志Error级别名称配置-->
        <property name="log.error.log.level" value="ERROR" />
        <!--异步写日志的队列大小配置,默认为256-->
        <property name="log.async.queue.size" value="1024" />
     
        <!--配置日志的上下文名称-->
        <contextName>${log.context.name}</contextName>
     
        <!--对应spring环境变量为local的日志配置,只做控制台输出配置-->
        <springProfile name="local">
            <!--控制台日志输出配置,可以匹配色彩和高亮-->
            <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
                <encoder>
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}) - %yellow([%file:%line]) - %msg%n</pattern>
                    <!--<pattern>${log.pattern}</pattern>-->
                    <charset>${log.charset}</charset>
                </encoder>
            </appender>
        </springProfile>
     
        <springProfile name="mu,dohko,pre,production">
            <!-- 服务器上使用的appender start -->
            <!-- 默认的file appender,按天切分日志 -->
            <appender name="ROLLING_FILE_DEFAULT" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>${log.directory}${log.context.name}/${HOSTNAME}-%d{yyyyMMdd}.log</file>
                <append>true</append>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>${log.directory}${log.context.name}/${HOSTNAME}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                    <maxHistory>${log.maxHistory}</maxHistory>
                    <totalSizeCap>30gb</totalSizeCap>
                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                      <maxFileSize>2gb</maxFileSize>
                    </timeBasedFileNamingAndTriggeringPolicy>
             </rollingPolicy>
                <encoder>
                    <pattern>${log.pattern}</pattern>
                    <charset>${log.charset}</charset>
                </encoder>
            </appender>
     
            <!-- 错误日志,按天切分 -->
            <appender name="ROLLING_FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <filter class="ch.qos.logback.classic.filter.LevelFilter">
                    <level>${log.error.log.level}</level>
                    <onMatch>ACCEPT</onMatch>
                    <onMismatch>DENY</onMismatch>
                </filter>
                <file>${log.directory}${log.context.name}/${HOSTNAME}_error-%d{yyyyMMdd}.log</file>
                <!-- 日志追加配置 -->
                <append>true</append>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>${log.directory}${log.context.name}/${HOSTNAME}_error.%d{yyyy-MM-dd}.log</fileNamePattern>
                    <maxHistory>${log.maxHistory}</maxHistory>
                </rollingPolicy>
                <!-- 此日志文件只记录error级别的 -->
                <encoder>
                    <pattern>${log.pattern}</pattern>
                    <charset>${log.charset}</charset>
                </encoder>
            </appender>
     
            <!-- 异步写日志文件的配置 -->
            <appender name ="ASYNC_FILE" class"ch.qos.logback.classic.AsyncAppender">
                <!-- 当队列达到配置队列大小的80%时,不将日志丢失 如果为-1 则超过队列80%的日志丢掉-->
                <discardingThreshold >0</discardingThreshold>
                <queueSize>${log.async.queue.size}</queueSize>
                <appender-ref ref "ROLLING_FILE_DEFAULT"/>
            </appender>
        </springProfile>
     
        <!-- rabbitmq的日志专属配置 -->
        <logger name "org.springframework.amqp.rabbit.listener.BlockingQueueConsumer" level ="WARN"/>
        <!-- zookeeper 的日志专属配置 -->
        <logger name "org.apache.zookeeper.ClientCnxn" level ="WARN"/>
        <!-- 多数据源 的日志专属配置 -->
        <logger name "com.hualala.commons.multidatasource.curator.CuratorClient" level ="WARN"/>
        <logger name "com.hualala.commons.multidatasource.datasource.DynamicDataSource" level ="WARN"/>
        <!-- 设置falcon监控的日志输出格式 -->
        <logger name "com.hualala.infrastructure.falcon.FalconMonitor" level ="WARN"/>
     
        <!--mybatis的日志专属配置 -->
        <logger name="jdbc.sqltiming" level="debug"/>
        <logger name="com.ibatis" level="debug" />
        <logger name="com.ibatis.common.jdbc.SimpleDataSource" level="debug" />
        <logger name="com.ibatis.common.jdbc.ScriptRunner" level="debug" />
        <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="debug" />
        <logger name="java.sql.Connection" level="debug" />
        <logger name="java.sql.Statement" level="debug" />
        <logger name="java.sql.PreparedStatement" level="debug" />
        <logger name="java.sql.ResultSet" level="debug" />
     
        <logger name="org.springframework" level="WARN" />
     
        <!-- 当前项目 的不同环境的日志级别配置 -->
        <logger name="com.hualala" level="debug" additivity="false">
            <springProfile name="local">
                <appender-ref ref="STDOUT" />
            </springProfile>
     
            <springProfile name="mu,dohko,pre">
                <appender-ref ref="ASYNC_FILE" />
                <appender-ref ref="ROLLING_FILE_ERROR" />
            </springProfile>
     
            <springProfile name="production">
                <appender-ref ref="ASYNC_FILE" />
                <appender-ref ref="ROLLING_FILE_ERROR" />
            </springProfile>
        </logger>
     
        <root>
            <springProfile name="local">
                <level value="info"/>
                <appender-ref ref="STDOUT" />
            </springProfile>
     
            <!-- dohko环境用来测试,日志级别尽量可以设置的低,便于定位问题 -->
            <springProfile name="mu,dohko,pre">
                <level value="info"/>
     
                <appender-ref ref="ASYNC_FILE" />
                <appender-ref ref="ROLLING_FILE_ERROR" />
            </springProfile>
     
            <!-- pre环境用来做压测,避免对测试环境的日志服务产生压力,日志级别设置为warn -->
            <springProfile name="pre">
                <level value="warn"/>
     
                <appender-ref ref="ASYNC_FILE" />
                <appender-ref ref="ROLLING_FILE_ERROR" />
            </springProfile>
     
            <!-- production为生产环境,需要记录能够定位问题或流程流转的日志,但是非必要的日志无须记录 -->
            <springProfile name="production">
                <level value="info"/>
                <appender-ref ref="ASYNC_FILE" />
                <appender-ref ref="ROLLING_FILE_ERROR" />
            </springProfile>
        </root>
    </configuration>

    配置解析

    property:将配置中引用的公共的常量做全局设置,便于修改及维护
    springProfile:配置spring的环境变量名称(对应application.yml中的profilename,name可以为单个或多个,多个名称用“,”隔开,还可取反,比如!local,代表非local环境的其它所有环境),appender节点的日志级别在未明确指定的情况下,继承自root根结点指定等级及其父等级
    root:root根结点配置,内部配置多个环境变量对应的日志引用,为每个环境变量设置对应等级,在local本地环境变量下配置终端输出日志,其它环境则配置写入文件
    logger:直接指定第三方服务的根目录报名,设置日志级别高于其默认输出的日志级别,将限制其日志输入;
    如果将其日志级别设置为小于等于其日志输出级别,且小于root根节点的日志级别,此时需要输出logger指定日志,则需要配置当前项目的的日志级别为logger中指定的日志级别,

    参考资料

    github项目配置参考

    springboot+logback日志配置

    logback官方文档

    logback 异步日志配置

  • 相关阅读:
    Http Get与Post的区别
    华为USG6000V防火墙简单配置案例
    华为USG6000V防火墙简单配置案例
    基于三层交换机的VRRP技术--MSTP、VRRP的综合运用
    ci test
    CI框架 default_controller 如何设置为:'目录/Controller' 转
    查看django版本的方法
    Django如何安装指定版本
    django学习--2 模板
    django学习--1
  • 原文地址:https://www.cnblogs.com/duyinqiang/p/15903938.html
Copyright © 2020-2023  润新知