logback配置详解 logback中文文档

本文大部分来自于官网文档,logback官方文档:https://logback.qos.ch/manual/introduction.html

logback作为log4j的改进版,所有在使用上和log4j也很相似,由三个模块组成:
logback-core:其它两个模块的基础模块
logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能

通常我们只需要使用logback-core和logback-classic即可。

Logger, Appenders and Layouts

logback的三个主要组成为Logger, Appenders and Layouts,和log4j一样。Logger包含在loback-classic里面,而Appender和Layout则是在logback-core里面。

Logger 作为日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。
Appender 主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、 MySQL、PostreSQL、 Oracle和其他数据库、 JMS和远程UNIX Syslog守护进程等。
Layout 负责把事件转换成字符串,格式化的日志信息的输出。

Logger:

和log4j一样,大小写敏感,具有父子关系,通过"."来实现。比如com.foo就是com.foo.test的父Logger。
rootLogger是Logger的顶级父Logger,所有的Logger都是他的子集。
可以通过Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);获取rootLogger。

Level:

Logger的级别定义在ch.qos.logback.classic.Level里面,按照等级从高往低排列如下:
OFF > ERROR > WARN > INFO > DEBUG > TRACE > ALL。

如果一个Logger没有指定Level,那么他会继承他的父Logger的Level,如果没有那么就直接继承rootLogger的Level。比如com.foo.test会继承com.foo,如果没有那么就找com,还是没有就直接继承rootLogger中指定的Level。
为了确保每个Logger最终都会有一个Level,一般会指定rootLogger的Level,默认为DEBUG级别。
只有当我们调用的打印方法的等级大于或等于该Logger指定的等级的时候才会打印。比如:XXX.info()只有在XXX的Logger的等级在info和info之上时才会打印。

Logger的获取:

我们通过org.slf4j.LoggerFactory 的getLogger()来获取Logger,getLogger的参数就是这个Logger的名字,如果传入的参数相同,那么和Logger4j一样,我们将会获取到同一个Logger对象。
Logger的参数名字是可以自由指定的,但是通常,我们建议使用Logger所在类的class来命名这个Logger

Appender:

Appender用来指定Log的输出目的地。目前appender支持输出到Console, file, remote socket servers, Mysql, JMS等等。
一个Logger可以指定多个Appender,和log4j一样。一个Logger的输出会输出到他的所有Appender中包括他的父Logger的Appender。比如rootLogger指定了一个Console的Appender,那么所有的Logger都会输出到Console。

Appender都是继承自ch.qos.logback.core.Appender
下面介绍一些常用的appender:

OutputStreamAppender:

这个其实不常用,但是他是ConsoleAppender,FileAppender 的父 类,所以先介绍一个他。他有两个属性encoder,immediateFlush。encoder默认为PatternLayoutEncoder用于格式化输出,后面会介绍 。immediateFlush默认为true,作用是指定log立即输出到目的地中。outputStreamAppender的继承关系图如下:
在这里插入图片描述
可以看到常用的ConsoleAppender,FileAppender和RollingFileAppender都是他的子类,所以我们先介绍了他。

ConsoleAppender:

通过System.out或者System.error将日志打印到控制台。他的主要属性是target,用来指定输出到System.out或者System.error,默认为System.out。

示例:

<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

FileAppender:

输出log到文件中。通过file属性决定输出到哪个文件中,通过append属性决定当文件存在时是追加输出日志,还是删掉旧文件重新生成一个输出日志。

示例:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>testFile.log</file>
    <append>true</append>
    <!-- set immediateFlush to false for much higher logging throughput -->
    <immediateFlush>true</immediateFlush>
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>
独特的文件名(根据timestamp):

如果我们想要根据项目的启动时间命名文件,我们可以使用 <timestamp> 来完成。

示例:

<configuration>
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <!-- 使用上面的bySecond属性命令文件 -->
    <file>log-${bySecond}.txt</file>
    <encoder>
      <pattern>%logger{35} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

<timestamp>有几个属性,上面的KEY指定这个timestamp的名字为bySecond,datePattern用来格式化时间,规则按照SimpleDateFormat来。

RollingFileAppender:

是FileAppender的子类,指定日志输出到文件,不过他可以配置按照某种规则备份之前输出的日志的文件,然后重新生成一个文件输出新的日志

RollingFileAppender有两个主要的组成:

RollingPolicy:

当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类。

ch.qos.logback.core.rolling.TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。有以下子节点:
fileNamePattern:必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%d{yyyy-MM}。如果直接使用 %d,默认格式是 yyyy-MM-dd。RollingFileAppender的file字节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;
如果没设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\”会被当做目录分隔符。
maxHistory:日志最大保存的日期。比如如果你设置的pattern是按天算的,那么设置maxHistory为30,那么会自动删除30天之前的日志。
totalSizeCap:日志最大保存的大小。当超过该值,会自动删除老的日志文件。必须和maxHistory一起使用,而且maxHistory先生效,其次是判断是否达到totalSizeCap。
cleanHistoryOnStart:默认false。如果设置为true,再项目启动的时候会自动删除老的日志文件。

triggeringPolicy:

告知 RollingFileAppender 什么时候激活滚动。
ch.qos.logback.core.rolling.FixedWindowRollingPolicy 根据固定窗口算法重命名文件的滚动策略。有以下子节点:
minIndex:窗口索引最小值
maxIndex:窗口索引最大值,当用户指定的窗口过大时,会自动将窗口设置为12。
fileNamePattern:必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz。

示例:

<configuration> 
   <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
         <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern> 
         <maxHistory>30</maxHistory> 
      </rollingPolicy> 
      <encoder> 
         <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> 
      </encoder> 
   </appender> 
   <root level="DEBUG"> 
      <appender-ref ref="FILE" /> 
   </root> 
</configuration>

备注:上述配置表示每天生成一个日志文件,文件名为logFile.yyyy-MM-dd.log,保存30天的日志文件

Encoder:

和layout一样,用来格式化输出。Encoder是在0.9.19版本之后的logback引入的。在这个版本之前,大部分的appender使用layout来格式化输出,但之后FileAppender和他的子类推荐使用encoder来代替layout。
常用的是PatternLayoutEncoder,前面我们也介绍了,这是默认的encoder,所以我们不用指定,直接使用<encoder>标签就好了。
PatternLayoutEncoder的组成和layout一样,如下:

Conversation WordEffect
%c{length} , %lo{length}, %logger{length}打印logger的名字。length不给,输出logger全名。
%C{length}, %class{length}打印调用logger的类的全名。length不给,打印全类名。
%d{pattern} , %date{pattern} , %d{pattern, timezone} , %date{pattern, timezone}日志打印的时间,pattern按照simpledateformat的格式,默认yyyy-MM-dd hh:mm:ss,SSS。第二个参数是时区。例如%date{HH:mm:ss.SSS, Australia/Perth}
%F ,%file打印调用logger的java源码文件名,速度不快,避免使用。
%L , %line打印输出log的行数。
%m , %msg , %message打印logger输出的日志信息,就是调用logger的方法的时候传入的log字符串。
%M , %method打印调用该logger的方法名。
%n换行符
%p , %le , %level打印该日志的等级
%t , %thread打印线程名
\%打印%号

格式化修饰器:可以限制上面的ConversationWord的宽度和左右对齐。
比如:

Conversation WordEffect
%20logger最小宽度20,当小于20时右对齐
%-20logger最小宽度20,当小于20时左对齐
%.30logger最大宽度30,当logger名大于30的时候会从开始处开始阶段。
%20.30logger最小20,最大30,小于20的时候右对齐,大于30的时候开始处截断
%-20.30logger最小20,最大30,小于20的时候左对齐,大于30的时候开始处截断
%.-30logger最大30,超出时从末尾开始截断。

Layout:

Layout的作用是指定日志的输出格式。因为一般使用的都是encoder,所以就不介绍了。

Filter:

过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。
    返回DENY,日志将立即被抛弃不再经过其他过滤器;
    返回NEUTRAL,有序列表里的下个过滤器过接着处理日志;
    返回ACCEPT,日志会被立即处理,不再经过剩余过滤器。

    
    过滤器被添加到<appender> 中,为<appender> 添加一个或多个过滤器后,可以用任意条件对日志进行过滤。 有多个过滤器时,按照配置顺序执行。
  下面是几个常用的过滤器 :

LevelFilter :

级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据 onMath 和 onMismatch 接收或拒绝日志。
    有以下子节点 :
      <level> : 设置过滤级别。
      <onMatch> : 用于配置符合过滤条件的操作。
      <onMismatch> : 用于配置不符合过滤条件的操作。
    例如:将过滤器的日志级别配置为info,所有info级别的日志交给appender处理,非info级别的日志,被过滤掉。
    XML :

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <property name="contextName" value="limeLog"/>
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HH:mm:ss"/>
    <contextName>${contextName} - ${bySecond}</contextName>
    <!-- 表示打印到控制台 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    	<!-- 过滤调除了info以外的日志,只打印info的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- encoder 默认配置为PatternLayoutEncoder --> 
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <target>System.err</target>
    </appender>
    <logger name="limeLogback.LogbackDemo" level="debug">
        <appender-ref ref="STDOUT"/>
    </logger>
    <root/>
</configuration>

ThresholdFilter :

临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。
    有以下子节点 :
      <level> : 设置过滤级别。
    例如:过滤掉所有低于info级别的日志。

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <property name="contextName" value="limeLog"/>
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HH:mm:ss"/>
    <contextName>${contextName} - ${bySecond}</contextName>
    
    <!-- 表示打印到控制台 -->
    <appender name="limeFlogger" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>
        <!-- encoder 默认配置为PatternLayoutEncoder --> 
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <target>System.err</target>
    </appender>
    
    <logger name="LogbackDemo" level="debug">
        <appender-ref ref="limeFlogger"/>
    </logger>
    <root/>
</configuration>

这样配置之后,虽然LogbackDemo这个logger的日志级别时debug,但是使用了limeFlogger后过滤了info之下的日志,也就是不会打印debug的日志。

实例:

maven依赖:

  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.21</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.1.7</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.1.7</version>
      </dependency>
  </dependencies>

logback.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 属性描述 scan:设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
    debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 定义日志文件 输入位置 -->
    <property name="log_dir" value="logs/" />
    <!-- 日志最大的历史 30天 -->
    <property name="maxHistory" value="30"/>
    
    <!-- ConsoleAppender 控制台输出日志 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 对日志进行格式化 -->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n</pattern>
        </encoder>
    </appender>

    <!-- ERROR级别日志 -->
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录ERROR级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志输出位置  可相对、和绝对路径 -->
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/error-log.log</fileNamePattern>
            <!-- 最大保存30天-->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- WARN级别日志 appender -->
    <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录WARN级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/warn-log.log
            </fileNamePattern>
            <!-- 日志最大的历史 30天 -->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- INFO级别日志 appender -->
    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录INFO级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/info-log.log
            </fileNamePattern>
            <!-- 日志最大的历史 30天 -->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="DruidFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名 -->
            <FileNamePattern>${log_dir}/settle-query.log-druid-%d{yyyy-MM-dd}</FileNamePattern>
            <!--日志文件保留天数 -->
            <MaxHistory>90</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <!-- DEBUG级别日志 appender -->
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录DEBUG级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/debug-log.log
            </fileNamePattern>
            <!-- 日志最大的历史 30天 -->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- TRACE级别日志 appender -->
    <appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录ERROR级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>TRACE</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/trace-log.log
            </fileNamePattern>
            <!-- 日志最大的历史 30天 -->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

<!-- 指定其他logger的Appender -->
    <logger name="org.springframework" value="WARN" />
	<logger name="org.apache" value="WARN" />
	<logger name="com.netflix" value="WARN" />
	<logger name="me.chanjar" value="WARN" />
	<logger name="com.ulisesbocchio" value="WARN" />
	<logger name="org.hibernate" value="WARN" />
	<logger name="com.github.liuweijw" value="INFO" />
	<logger name="c.n.discovery" value="WARN" />
	<logger name="o.s.c.s" value="WARN" />
	<logger name="c.u.j.encryptor" value="WARN" />
	<logger name="o.s.boot" value="WARN" />
<!-- 指定druid的日志级别为DEBUG,除了继承rootLogger的appender外,自己还加了DruidFILE -->
    <logger name="druid" level="DEBUG">
        <appender-ref ref="DruidFILE" />
    </logger>
    <!-- 指定rootLogger级别   INFO,appender为STDOUT,ERROR,INFO-->
    <root level="INFO">
        <!-- 控制台输出 -->
        <appender-ref ref="STDOUT" />
        <!-- 文件输出 -->
        <appender-ref ref="ERROR" />
        <appender-ref ref="INFO" />
    </root>
</configuration>

这个配置之后会在当前目录生成一个logs文件夹,logs文件夹会每天生成一个yyyy-MM-dd命名的文件夹,然后每天的trace,info,warn,error-log.log会生成到对应日期的文件夹下面。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值