最全的Logback快速实践

简介

logback是当下最受欢迎的log记录工具,高性能,功能全,文档全,同时做者也log4j的系列的开发者, 本文从logback经常使用的组件和功能点进行介绍,并提供了简单的例子参考,logback官网php


java中如何使用logback

pom.xml中引入关键的两个包html

<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>test</scope>
        </dependency>
复制代码

而后在resources目录下建立一个logback.xml就能够了,请参考全量的可用配置文件这个章节java


日志级别

推荐使用如下几种,级别从高到低排列web

Level 描述
ERROR 错误事件可能仍然容许应用程序继续运行
WARN 指定具备潜在危害的状况
INFO 指定可以突出在粗粒度级别的应用程序运行状况的信息的消息
DEBUG 指定细粒度信息事件是最有用的应用程序调试

Appender级别

What is an Appender?正则表达式

Appender class dependency

appender

ConsoleAppender (将日志输出到控制台)

将日志信息打印在控制台中算法

配置 类型 描述
encoder Encoder 日志输出格式
target String 日志输出目标,能够是System.out或者System.err,默认是System.out
withJansi boolean 默认是false,这个使用不到,好像是开启后输出的ANSI会有颜色,具体看官网介绍

sample:spring

<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(将日志输出到文件中)

FileAppender OutputStreamAppender的子类,将日志输出到指定文件中。若是文件已经存在,根据配置属性来判断在末尾追加或者从新生成文件apache

配置 类型 描述
append boolean 默认为true,会将日志追加到现有文件末尾
encoder Encoder 日志输出格式
file String 文件名,能够带路径,如不过文件或目录不存在则会建立,例如: logs/info.log,该属性没有默认值
immediateFlush boolean 一旦有日志产生当即刷新到文件,经过状况下把它设为false,以提升性能,由于会频繁的flush buffer;

sample:tomcat

<configuration>
  <!-- 使用时间戳做为文件名 -->
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>testFile-${bySecond}.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>
复制代码

RollingFileAppender(滚动式输出)

RollingFileAppender继承于FileAppender, 按照一些特定策略生成滚动文件,例如与TimeBasedRollingPolicy策略搭配时,当文件到达指定时间,会从新生成一个新的文件,关于策略,后面章节会有具体详细介绍。bash

配置 类型 描述
append boolean 看FileAppender配置
encoder Encoder 看FileAppender配置
file String 看FileAppender配置
rollingPolicy RollingPolicy 日志滚动策略:配置这个选项会让日志文件按照指定策略进行滚动
triggeringPolicy TriggeringPolicy 触发滚动策略:一般搭配rollingPolicy一块儿使用,用于设置滚动的触发条件

sample:

<appender name="errorAppender" class="ch.qos.logback.core.RollingFileAppender">
    <file>logs/error.log</file>
    <!-- 设置滚动策略 TimeBasedRollingPolicy 按日期滚动 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--设置日志命名模式-->
        <fileNamePattern>errorFile.%d{yyyy-MM-dd}.log</fileNamePattern>
        <!--最多保留30天log-->
        <maxHistory>30</maxHistory>
    </rollingPolicy>
    <!-- 超过150MB时,当即触发滚动策略,生成新的文件 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <maxFileSize>150</maxFileSize>
    </triggeringPolicy>
    <encoder>
        <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>
    </encoder>
</appender>
复制代码

日志文件策略 *Policy(经常使用)

TimeBasedRollingPolicy(按日期滚动策略)

TimeBasedRollingPolicy 多是logback最受欢迎的滚动策略,基于时间的滚动,能够是一天也能够是一个月,这个较为经常使用,一般咱们能够设置一天生成一个新的文件,很好概括,统计

配置 类型 描述
fileNamePattern String log文件命名规则,一般使用%d来按天或按月输出,例如errorFile.%d{yyyy-MM-dd}.log,生成出来的文件相似于errorFile.2018-10-09.log,带上日期后这样天天生成的文件就不会名字重复了,这个还支持选择时区,例如%d{yyyy-MM-dd,UTC}
maxHistory int 日志保留天数,超过该天数的历史日志文件将会被logback异步删除
totalSizeCap int 归档文件的总大小,优先应用maxHistory的策略。
cleanHistoryOnStart boolean 默认为false,触发归档文件当即删除的动做。

滚动输出支持自动压缩,文件名以.gz或者.zip结尾便可,例如:/wombat/foo.%d.gz

sample:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!-- keep 30 days' worth of history capped at 3GB total size -->
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>

    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>
复制代码

SizeAndTimeBasedRollingPolicy(按大小和时间滚动策略)

这个应该是最经常使用的吧,按照指定时间和文件大小的策略来滚动日志。废话很少说看下面的例子

<configuration>
  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
       <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
       <maxFileSize>100MB</maxFileSize>    
       <maxHistory>60</maxHistory>
       <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>


  <root level="DEBUG">
    <appender-ref ref="ROLLING" />
  </root>

</configuration>
复制代码

请注意除“%d”以外的“%i”转换标记。 %i%d令牌都是强制性的。 每当当前日志文件在当前时间段结束以前达到maxFileSize时,它将以增长的索引存档,从0开始


FixedWindowRollingPolicy(以固定的算法策略生成滚动文件 不经常使用)

这个策略不经常使用,咱就很少bb了,属性和其余滚动策略是同样的,一般文件命名规范是这样的:tests.%i.log,当到达条件触发滚动时会生成文件test1.log,test2.log,test3.log ...


SizeBasedTriggeringPolicy(根据大小触发滚动的策略)

这个标签里的配置,用来触发滚动时间的,例如文件大小到了指定值,就是触发滚动

sample:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>test.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
      <fileNamePattern>test.%i.log.zip</fileNamePattern>
      <minIndex>1</minIndex>
      <maxIndex>3</maxIndex>
    </rollingPolicy>

    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>5MB</maxFileSize>
    </triggeringPolicy>
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>
复制代码

fileNamePatten的一些规则(例子,按年,月,日,天,时,分,秒滚动)

例子 描述
/wombat/foo.%d 按天滚动,格式 年-月-日,都生成在一个文件夹中
/wombat/%d{yyyy/MM}/foo.txt 按月滚动,每月生成一个相同的文件,在不一样的月份文件夹中,例如first: /wombat/2018/09/foo.txt,next: /wombat/2018/10/foo.txt
/wombat/foo.%d{yyyy-ww}.log 每周生成一次,每周的第一天开始从新生成
/wombat/foo%d{yyyy-MM-dd_HH}.log 每小时生成一次
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log 每分钟生成一次
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log 按指定时区每分钟生成一次
/foo/%d{yyyy-MM,aux}/%d.log 天天生成一次,按照年和月区分,例如,/foo/2018-09/中存在一个月的log,log名是天天的日期

pattern配置(日志输出格式化)

例子

下面会介绍一些经常使用的配置规则。

<encoder>
    <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
复制代码
  • %-4relative: 将输出日志记录的时间,进行左对齐,宽度为4.
  • %thread: 将输出记录日志的线程号
  • %-5level: 输出5个日志级别,进行左对齐。
  • %logger{35}: 输出日志记录的logger名一般为类名,长度为35。
  • %msg%n: 输出应用程序提供的信息,并换行。

注意:全部关键字在使用的时候必须带上%,如上,-为对其标志

pattern表格

关键字 描述
c{length}
lo{length}
输出logger所属的类目,一般就是所在类的全名,参数为logger名保留长度,默认不填为全名.
%logger com.util.StringUtils com.util.StringUtils
%logger{0} com.util.StringUtils StringUtils
%logger{10} com.util.StringUtils c.u.StringUtils
C{length}
class{length}
和上面用法相似,输出调用者的全名,性能较差,不推荐配置。
contextName
cn|
输出上下文名称
d{pattern}
date{pattern}
输出日志的打印时间,和java中的日期格式化相似
%d 2019-02-12 18:00:00,000
%date 2019-02-12 18:00:00,000
%date{ISO8601} 2019-02-12 18:00:00,000
%date{HH:mm:ss,SSSS} 18:00:00,000
%date{yyyy-MM-dd HH:mm:ss,SSSS} 2019-02-12 18:00:00,000
caller{depth} 输出日志调用者的调用栈深度信息,值越大,输出的栈信息越多
%caller{2} [main]-[INFO]: log test
Caller+0 at com.util.StringUtil.subString(StringUtil.java :22)
Caller+1 at com.util.Main.exec(Main.java :17)
L
line
输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。如不考虑性能问题,可使用
m
msg
message
应用程序提供的信息
M
method
输出执行日志记录的方法名性能较差,如不考虑性能问题,可使用
n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”
p
le
level
输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL
t
thread
输出打印日志的线程名
replace(msg){r,t} msg为日志内容,r是正则表达式,将msg中符合r的内容替换成t。
例如:%replace(%msg){'\s',""}
r
relative
输出自应用启动到输出该log信息耗费的毫秒数

配置:

<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 日期 [线程] [class类]-[日志级别] log内容 回车符号 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n</pattern>
        </encoder>

    </appender>

    <!-- 输出INFO及以上的日志 -->
    <root level="INFO">
        <!-- 让自定义的appender生效 -->
        <appender-ref ref="STDOUT"/>
    </root>

</configuration>

复制代码

控制台输出:

2018-10-09 14:27:55 [main] [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping]-[INFO] Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-09 14:27:55 [main] [org.springframework.jmx.export.annotation.AnnotationMBeanExporter]-[INFO] Registering beans for JMX exposure on startup
2018-10-09 14:27:55 [main] [org.apache.coyote.http11.Http11NioProtocol]-[INFO] Starting ProtocolHandler ["http-nio-6677"]
2018-10-09 14:27:55 [main] [org.apache.tomcat.util.net.NioSelectorPool]-[INFO] Using a shared selector for servlet write/read
2018-10-09 14:27:55 [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer]-[INFO] Tomcat started on port(s): 6677 (http) with context path ''
2018-10-09 14:27:55 [main] [com.xj.plugins.Springboot2AnalyzeApplication]-[INFO] Started Springboot2AnalyzeApplication in 2.014 seconds (JVM running for 3.949)

复制代码

控制台输出的log配置颜色

格式 描述
%black 黑色
%red 红色
%green 绿色
%yellow 黄色
%blue 蓝色
%magenta 品红
%cyan 青色
%white 白色
%gray 灰色
%highlight 高亮色
%bold 更鲜艳色颜色,强化以上全部的颜色,例如%boldRed,%boldBlack

例子:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 日期 [线程] [class类]-[日志级别] log内容 回车符号 -->
            <pattern>%blue(%d{yyyy-MM-dd HH:mm:ss,SSS}) [%cyan(%t)] [%yellow(%c)]-[%highlight(%p)] %m%n</pattern>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;
        </encoder>
    </appender>

    <!-- 输出INFO及以上的日志 -->
    <root level="INFO">
        <!-- 让自定义的appender生效 -->
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>
复制代码

配置事后的控制台输出

增长色彩输出


日志定向输出

logback.xml中如何须要将某中日志输出到文件中可使用过滤器,相似于如下这个例子

xml配置过滤器,例如将error日志输出到error.log中

<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
           <encoder>
               <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c]-[%p] %m%n</pattern>
           </encoder>

           <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
               <!-- rollover daily -->
               <fileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
               <!-- 文件最大30MB,保留60天,总大小20GB -->
               <maxFileSize>30MB</maxFileSize>
               <maxHistory>60</maxHistory>
               <totalSizeCap>20GB</totalSizeCap>
           </rollingPolicy>

           <!-- 过滤器,只写入error级别log -->
           <filter class="ch.qos.logback.classic.filter.LevelFilter">
               <level>ERROR</level>
               <onMatch>ACCEPT</onMatch>
               <onMismatch>DENY</onMismatch>
           </filter>

       </appender>
复制代码

若是有须要特殊log须要定向输出的话能够重写 Filter方法

public class MyLogFilter extends Filter<ILoggingEvent> {
       @Override

       public FilterReply decide(ILoggingEvent event) {
           
           if(event.getMessage() != null
                   && (event.getMessage().startsWith("test")
                   || event.getMessage().startsWith("demo"))) {
               return FilterReply.ACCEPT;
           } else {
               return FilterReply.DENY;
           }
       }
   }
复制代码

而后将filter加入到你的appender中

<!-- 过滤器,写入test和demo开头的日志 -->
<filter class="xx.xxx.xxxx.MyLogFilter" />
复制代码

关闭类中某个级别的log输出

在logback.xml中加入如下配置

OFF表示所有关闭,能够配置指定级别如INFO,DEBUG...

<logger name="xx.xx.class" level="OFF" />
复制代码

logback.xml读取环境变量

logback.xml支持两种读取方式,从系统环境中读取,从spring配置文件中读取

读取系统环境变量 经过${envName}方式获取

<!-- 从系统环境变量读取日志输出目录 -->
<property name="LOG_HOME" value="${log.dir}"/>
复制代码

读取spring配置文件的方式

<!-- 从context中读取因此不须要使用${}获取 -->
<springProperty scope="context" name="LOG_HOME" source="logback.dir"/>
复制代码

默认值设置

若是在环境变量中没有取到LOG_HOME 的值,则会使logs做为默认值,和Shell语法中设置默认值相似

<file>${LOG_HOME:-logs}/test/test-info.log</file>
复制代码

-

全量的可用配置文件

如下配置会生成三个日志文件,具体的策略是:天天会生成一个新的文件,当天日志文件达到指定大小会自动压缩,而且生成新的文件进行记录。

  • main.log(只记录info级别及以上的日志输出)
  • warn.log(只记录warn级别的日志输出)
  • error.log(只记录error级别的日志输出)
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!-- 从spring中获取配置,如获取不到会使用默认值 -->
    <springProperty scope="context" name="LOG_HOME" source="logging.path"/>
    <springProperty scope="context" name="LOG_LEVEL" source="logging.output.level"/>
    <springProperty scope="context" name="LOG_MAX_SIZE" source="logging.file.max-size"/>
    <springProperty scope="context" name="LOG_TOTAL_SIZE_CAP" source="logging.file.total-size-cap"/>
    <springProperty scope="context" name="LOG_MAX_HISTORY" source="logging.file.max-history"/>
    <!-- 输出样式 -->
    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%logger{10}]-[%p] %m%n"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%blue(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%cyan(%t)] [%yellow(%logger{10})]-[%highlight(%p)] %m%n</pattern>
        </encoder>
    </appender>

    <appender name="Main-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME:-logs}/logback/main.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME:-logs}/logback/main-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
            <MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
            <MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
            <totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>


    <appender name="Error-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME:-logs}/logback/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME:-logs}/logback/error-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
            <MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
            <MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
            <totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>

        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="Warn-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME:-logs}/logback/warn.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME:-logs}/logback/warn-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
            <MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
            <MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
            <totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
        <!-- log filter -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    
    <!-- 关闭类中某个级别的输出 OFF所有关闭 , INFO,DEBUG ... <logger name="x.x.Constants"> <level value="OFF"/> </logger> -->

    <!-- log output level -->
    <root level="${LOG_LEVEL:-INFO}">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="Main-Log"/>
        <appender-ref ref="Warn-Log"/>
        <appender-ref ref="Error-Log"/>
    </root>

</configuration>
复制代码
相关文章
相关标签/搜索