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查找順序:
- 首先會試着查找logback.groovy文件
- 當沒有找到時,繼續試着查找 logback-test.xml 文件
- 當沒有找到時,繼續試着查找 logback.xml 文件
- 如果仍然沒有找到,則使用默認配置(打印到控制檯)
自定義日誌配置
根據不同的日誌系統,可以按照如下規則組織配置文件名,就可以被正確加載:
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
- 根節點 configuration 包含的屬性:
- scan:
此屬性設置爲true,配置文件如果發生改變,將會被重新加載,默認爲true - scanPeriod:
設置監測配置文件是否有修改的時間間隔,如果沒有給出事件單位,默認單位是毫秒。當scan爲true時,此屬性默認生效。默認的時間將爲1分鐘。 - debug:
此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態。默認爲false。
例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 其他配置省略-->
</configuration>
- 根節點 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
- name:
- root
也是logger元素,但是它是根logger。只有一個level屬性,因爲已經被命名爲“root”- level
用來設置打印級別,大小寫無關,默認是debug
root 可以包含多個 appender-ref 元素,標識這個appender將會添加到這個 logger
例如:
- level
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的全限定名
- 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>
- 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>
-
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個月的文件,刪除之前的舊文件。注意,刪除舊文件,那些爲了歸檔而創建的目錄也會被刪除。關於保存的時間的單位,是根據時間格式的單位。
- fileNamePattern
- 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有多個過濾器時,安卓配置順序執行。
- 常用過濾器:
- LevelFilter:級別過濾器,根據日誌級別進行過濾。如果日誌級別等於配置級別,過濾器會根據 onMatch 和 onMismatch 接收或拒絕日誌。子節點:
- level:設置過濾級別
- onMatch: 用於配置符合過濾條件的操作
- onMismatch:用於配置不符合過濾條件的操作
例如:將過濾器的日誌級別配置爲INFO,所以INFO級別的日誌交給appender處理,非INFO級別的日誌,被過濾掉。
- LevelFilter:級別過濾器,根據日誌級別進行過濾。如果日誌級別等於配置級別,過濾器會根據 onMatch 和 onMismatch 接收或拒絕日誌。子節點:
<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>
- 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>