logback快速从0到1

167 阅读3分钟

前言

Logback,是springboot的默认日志框架,对@Slf4j进行了实现。 我学习logback的文章

使用@Slf4j,必须使用lombok

@Slf4j(topic = "xxxxx")

在日志打印中会表明来自于 xxxxx 的日志,无需在logback-spring.xml文件中配置

logback相较于log4j的优势

  1. 比log4j更快,重写了内核,在一些关键路径上性能提升10倍,内存占用也更少。
  2. 经过大量的测试,和log4j测试不在一个量级。
  3. logback-classic是SLF4J的实现,切换其他日志框架非常方便。
  4. 文档丰富并且不断更新,支持Groovy风格的配置文件配置文件自动重新加载,如果更新了配置文件,logback-classic可以自动重新加载。
  5. 自动删除日期较老的日志文件,maxHistory属性,你可以控制已经产生日志文件的最大数量。如果设置maxHistory为12,那那些log文件超过12个月的都会被自动移除。
  6. 自动压缩归档的日志文件,压缩文件是异步进行,不影响应用。
  7. 配置文件可以处理不同的环境开发,测试,生产),这样一个配置文件就可以适应多个环境。
  8. SiftingAppender(一个非常多功能的Appender) 它可以用来分割日志文件根据任何一个给定的运行参数。如,SiftingAppender能够区别日志事件跟进用户的Session,然后每个用户会有一个日志文件。

logback的配置加载的顺序

  • 上下文初始化的时候会调用ContextInitializer,在这个类中的方findURLOfDefaultConfigurationFile是用来加载默认的配置文件。
  1. 先从系统的属性中获取键为logback.configurationFile的值,如果有,就加载指定的配置文件。
  2. 如果没有设置,会在classpath中找文件logback-test.xml。
  3. 如果logback-test.xml不存在,搜索logback.groovy配置文件。
  4. 如果logback.groovy不存在,最后查找logback.xml。
  5. 如果以上配置文件不存在,会用SPI的方式加载classpath下的Configurator接口的实现类。
  6. 最后,如果以上都没有成功,会默认创建BasicConfigurator实例,BasicConfigurator默认配置了ConsoleAppender,也就是只能输出到控制台。

logback的三个核心模块

  • logback-core
  1. SpringBoot默认集成
  2. 其他两个模块的基础模块
  • logback-classic
  1. SpringBoot默认集成
  2. 完整实现了slf4j api
  • logback-acces
  1. 需要自行引入依赖,本文没有引入使用
  2. 访问模块与Servlet容器集成提供通过Http来访问日志的功能

logback的隔离级别(从高到低,越高意味着越需要日志管理)

  • ERROR
  • WARN
  • INFO
  • DEBUG => 默认级别
  • TRACE

创建logback-spring.xml配置文件

<configuration>
    <!-- 获取.properties文件中的属性,在properties文件中找到对应的配置项 -->
    <springProperty scope="context" name="logging.path" source="logging.path" />
    <springProperty scope="context" name="logging.console.level" source="logging.console.level" />
    <springProperty scope="context" name="logging.normal-server.level" source="logging.normal-server.level" />
    <springProperty scope="context" name="logging.cainiao-server.level" source="logging.cainiao-server.level" />
    <springProperty scope="context" name="logging.tam-server.level" source="logging.tam-server.level" />
    <springProperty scope="context" name="logging.kam-server.level" source="logging.kam-server.level" />

    <!-- 控制台日志配置器 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 控制台日志打印器 -->
    <root level="${logging.console.level}">
        <appender-ref ref="STDOUT"/>
    </root>

    <!-- 一般日志配置器 -->
    <appender name="NORMAL-SERVER-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 日志是否拼接,默认true 拼接,选择false会清空log文件 -->
        <append>true</append>
        <!-- 过滤器处理时有三种方式
        ● DENY:日志将立即被抛弃不再经过其他过滤器
        ● NEUTRAL:有序列表里的下个过滤器过接着处理日志
        ● ACCEPT:日志会被立即处理,不再经过剩余过滤器
        -->
        <!-- 第一种日志过滤器 - 级别过滤器 -->
<!--        <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
<!--            &lt;!&ndash; 只记录${level}级别的日志 &ndash;&gt;-->
<!--            <level>${logging.normal-server.level}</level>-->
<!--            &lt;!&ndash; 符合当前级别的日志输出到日志文件当中&ndash;&gt;-->
<!--            <onMatch>ACCEPT</onMatch>-->
<!--            &lt;!&ndash; 其他级别的日志拒绝&ndash;&gt;-->
<!--            <onMismatch>DENY</onMismatch>-->
<!--        </filter>-->
        <!-- 第二种日志过滤器 - 临界过滤器 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <!-- 记录高于等于${level}级别的日志 -->
            <level>${logging.normal-server.level}</level>
        </filter>
        <!-- 日志文件输出的文件名:按天回滚 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>
                ${logging.path}/normal-server/normal-server.log.%d{yyyy-MM-dd}
            </FileNamePattern>
        </rollingPolicy>
        <!-- 日志格式配置,把日志转为字节数组,把字节数组写入输出流 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 一般日志打印器-->
    <!--  <logger name="com.shinefriends.ecb" additivity="false"> -->
    <!--  additivity表示是否继承上层LOGGER,当前上层LOGGER为ROOT,ROOT LOGGER负责打印到控制台,所以可以继承 -->
    <!--  additivity的默认值为true,不设置即使用默认值 -->
    <logger name="com.shinefriends.ecb">
        <appender-ref ref="NORMAL-SERVER-APPENDER" />
    </logger>

    <!-- 菜鸟日志配置器 -->
    <appender name="CAINIAO-SERVER-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${logging.cainiao-server.level}</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>
                ${logging.path}/cainiao-server/cainiao-server.log.%d{yyyy-MM-dd}
            </FileNamePattern>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 菜鸟日志-自定义API打印器 -->
    <logger name="CAINIAO-API-LOGGER">
        <appender-ref ref="CAINIAO-SERVER-APPENDER" />
    </logger>

    <!-- 菜鸟日志-Signature注解打印器 -->
    <logger name="CAINIAO-SIGNATURE-LOGGER">
        <appender-ref ref="CAINIAO-SERVER-APPENDER" />
    </logger>

    <!-- 菜鸟日志-Controller打印器,不包含下层SERVICE -->
    <logger name="com.shinefriends.ecb.controller.cainiao">
        <appender-ref ref="CAINIAO-SERVER-APPENDER" />
    </logger>

    <!-- 菜鸟日志-Service打印器 -->
    <logger name="com.shinefriends.ecb.service.cainiao">
        <appender-ref ref="CAINIAO-SERVER-APPENDER" />
    </logger>

    <!-- TAM日志配置器  -->
    <appender name="TAM-SERVER-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${logging.tam-server.level}</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>
                ${logging.path}/tam-server/tam-server.log.%d{yyyy-MM-dd}
            </FileNamePattern>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- TAM日志-Controller打印器 -->
    <logger name="com.shinefriends.ecb.controller.tam">
        <appender-ref ref="TAM-SERVER-APPENDER"/>
    </logger>

    <!-- TAM日志-Service打印器 -->
    <logger name="com.shinefriends.ecb.service.tam">
        <appender-ref ref="TAM-SERVER-APPENDER"/>
    </logger>

    <!-- KAM日志配置器  -->
    <appender name="KAM-SERVER-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${logging.kam-server.level}</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>
                ${logging.path}/kam-server/kam-server.log.%d{yyyy-MM-dd}
            </FileNamePattern>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- KAM日志-Controller打印器 -->
    <logger name="com.shinefriends.ecb.controller.mall">
        <appender-ref ref="KAM-SERVER-APPENDER"/>
    </logger>

    <!-- KAM日志-Service打印器 -->
    <logger name="com.shinefriends.ecb.service.mall">
        <appender-ref ref="KAM-SERVER-APPENDER"/>
    </logger>

</configuration>


        <!-- 1.ConsoleAppender:把日志添加到控制台
             2.FileAppender:把日志添加到文件
             3.RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件,是FileAppender的子类
             4.TRACE < DEBUG < INFO < WARN < ERROR -->

        <!-- 简要配置说明 -->
        <!--    <appender name="CAINIAO-API-APPENDER"-->
        <!--              class="ch.qos.logback.core.rolling.RollingFileAppender">-->
        <!--        &lt;!&ndash; 日志是否拼接,默认true 拼接,选择false会清空log文件   &ndash;&gt;-->
        <!--        <append>true</append>-->
        <!-- 文件地址及文件名, 如果这个静态log存在,下面的动态log会失效 -->
        <!--        <file>-->
        <!--            ${logging.path}/cainiao-api.log-->
        <!--        </file>-->
        <!-- 日志文件输出的文件名:按天回滚 -->
        <!--        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
        <!--            <FileNamePattern>-->
        <!--                ${logging.path}/cainiao-api-%d{yyyy-MM-dd}.log-->
        <!--            </FileNamePattern>-->
        <!-- 30天有效期,到期自动删除 -->
        <!--            <MaxHistory>30</MaxHistory>-->
        <!--        </rollingPolicy>-->
        <!--        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">-->
        <!--            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n</pattern>-->
        <!--            <charset>UTF-8</charset>-->
        <!--        </encoder>-->
        <!--    </appender>-->

logback打印日志的方式

  • 在logback-spring.xml中对于“logger name="com.shinefriends.ecb.service.tam"”会自动监测该目录下的程序运行
  • 在类上引用注解@Slf4j,通过log.info("xxxx")...进行打印
  • 在logback-spring.xml中配置自定义日志打印器,并在类中获取一个logger的实例,如private static final Logger logger = LoggerFactory.getLogger("CAINIAO-API-LOGGER");,通过logger.info("xxxx")...进行打印