最全的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>
複製代碼
相關文章
相關標籤/搜索