【精准打击】logback.xml从入门到了解

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。【精准打击】logback.xml从入门到了解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

RT

最近在学习总结logback的一些知识,不知道你们是何感觉,反正我看了很多文章之后,印象总是不深刻。所谓“好记性不如烂笔头”,所以就干脆写个blog,顺带学习一下。另外你们懂的,就像LOL王者大佬永远无法预判青铜仔的操作一样,只有“菜鸡才知道菜鸡”的想法、痛点

阅读对象

  • logback.xml配置小白

温馨提示

  1. 本文总共有5912个字,预计耗时15分钟可以看完
  2. 所有标题带“*”的皆为重点知识,一定要理解
  3. 本文只是简单的介绍每个标签的意思,但我可以保证,通过本文你基本能够在生产项目上使用、配置logback日志框架了。

*读前须知

什么是logback?

答:logback是一个非常好用,且流行的日志框架。 面对当下java环境日志产品的内卷(4个Log产品,3个Log接口,非常驳杂),如果你对”应该使用什么日志接口“没什么概念,推荐直接使用 logback+slf4j的日志组合!

*logback日志的核心是什么?

答:关于Logback日志的核心,我们只需要了解3个单词:Logger(记录器),Appenders(附加器),Layout(布局)

  • Logger:记录器,是我们在编写logback.xml文件的时候,configuration下的基本标签。它的作用,等价于如下代码
//import ch.qos.logback.classic.Logger;  这是org.slf4j.Logger的一个实现示例
//import org.slf4j.LoggerFactory;
Logger logger = (Loggger)LoggerFactory.getLogger(TestRestFulController.class);

准确来说,当我们在logback-spring.xml下这样写的时候,等价于上面这条语句:

<configuration>
  <logger name="com.this.is.a.example.name"/>
</configuration>
  • Appender:有道翻译一下,他的意思是“附加器”,“输出目的地”,“输出源”。到了这里其实就不难理解了,顾名思义,它表示的是:日志输出目的地、输出源、输出媒介。那我们日志输出的目的地有什么?是什么?无非就是“控制台”、“某个指定的日志文件”呗。
  • Layout:暂时不介绍。其实核心是上面两个元素

logback.xml文件标签解析

下面是一个简单的logback.xml文件解析,请仔细阅读,关键内容就在里面了,并且已经写了注释

<?xml version="1.0" encoding="UTF-8" ?>
<!--
configuration是logback的根标签
scan="true" 表示配置文件发生了改变会自动加载
scanPeriod="60 seconds" 检测配置文件修改的时间间隔,默认的单位是毫秒,这里我们设置的表示每分钟检测
debug="false" debug如果设置为true,表示我们会打印出来logback自身实时的运行信息,很显然我们是不需要的,人家成熟的软件比咱小辣鸡写的好多了
-->
<configuration
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNameSpaceSchemaLocation="logback.xsd"
        scan="true"
        scanPeriod="60 seconds"
        debug="false">

    <!--
    定义一些常量,方便后续使用
    1、日志默认打印格式
    name:DEFAULT_LOG_PATTERN。 表示定义的常量名叫DEFAULT_LOG_PATTERN,后面可以通过el表达式使用这个常量。
    value解析:
        %d{yyyy-MM-dd HH:mm:ss.SSS}:定义一条日志的展示时间
        %-5level:表示空出5个空格
        %thread:表示执行日志的线程
        %logger{40}:显示我们在哪个类(全限定名)里面记录日志,后面的{40}表示这个类名展示的最大长度是40
        %msg:表示我们的日志信息
        %n:表示换行
    -->
    <property name="DEFAULT_LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%thread] %logger{40} : %msg%n"/>

    <!--    定义日志的输出路径-->
    <property name="FILE_PATH" value="F:\\log"/>

    <!--
    定义日志输出的媒介
    我们知道,日志的输出是有级别的,优先级从低到高分别是:trace < debug < info < warn < error
    -->
    <!--
    定义console的日志打印,即控制台
    name="consoleLog":定义一个名字叫做"consoleLog"的日志附加器
    class="ch.qos.logback.core.ConsoleAppender":表示日志附加器采用的策略是ConsoleAppender。即打印到控制台
    -->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 默认情况下,每个日志事件都会立即刷新到基础输出流。 这种默认方法更安全,因为如果应用程序在没有正确关闭appender的情况下退出,则日志事件不会丢失。
        但是,为了显着增加日志记录吞吐量,您可能希望将immediateFlush属性设置为false -->
        <immediateFlush>false</immediateFlush>
        <encoder>
            <!--输出格式,上面声明的常量-->
            <pattern>${DEFAULT_LOG_PATTERN}</pattern>
            <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--
    定义debug级别的日志输出,并且采用RollingFileAppender表示日志会滚动打印
    name="consoleLog":定义一个名字叫做"debugLog"的日志附加器
    class="ch.qos.logback.core.rolling.RollingFileAppender":表示日志附加器采用的策略,以滚动文件形式记录
    -->
    <appender name="debugLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--定义文件的路径-->
        <file>${FILE_PATH}/debug.log</file>
        <!--定义日志滚动策略,TimeBasedRollingPolicy是一个基于时间的滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--
            设置按每天的方式来生成文件
            如果把%d{yyyy-MM-dd}换成%d{yyyy-MM-dd_HH_mm}则表示按每分钟来生成。(PS:文件名不能有空格)
            log.gz:gz则表示自动压缩日志文件,不需要压缩,则不要以gz结尾
            -->
            <fileNamePattern>#{LOG_PATH}/debug-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <!--设置文件最搭保存的历史数据,这里默认30天-->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <!--定义日志输出的格式,上面声明的常量-->
        <encoder>
            <pattern>${DEFAULT_LOG_PATTERN}</pattern>
        </encoder>
        <!--        定义日志记录的过滤器,很显然,在这里我们当然选择“级别”过滤器-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--定义debug级别-->
            <level>DEBUG</level>
            <!--如果匹配,则同意打印-->
            <onMatch>ACCPET</onMatch>
            <!--如果不匹配,则拒绝打印-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!--定义debug级别的日志输出,并且采用RollingFileAppender表示日志会滚动打印-->
    <appender name="infoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--定义文件的路径-->
        <file>${FILE_PATH}/info.log</file>
        <!--定义日志滚动策略,TimeBasedRollingPolicy是一个基于时间的滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--
            设置按每天的方式来生成文件
            如果把%d{yyyy-MM-dd}换成%d{yyyy-MM-dd_HH_mm}则表示按每分钟来生成。(PS:文件名不能有空格)
            log.gz:gz则表示自动压缩日志文件,不需要压缩,则不要以gz结尾
            -->
            <fileNamePattern>#{LOG_PATH}/debug-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <!--设置文件最搭保存的历史数据,这里默认30天-->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <!--定义日志输出的格式-->
        <encoder>
            <!--定义日志输出的格式,上面声明的常量-->
            <pattern>${DEFAULT_LOG_PATTERN}</pattern>
        </encoder>
        <!--        定义日志记录的过滤器,很显然,在这里我们当然选择“级别”过滤器-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--定义info级别-->
            <level>INFO</level>
            <!--如果匹配,则同意打印-->
            <onMatch>ACCPET</onMatch>
            <!--如果不匹配,则拒绝打印-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!--
    根记录器(项目所有的日志都会经过这里)
    其实,日志的记录器就像是管道设计一样。字符流进来的时候,会一一通过<appender-ref>设置的管道中,然后根据设置的条件(<filter>标签),匹配则输出
    -->
    <root level="info">
        <appender-ref ref="consoleLog" />
    </root>

    <!--
    PS:这里有一个重重重重重重重重重重重重重重重重点,也是我之前没理解的点
    <logger>跟<root>是什么关系呢?父子关系!(大哥们这个是java代码写的一个api,xml只是约定一些配置!约定!!配置!!understand??)
    <logger>继承于<root>,所以,当<logger>没有指定level的时候,会自动继承<root>标签的level属性
    所以,日志记录的过程,就是在走职责链的过程,即一一通过logger过滤器
    -->
    <!--
    配置我们自己写的代码的日志记录器
    name="com.shen.boot":表示对应包里面的类代码产生的日志才会被下面的记录器记录,否则不会
    level="debug":表示我们的日志记录的级别是debug
    additivity="true":表示我们自定义的记录器日志输出
    -->
    <logger name="com.shen" level="debug" additivity="true">
        <appender-ref ref="debugLog" />
    </logger>
    <logger name="com.shen.boot" level="debug" additivity="true">
        <appender-ref ref="debugLog" />
        <appender-ref ref="infoLog" />
    </logger>
</configuration>

我知道,应该有不少人没有耐心阅读上面这个文件,但我告诉你,B也要B自己看完,里面我加了很多注释,基本上都是必要的内容。自觉点,赶紧回头再看一遍
以上内容都看完了吧,我想你也许有如下疑问,下面还是用我最喜欢的问答形式解答疑问。

日志记录的内部流程是怎样的?

答:如下图所示,用一个简单的流程图表示:
logback日志内部处理流程图
上图有两点需要补充:(我希望你们最好知道“职责链”这个设计模式,可以更好的了解。设计模式传送门

  1. logger过滤器,里面的各个过滤器是如何排序,并且传递的?他们是自下而上,逐级调用的,如下图所示:
    在这里插入图片描述
    我相信这个已经很清晰了吧?这张图也说明了additivity这个属性的用法。
  2. appender过滤器里面的逻辑是什么?
    答:过滤器嘛,逻辑不就是逐个调用吗,至于在这个appender会不会写日志,就是根据你在appender里面的配置咯。如下,你的infoLog配置不就是”只要info级别“的日志吗
	<!--infoLog的filter片段-->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--定义info级别-->
            <level>INFO</level>
            <!--如果匹配,则同意打印-->
            <onMatch>ACCPET</onMatch>
            <!--如果不匹配,则拒绝打印-->
            <onMismatch>DENY</onMismatch>
        </filter>

root标签跟logger标签的关系如何理解?

答:root跟logger之间是父子关系,logger继承于root。细心的朋友肯定看到我在xml文件中的注释了,他们就是用java代码写的,这两个之间就是logger类继承了root类

感谢

来自B站的V哥教程 logback小白入门课程
以及一些CSDN大佬的博客,查阅了不少资料,但这次是第二次总结了,然后第一次总结的时候没记录出处,所以没办法溯源了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/180547.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!