日誌框架整理--logback

logback是有log4j 創始人設計的又一個開源日誌框架
logback 當前分爲三個模塊:logbakc-core,logback-classic 和 logback-access

  • logback-core:是其他兩個模塊的基礎模塊
  • logback-classic:是log4j的一個改良版本。此外logback-classic 完整實現SLF4J API,所以可以很方便的更換成其他日誌系統,如 log4j 或 JDK14 Logging
  • logback-access:訪問模塊與Servlet容器基礎,提供通過http訪問日誌的功能。

maven:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.7</version>
</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-access</artifactId>
    <version>1.1.7</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.7</version>
</dependency>

logback, 一個“通用,可靠,快速又靈活的Java日誌框架”

在src目錄下建立logback.xml
logback查找順序:

  1. 首先會試着查找logback.groovy文件
  2. 當沒有找到時,繼續試着查找 logback-test.xml 文件
  3. 當沒有找到時,繼續試着查找 logback.xml 文件
  4. 如果仍然沒有找到,則使用默認配置(打印到控制檯)

自定義日誌配置

根據不同的日誌系統,可以按照如下規則組織配置文件名,就可以被正確加載:
Logback:logback-spring.xml,logback-spring.groovy,logback.xml,logback.groovy
Log4j: log4J-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
Log4j2: log4j2-spring.xml, log4j2.xml
JDK(Java Util Logging): logging.properties

Spring Boot 官方推薦優先使用帶有-spring的文件名作爲你的日誌配置(如使用logback-spring.xml,而不是logback.xml), 命名爲logback-spring.xml 的日誌配置文件,spring boot 可以爲它添加一些spring boot特有的配置項。
默認的命名規則,並且放在 src/main/resources 下面即可

如果你不想用 logback.xml 作爲 logback 配置的名字,application.yml 可以通過 logging.config 屬性指定自定義的名字:
logging.config=classpath:logging-config.xml
雖然一般並不需要改變配置文件的名字,但是如果你想針對不同運行是profile使用不同的配置,這個功能會很有用。
一般不需要這個屬性,而是直接在 logback-spring.xml 中使用 springProfile配置,不需要logging.config 指定不同環境使用不同配置文件。

上代碼:

package logback;  
  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
  
public class LogbackDemo {  
    private static Logger log = LoggerFactory.getLogger(LogbackDemo.class);  
    public static void main(String[] args) {  
        log.trace("======trace");  
        log.debug("======debug");  
        log.info("======info");  
        log.warn("======warn");  
        log.error("======error");  
           
        String name = "Aub";  
        String message = "3Q";  
        String[] fruits = { "apple", "banana" };  
          
        // logback提供的可以使用變量的打印方式,結果爲"Hello,Aub!"  
        log.info("Hello,{}!", name);  
          
        // 可以有多個參數,結果爲“Hello,Aub! 3Q!”  
        log.info("Hello,{}!   {}!", name, message);  
          
        // 可以傳入一個數組,結果爲"Fruit:  apple,banana"  
        log.info("Fruit:  {},{}", fruits);   
    }  
}  

configuration

  1. 根節點 configuration 包含的屬性:
  • scan:
    此屬性設置爲true,配置文件如果發生改變,將會被重新加載,默認爲true
  • scanPeriod:
    設置監測配置文件是否有修改的時間間隔,如果沒有給出事件單位,默認單位是毫秒。當scan爲true時,此屬性默認生效。默認的時間將爲1分鐘。
  • debug:
    此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態。默認爲false。
    例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">  
      <!-- 其他配置省略-->  
</configuration>  
  1. 根節點 configuration 的子節點:
  • contextName
    每個logger都關聯到logger上下文,默認上下文名稱爲“default”。但可以使用設置成其他名字,用於區分不同應用程序的記錄。一旦設置,不能修改。可以通過%contextName來打印日誌上下文名稱,一般來說我們不用這個屬性,可有可無.
    例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">  
      <contextName>myAppName</contextName>  
      <!-- 其他配置省略-->  
</configuration> 
  • property
    用來定義變量值的標籤,property 有兩個屬性,name和value;通過property定義的值會被插入到 logger上下文中。定義變量後,可以使用 ${} l來使用變量。
    例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">  
      <property name="APP_Name" value="myAppName" />   
      <contextName>${APP_Name}</contextName>  
      <!-- 其他配置省略-->  
<!-- 系統日誌輸出 -->
	<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${APP_Name}/boss.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!-- 按天回滾 daily -->
			<fileNamePattern>${APP_Name}/boss.%d{yyyy-MM-dd}.log</fileNamePattern>
			<!-- 日誌最大的歷史 30天 -->
			<maxHistory>60</maxHistory>
			<!--用來指定日誌文件的上限大小,那麼到了這個值,就會刪除舊的日誌-->
			<!--<totalSizeCap>1GB</totalSizeCap>-->
		</rollingPolicy>
		<encoder>
			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n</pattern>
		</encoder>
	</appender>
</configuration> 
  • timestamp
    兩個屬性:
    • key:標識此 timestamp 的名字
    • datePattern: 設置將當前時間轉換爲字符串的模式,遵循 java.txt.SimpleDateFormat 的格式。
      例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">  
      <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>   
      <contextName>${bySecond}</contextName>  
      <!-- 其他配置省略-->  
</configuration>
  • logger
    用來設置某一個包或者具體的某一個類的日誌打印級別,以及指定 appender.
    包含的屬性:
    • name:
      用來指定受此logger約束的某一個包或者具體的某一個類。
    • level:
      用來設置打印級別,大小寫無關:TRACE,DEBUG,INFO,WARN,ERROR,ALL和OFF,還有一個特殊值 INHERITED 或者同義詞NULL,代碼強制執行上級的級別。
      如果未設置此屬性,那麼當前logger將會繼承上級的打印級別。
    • additivity:
      是否向上級logger傳遞打印信息。默認是true。
      logger可以包含零個或多個 appender-ref 元素,標識這個 appender 將會添加到這個 lgger
  • root
    也是logger元素,但是它是根logger。只有一個level屬性,因爲已經被命名爲“root”
    • level
      用來設置打印級別,大小寫無關,默認是debug
      root 可以包含多個 appender-ref 元素,標識這個appender將會添加到這個 logger
      例如:
package logback;  
  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
  
public class LogbackDemo {  
    private static Logger log = LoggerFactory.getLogger(LogbackDemo.class);  
    public static void main(String[] args) {  
        log.trace("======trace");  
        log.debug("======debug");  
        log.info("======info");  
        log.warn("======warn");  
        log.error("======error");  
    }  
}  

logback.xml 配置文件:

<configuration>   
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
    <!-- encoder 默認配置爲PatternLayoutEncoder -->   
    <encoder>   
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>   
    </encoder>   
  </appender>   
   
  <!-- logback爲java中的包 -->   
  <logger name="logback"/>   
  <!--logback.LogbackDemo:類的全路徑 -->   
  <logger name="logback.LogbackDemo" level="INFO" additivity="false">  
    <appender-ref ref="STDOUT"/>  
  </logger>   
    
  <root level="ERROR">             
    <appender-ref ref="STDOUT" />   
  </root>     
</configuration>  

appender

是 configuration的子節點,是負責寫日誌的組件
有兩個必要屬性:
* name: 指定appender的名稱
* calss:指定appender的全限定名
  1. ConsoleAppender:
    把日誌添加到控制檯,子節點:
    • encoder: 對日照進行格式化
    • target:字符串 System.out 或者 System.err, 默認System.out
      例如:
<configuration>  
  
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
    <encoder>  
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>  
    </encoder>  
  </appender>  
  
  <root level="DEBUG">  
    <appender-ref ref="STDOUT" />  
  </root>  
</configuration>  
  1. FileAppender
    把日誌添加到文件,子節點:
    • file: 被寫入的文件名,可以是相對目錄,也可以說是絕對目錄,如果上級目錄不存在會自動創建,沒有默認值
    • append:如果是true,日誌被追加到文件結尾,如果是false,清空現存文件,默認是true。
    • encoder:對記錄時間進行格式化
    • prudent:如果是true,日誌會被安全的寫入文件,即使其他的FileAppender也在此文件做寫入操作,效率低,默認是false。
      例如:
<configuration>  
  
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">  
    <file>testFile.log</file>  
    <append>true</append>  
    <encoder>  
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>  
    </encoder>  
  </appender>  
          
  <root level="DEBUG">  
    <appender-ref ref="FILE" />  
  </root>  
</configuration>
  1. RollingFileAppender:
    滾動記錄文件,先將日誌記錄到指定文件,當符合某個條件時,將日誌記錄到其他問題。
    子節點:

    • file:被寫入的文件名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動創建,沒有默認值。
    • append:如果是 true,日誌被追加到文件結尾,如果是 false,清空現存文件,默認是true。
    • encoder:對記錄事件進行格式化。
    • rollingPolicy: 當發生滾動時,決定RollingFileAppender的行爲,涉及文件移動和重命名。
    • triggeringPolicy:告知 RollingFileAppender 何時激活滾動
    • prudent: 當爲true時,不支持FixedWindowRollingPolicy. 支持 TimeBasedRollingPolicy,但是有兩個限制:1. 不支持也不允許文件壓縮;2:不能設置file屬性,必須留空。

    rollingPolicy:

    • TimeBasedRollingPolicy
      最常用的滾動策略,它根據實際來制定滾動策略,既負責滾動,也負責觸發滾動。子節點:
      • fileNamePattern
        必要節點,包含文件名及%d 轉換符。%d 可以包含一個 java.text.SimpleDateFormat制定的時間格式,如" %d{yyyy-MM} 。如果直接使用%d,默認格式是 yyyy-MM-dd。RollingFileAppender 的file子節點可有可無,通過設置file,可以爲活動文件和歸檔文件制定不同位置,當前日誌總是極力到file指定的文件(活動文件),活動文件的名字不會改變;如果沒設置file,活動文件的名字會根據 fileNamePattern 的值,每隔一段時間改變一次。"/" 或 ""會被當做目錄分隔符。
      • maxHistory
        可選節點,控制保留的歸檔文件的最大數量,超出數量就刪除文件。假設設置每個月滾動,且 maxHistory是6,則只保存最近6個月的文件,刪除之前的舊文件。注意,刪除舊文件,那些爲了歸檔而創建的目錄也會被刪除。關於保存的時間的單位,是根據時間格式的單位。
    • FixedWindowRollingPolicy
      根據固定窗口算法重命名文件的滾動策略。子節點:
      • minIndex: 窗口索引最小值
      • maxIndex:窗口索引最大值,當用戶指定的窗口過大時,會自動將窗口設置爲12
      • fileNamePattern:必須包含 %i。例如,假設最小值和最大值分別爲1和2,命名模式爲 mylog%i.log,會產生歸檔文件mylog1.log 和 mylog2.log。還可以指定文件壓縮選項,例如,mylog%i.log.gz 或者 mylog%i.log.zip。

    triggeringPolicy:
    * SizeBasedTriggeringPolicy
    查看當前活動文件的大小,如果超過指定大小會告知RollingFileAppender 觸發當前活動文件滾動。只有一個節點:
    * maxFileSize:活動文件的大小,默認值是10MB

例如:
每天生產一個日誌文件,保存30天的日誌

<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>  

例如:
按照固定窗口模式生產日誌文件,當文件大於20MB時,生產新的日誌文件。窗口大小1到3,當保存了3個歸檔文件後,將覆蓋最早的日誌。

<configuration>   
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">   
    <file>test.log</file>   
   
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">   
      <fileNamePattern>tests.%i.log.gz</fileNamePattern>   
      <minIndex>1</minIndex>   
      <maxIndex>3</maxIndex>   
    </rollingPolicy>   
   
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">   
      <maxFileSize>20MB</maxFileSize>   
    </triggeringPolicy>   
    <encoder>   
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>   
    </encoder>   
  </appender>   
           
  <root level="DEBUG">   
    <appender-ref ref="FILE" />   
  </root>   
</configuration>  

另外,還是SocketAppender,SMTPAppender,DBAppender,SyslogAppender,SiftingAppender,並不常用。

  • encoder
    負責兩件事,一是把日誌信息轉換成字節數組,二是把字節數組寫入到輸出流
    目前 PatterLayoutEncoder 是唯一且有用的默認的 encoder,有一個節點pattern,用來設置日誌的輸入格式。
    使用%加轉換符的方式,如果要輸出%,則必須用 \ 對 % 進行轉義。

例如:

<encoder>   
   <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>   
</encoder
  • pattern 裏轉換符說明:

    • c {length } /lo {length } /logger {length }
      輸出日誌的logger名,可有一個整形參數,功能是縮短logger名,設置爲0表示只輸入logger最右邊點符號之後的字符串。 Conversion specifier Logger name Result
      %logger mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar
      %logger{0} mainPackage.sub.sample.Bar Bar
      %logger{5} mainPackage.sub.sample.Bar m.s.s.Bar
      %logger{10} mainPackage.sub.sample.Bar m.s.s.Bar
      %logger{15} mainPackage.sub.sample.Bar m.s.sample.Bar
      %logger{16} mainPackage.sub.sample.Bar m.sub.sample.Bar
      %logger{26} mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar

    • C {length } /class {length }
      輸出執行記錄請求的調用者的全限定名。參數與上面的一樣。儘量避免使用,除非執行速度不造成任何問題。

    • contextName /cn
      輸出上下文名稱。

    • d {pattern } /date {pattern }
      輸出日誌的打印日誌,模式語法與java.text.SimpleDateFormat 兼容。 Conversion Pattern Result
      %d 2006-10-20 14:06:49,812
      %date 2006-10-20 14:06:49,812
      %date{ISO8601} 2006-10-20 14:06:49,812
      %date{HH:mm:ss.SSS} 14:06:49.812
      %date{dd MMM yyyy ;HH:mm:ss.SSS} 20 oct. 2006;14:06:49.812

    • F / file
      輸出執行記錄請求的java源文件名。儘量避免使用,除非執行速度不造成任何問題。

    • caller{depth}caller{depth, evaluator-1, … evaluator-n}
      輸出生成日誌的調用者的位置信息,整數選項表示輸出信息深度。
      例如, %caller{2}   輸出爲:

      0 [main] DEBUG - logging statement
      Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
      Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
      例如, %caller{3}   輸出爲:

      16 [main] DEBUG - logging statement
      Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
      Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
      Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)

    • L / line
      輸出執行日誌請求的行號。儘量避免使用,除非執行速度不造成任何問題。

    • m / msg / message
      輸出應用程序提供的信息。

    • M / method
      輸出執行日誌請求的方法名。儘量避免使用,除非執行速度不造成任何問題。

    • n
      輸出平臺先關的分行符“\n”或者“\r\n”。

    • p / le / level
      輸出日誌級別。

    • r / relative
      輸出從程序啓動到創建日誌記錄的時間,單位是毫秒

    • t / thread
      輸出產生日誌的線程名。

    • replace(p ){r, t}
      p 爲日誌內容,r 是正則表達式,將p 中符合r 的內容替換爲t 。
      例如, “%replace(%msg){’\s’, ‘’}”

  • 格式修飾符,與轉換符共同使用
    可選的格式修飾符位於 % 和 轉換符之間,
    第一個可選修飾符是左對齊的標誌,符號是減號“-”;接着是可選的最小寬度修飾符,用十進制數表示。如果字符小於最小寬度,則左填充或右填充,默認是左填充(即右對齊),填充符是空格。如果字符大於最小寬度,字符永遠不會被截斷。最大寬度修飾符,符號是點號".“後面加十進制。如果字符大於最大寬度,則從前面截斷。點符號”."後面加減號“-”再加數字,表示從尾部截斷。
    例如:%-4relative 表示將輸出從程序啓動到創建日誌記錄的時間,進行左對齊,最小寬度爲4.

filter

過濾器,執行一個過濾器會返回枚舉值DENY,NEUTRAL,ACCEPT其中之一。

  • 返回DENY,日誌將立即被拋棄而不再經過其他過濾器
  • 返回NEUTRAL,有序列表中的下個過濾器會接着處理日誌
  • 返回ACCEPT,日誌會被立即處理,不再經過剩餘過濾器

過濾器被添加到 Appender中,爲Appender添加一個或奪歐冠過濾器後,可以用任意條件對日誌進行過濾。Appender有多個過濾器時,安卓配置順序執行。

  • 常用過濾器:
    1. LevelFilter:級別過濾器,根據日誌級別進行過濾。如果日誌級別等於配置級別,過濾器會根據 onMatch 和 onMismatch 接收或拒絕日誌。子節點:
      • level:設置過濾級別
      • onMatch: 用於配置符合過濾條件的操作
      • onMismatch:用於配置不符合過濾條件的操作
        例如:將過濾器的日誌級別配置爲INFO,所以INFO級別的日誌交給appender處理,非INFO級別的日誌,被過濾掉。
<configuration>   
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">   
    <filter class="ch.qos.logback.classic.filter.LevelFilter">   
      <level>INFO</level>   
      <onMatch>ACCEPT</onMatch>   
      <onMismatch>DENY</onMismatch>   
    </filter>   
    <encoder>   
      <pattern>   
        %-4relative [%thread] %-5level %logger{30} - %msg%n   
      </pattern>   
    </encoder>   
  </appender>   
  <root level="DEBUG">   
    <appender-ref ref="CONSOLE" />   
  </root>   
</configuration>  
  1. ThresholdFilter
    臨界值過濾器,過濾掉低於指定臨界值的日誌。當日志級別高於或等於臨界值時,過濾器返回NEUTRAL;當日志界別低於臨界值時,日誌會被拒絕。
    例如:過濾掉所有低於INFO級別的日誌。
<configuration>   
  <appender name="CONSOLE"   
    class="ch.qos.logback.core.ConsoleAppender">   
    <!-- 過濾掉 TRACE 和 DEBUG 級別的日誌-->   
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">   
      <level>INFO</level>   
    </filter>   
    <encoder>   
      <pattern>   
        %-4relative [%thread] %-5level %logger{30} - %msg%n   
      </pattern>   
    </encoder>   
  </appender>   
  <root level="DEBUG">   
    <appender-ref ref="CONSOLE" />   
  </root>   
</configuration>  

多環節日誌輸出

通過springProfile 標籤

<configuration>
    ...
 
    <!-- 測試環境+開發環境. 多個使用逗號隔開. -->
    <springProfile name="test,dev">
        <logger name="com.example.demo.controller" level="DEBUG" additivity="false">
            <appender-ref ref="consoleLog"/>
        </logger>
    </springProfile>
 
    <!-- 生產環境. -->
    <springProfile name="prod">
        <logger name="com.example.demo.controller" level="INFO" additivity="false">
            <appender-ref ref="consoleLog"/>
        </logger>
    </springProfile>
</configuration>
application.yml增加環境選擇的配置active: dev
 
server:
  port: 9010
 
spring:
  profiles:
    active: dev
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8
    username: root
    password: root
 
mybatis:
    type-aliases-package: org.larry.springboot.entity
    mapper-locations: classpath:mapper/**/*.xml
    check-config-location: true
 
active: 【test、dev、prod】,根據 active 的環境,自動採用上面配置的springProfile的 logger 日誌

自定義日誌路徑(application.xml)

application.xml 增加日誌相關自定義配置

logback:
  logdir: /Users/inke/dev/log/tomcat/sell
  appname: sell

在logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
 
    <!--application.yml 傳遞參數,不能使用logback 自帶的<property>標籤 -->
    <springProperty scope="context" name="appname" source="logback.appname"/>
    <springProperty scope="context" name="logdir" source="logback.logdir"/>
 
    <contextName>${appname}</contextName>
 
    <!--輸出到控制檯 ConsoleAppender-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <!--展示格式 layout-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
            </pattern>
        </layout>
    </appender>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章