LogBack管理日志信息

获取程序运行的细节

Posted by YD Blog on October 10, 2022

LogBack管理日志信息

什么是LogBack

师出同门,与log4j一样,logback也是由Ceki Gülcü开发的开源日志组件,可以说是log4j的改进版;在现如今的项目中,logback的出现次数越来越多,是目前主流首选的日志记录工具。

LogBack结构

logback分成三个模块:logback-core,logback- classic,logback-access。

logback-core提供了logBack的核心功能,是另外两个组件的基础;

logback-classic模块实现了SLF4J API;

logback-access模块与Servlet容器集成提供Http来访问日志的功能。

如何使用

首先需要在pom文件里添加依赖项:

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.3</version>
        </dependency>

更新maven项目,在resources文件夹下新建两个xml文件,分别命名为logback和logback-test,填写以下内容:

<!-- logback.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,比如: 如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds" debug="false">
    <!-- 尽量别用绝对路径,如果带参数不同容器路径解释可能不同,以下配置参数在pom.xml里 -->
    <!-- 日志级别 -->
    <property name="log.root.level" value="info"/>
    <!-- 其他日志级别 -->
    <property name="log.other.level" value="info"/>
    <!-- 日志路径,这里是相对路径,web项目eclipse下会输出到eclipse的安装目录下,如果部署到linux上的tomcat下,会输出到tomcat/bin目录 下 -->
    <property name="log.base" value="logs"/>
    <!-- 模块名称, 影响日志配置名,日志文件名 -->
    <property name="log.moduleName" value="2020-edge-barnacle-application"/>
    <!-- 日志文件大小 -->
    <property name="log.max.size" value="500MB"/>
    <!-- 定义日志输出格式-->
    <property name="log.pattern"
              value="%green(%date{yyyy-MM-dd HH:mm:ss.SSS}) %yellow(%-5level) [%thread] %logger{56}.%method:%L -%msg%n"/>
    <property name="log.charset" value="UTF-8"/>

    <!--控制台输出 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 用来定义日志的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${log.pattern}</pattern>
            <charset>${log.charset}</charset>
        </encoder>
    </appender>

    <!-- 日志文件输出 -->
    <appender name="infoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 -->
        <file>${log.base}/info/${log.moduleName}_info.log</file>
        <!-- 日志输出的文件的格式  -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern>
            <charset>${log.charset}</charset>
        </encoder>
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按天回滚-->
            <fileNamePattern>${log.base}/info/archive/${log.moduleName}_info_%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
            <!--日志最大存储天数-->
            <maxHistory>60</maxHistory>
            <!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 -->
            <maxFileSize>${log.max.size}</maxFileSize>
        </rollingPolicy>
        <!--过滤器,只记录INFO级别的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日志文件输出 -->
    <appender name="warnFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 -->
        <file>${log.base}/warn/${log.moduleName}_warn.log</file>
        <!-- 日志输出的文件的格式  -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern>
        </encoder>
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${log.base}/warn/archive/${log.moduleName}_warn_%d{yyyy-MM-dd}.%i.log.zip
            </fileNamePattern>
            <!--日志最大存储天数-->
            <maxHistory>60</maxHistory>
            <!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 -->
            <maxFileSize>${log.max.size}</maxFileSize>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日志文件输出 -->
    <appender name="errorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 -->
        <file>${log.base}/error/${log.moduleName}_error.log</file>
        <!-- 日志输出的文件的格式  -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern>
        </encoder>
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${log.base}/error/archive/${log.moduleName}_error_%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
            <!--日志最大存储天数-->
            <maxHistory>60</maxHistory>
            <!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 -->
            <maxFileSize>${log.max.size}</maxFileSize>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!-- 为某个包下的所有类的指定Appender 这里也可以指定类名称例如:com.aa.bb.ClassName -->
    <logger name="org.springframework.aop.framework.CglibAopProxy" additivity="false">
        <level value="info" />
        <appender-ref ref="stdout" />
    </logger>
    <!-- root将级别为“DEBUG”及大于“DEBUG”的日志信息交给已经配置好的名为“Console”的appender处理,“Console”appender将信息打印到Console -->
    <root level="info">
        <appender-ref ref="stdout" /> <!-- 标识这个appender将会添加到这个logger -->
        <appender-ref ref="infoFile" />
        <appender-ref ref="warnFile" />
        <appender-ref ref="errorFile" />
    </root>
</configuration>
<!-- logback-test.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,比如: 如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds" debug="true">
    <!-- 尽量别用绝对路径,如果带参数不同容器路径解释可能不同,以下配置参数在pom.xml里 -->
    <!-- 日志级别 -->
    <property name="log.root.level" value="info"/>
    <!-- 其他日志级别 -->
    <property name="log.other.level" value="info"/>
    <!-- 日志路径,这里是相对路径,web项目eclipse下会输出到eclipse的安装目录下,如果部署到linux上的tomcat下,会输出到tomcat/bin目录 下 -->
    <property name="log.base" value="logs"/>
    <!-- 模块名称, 影响日志配置名,日志文件名 -->
    <property name="log.moduleName" value="2020-edge-barnacle-application"/>
    <!-- 日志文件大小 -->
    <property name="log.max.size" value="500MB"/>
    <!-- 定义日志输出格式-->
    <property name="log.pattern"
              value="%green(%date{yyyy-MM-dd HH:mm:ss.SSS}) %yellow(%-5level) [%thread] %logger{56}.%method:%L -%msg%n"/>
    <property name="log.charset" value="UTF-8"/>

    <!--控制台输出 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 用来定义日志的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${log.pattern}</pattern>
            <charset>${log.charset}</charset>
        </encoder>
    </appender>

    <!-- 日志文件输出 -->
    <appender name="infoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 -->
        <file>${log.base}/info/${log.moduleName}_info.log</file>
        <!-- 日志输出的文件的格式  -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern>
            <charset>${log.charset}</charset>
        </encoder>
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按天回滚-->
            <fileNamePattern>${log.base}/info/archive/${log.moduleName}_info_%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
            <!--日志最大存储天数-->
            <maxHistory>60</maxHistory>
            <!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 -->
            <maxFileSize>${log.max.size}</maxFileSize>
        </rollingPolicy>
        <!--过滤器,只记录INFO级别的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日志文件输出 -->
    <appender name="warnFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 -->
        <file>${log.base}/warn/${log.moduleName}_warn.log</file>
        <!-- 日志输出的文件的格式  -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern>
        </encoder>
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${log.base}/warn/archive/${log.moduleName}_warn_%d{yyyy-MM-dd}.%i.log.zip
            </fileNamePattern>
            <!--日志最大存储天数-->
            <maxHistory>60</maxHistory>
            <!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 -->
            <maxFileSize>${log.max.size}</maxFileSize>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日志文件输出 -->
    <appender name="errorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 -->
        <file>${log.base}/error/${log.moduleName}_error.log</file>
        <!-- 日志输出的文件的格式  -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern>
        </encoder>
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${log.base}/error/archive/${log.moduleName}_error_%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
            <!--日志最大存储天数-->
            <maxHistory>60</maxHistory>
            <!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 -->
            <maxFileSize>${log.max.size}</maxFileSize>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!-- 为某个包下的所有类的指定Appender 这里也可以指定类名称例如:com.aa.bb.ClassName -->
    <logger name="org.springframework.aop.framework.CglibAopProxy" additivity="false">
        <level value="info" />
        <appender-ref ref="stdout" />
    </logger>
    <!-- root将级别为“DEBUG”及大于“DEBUG”的日志信息交给已经配置好的名为“Console”的appender处理,“Console”appender将信息打印到Console -->
    <root level="info">
        <appender-ref ref="infoFile" /><!-- 标识这个appender将会添加到这个logger -->
        <appender-ref ref="warnFile" />
        <appender-ref ref="errorFile" />
    </root>
    <!-- 将程序运行时的所有细节打印到控制台(用于学习) -->
    <root level="trace">
        <appender-ref ref="stdout" />
    </root>
</configuration>

这样,在之后的程序运行时就会自动打印调试信息。

配置文件详解

LogBack配置文件通常由一个configuration作为父标签,在其下有多个appender、logger、root标签作为子标签。

  1. configuration:配置根节点
<configuration scan="true" scanPeriod="60" debug="false"></configuration>  
<!-- 
    scan:程序运行时配置文件被修改,是否重新加载。true,重新加载;false,不重新加载;默认为true;

    scanPeriod:监测配置文件被修改的时间间隔,scan属性必须设置为true才可生效;默认为1分钟,默认单位是毫秒;

    debug:是否打印logback程序运行的日志信息。true,打印;false,不打印;默认为false;
 -->
  1. property:属性变量
<configuration scan="true" scanPeriod="60" debug="false">
    <property name="pattern" value="%d{HH:mm:ss.SSS} [%-5level] [%logger] %msg%n" ></property>
</configuration>
<!-- 
    name:变量的名称,可以随意起名,但建议名字要简明直译;

    value:变量的值;
 -->

在配置文件中,可以使用property标签来设置变量,在需要使用的时候,可以用 ${name} 的形式来使用,将变量引入到其他节点中去。如果有多处使用相同的内容,便可使用属性变量的方式进行统一,减少很多不必要的代码。

  1. logger:日志对象

logger分为2种,一种是普通日志对象,另一种是根日志对象。对于大部分应用来说,只设置根日志对象即可。

在java日志系统中,无论是log4j还是logback,他们的日志对象体系都是呈现“树”的形式,根日志对象为最顶层节点,其余包或者类中的日志对象都继承于根日志节点;

对于普通日志对象来说,我们可以设置某一个包或者某一个类的日志级别,还可以单独设置日志的输出目的地

<configuration scan="true" scanPeriod="60" debug="false">   
    <logger name="java.sql" level="debug" addtivity="true">
        <appender-ref ref="CONSOLE" />
    </logger>   
</configuration>
<!-- 
    name:用来指定此logger属于哪个包或者哪个类;

    level:用来指定此logger的日志打印级别;

    addtivity:是否向上传递日志打印信息。之前说了,logger对象呈现一个树的结构,根logger是树的顶端,下面的子logger的addtivity属性如果设置为true则会向上传递打印信息,出现日志重复打印的现象;

    appender-ref:日志输出目的地,将此logger所打印的日志交给此appender
 -->

值得注意的是,上面的例子中,如果此logger没有指定appender,而且addtivity也设置为true,那么此logger对应的日志信息只会打印一遍,是由root来完成的;但是如果addtivity设置成false,那么此logger将不会输出任何日志信息。

  1. logger:根日志对象
也是日志对象中的一种,但它位于logger体系中的最顶层。当一个类中的logger对象进行打印请求时,如果配置文件中没有为该类单独指定日志对象,那么都会交给root根日志对象来完成。 节点中只有一个level属性,还可以单独指定日志输除目的地。 ```XML ``` 5. appender:日志输出目的地 与log4j中的appender一样,logback中的节点也同样负责日志输出的目的地。 appender中有2个必填属性--name和class。name为节点的名称,class为的全限定类名,也就是日志输出目的地的处理类。此外,我们还可以在中单独指定日志的格式,设置日志过滤器等操作。 ```XML %-4relative [%thread] %-5level %logger{35} - %msg %n ``` 在logback中,主要有以下四种日志目的地处理类: * ch.qos.logback.core.ConsoleAppender 将日志输出到控制台,可以在其节点中设置子节点,设置日志输出的格式 ```XML e:/log.out true false %-4relative [%thread] %-5level %logger{35} - %msg%n ``` * ch.qos.logback.core.FileAppender 将日志输出到具体的磁盘文件中,可以单独指定具体的位置,也可以设置日志的输出格式 ```XML e:/log.out true false %-4relative [%thread] %-5level %logger{35} - %msg%n ``` 子节点:新增的日志是否以追加到文件结尾的方式写入到log.out文件中,true为追加,fasle为清空现存文件写入。 子节点:日志是否被安全的写入磁盘文件,默认为false。如果为true,则效率低下。 * ch.qos.logback.core.rolling.RollingFileAppender 滚动记录日志,当符合节点中设置的条件时,会将现有日志移到新的文件中去。节点中可设置的条件为:文件的大小、时间等 ```XML e:/log.out true false testLog-%d{yyyy-MM-dd}.log 30 %-4relative [%thread] %-5level %logger{35} - %msg%n ``` * ch.qos.logback.classic.AsyncAppender 异步记录日志,内部通过使用缓存的方式来实现异步打印,将日志打印事件event放入缓存中。具体数据结构为BlockingQueue ```XML e:/log.out true false %-4relative [%thread] %-5level %logger{35} - %msg%n 0 512 ``` 子节点:指的是BlockingQueue的队列容量大小,默认为256个。 子节点:如果BlockingQueue中还剩余20%的容量,那么程序会丢弃TRACE、DEBUG和INFO级别的日志打印事件event,只保留WARN和ERROR级别的。为了保留所有的日志打印事件,可以将该值设置为0。