1、介紹html
Logback,一個「可靠、通用、快速而又靈活的Java日誌框架」數據庫
分爲如下幾個模塊:api
logback-classic:log4j的一個改良版本,同時它完整提供了slf4j API是咱們能夠很方便地更換成其餘日誌系統如log4j安全
logback-access:訪問模塊與Servlet容器集成提供經過HTTP來訪問日誌的功能服務器
logback-core:其餘兩個模塊的基礎模塊app
2、取代log4j的理由框架
一、更快的實現:重寫了內核,在一些關鍵執行路徑上性能提高了10倍以上,並且logback不只性能提高了,初始化內存加載也更小了dom
二、很是充分的測試異步
三、Logback-classic很是天然實現了SLF4j:Logback-classic實現了SLF4j。在使用SLF4j中,你都感受不到logback-classic。並且由於logback-classic很是天然地實現了slf4j ,socket
因此切換到log4j或者其餘,很是容易,只須要提供成另外一個jar包就OK,根本不須要去動那些經過SLF4JAPI實現的代碼。
四、很是充分的文檔,官網有兩百多頁的文檔,官網地址:https://logback.qos.ch/index.html
五、自動從新加載配置文件,當配置文件修改了,Logback-classic能自動從新加載配置文件。掃描過程快且安全,它並不須要另外建立一個掃描線程。這個技術充分保證了應用程序能跑得很歡
在JEE環境裏面。
六、Lilith是log事件的觀察者,和log4j的chainsaw相似。而lilith還能處理大數量的log數據 。
七、謹慎的模式和很是友好的恢復,在謹慎模式下,多個FileAppender實例跑在多個JVM下,能 夠安全地寫道同一個日誌文件。RollingFileAppender會有些限制。Logback的FileAppender和它
的子類包括 RollingFileAppender可以很是友好地從I/O異常中恢復。
八、配置文件能夠處理不一樣的狀況,開發人員常常須要判斷不一樣的Logback配置文件在不一樣的環境下(開發,測試,生產)。而這些配置文件僅僅只有一些很小的不一樣,能夠經過,和來實現,這
樣一個配置文件就能夠適應多個環境。
九、Filters(過濾器)有些時候,須要診斷一個問題,須要打出日誌。在log4j,只有下降日誌級別,不過這樣會打出大量的日誌,會影響應用性能。在Logback,你能夠繼續 保持那個日誌級別
而除掉某種特殊狀況,如alice這個用戶登陸,她的日誌將打在DEBUG級別而其餘用戶能夠繼續打在WARN級別。要實現這個功能只需加4行XML配置。能夠參考MDCFIlter 。
十、SiftingAppender(一個很是多功能的Appender):它能夠用來分割日誌文件根據任何一個給定的運行參數。如,SiftingAppender可以區別日誌事件跟進用戶的Session,而後每一個用戶會
有一個日誌文件。
十一、自動壓縮已經打出來的log:RollingFileAppender在產生新文件的時候,會自動壓縮已經打出來的日誌文件。壓縮是個異步過程,因此甚至對於大的日誌文件,在壓縮過程當中應用不會受任
何影響。
十二、堆棧樹帶有包版本:Logback在打出堆棧樹日誌時,會帶上包的數據。
1三、自動去除舊的日誌文件:經過設置TimeBasedRollingPolicy或者SizeAndTimeBasedFNATP的maxHistory屬性,你能夠控制已經產生日誌文件的最大數量。若是設置maxHistory 12,那那些
log文件超過12個月的都會被自動移除。
3、Logback的結構
Logback創建在三個類之上:Logger,Appender和Layouts。這三個類型的組件一塊兒工做使開發人員可以根據消息類型和級別記錄消息,並在運行時控制如何格式化這些消息以及在何處打印這些消息。
Logger context:指定了日誌輸出的上下文
Appender(附加目的地):Logback容許將日誌輸出到多個目的地,一個輸出目的地對應一個Appender。目前Appeners有,console、file、remote socket servers、to MySQL、PostgreSQL 還有其餘的數據庫、JMS、remote UNIX Syslog daemons。
一個Logger能夠輸出到一個或多個appender。
默認狀況下,日誌輸出Appender會繼承,如全部的Logger都會輸出到root指定的Appender,子包會輸出到其父包的Appender。因此想要避免重複輸出,須要指定additivity屬性爲false。
若是想根據日誌級別篩選appender,那就使用filter,經常使用的filter有隻輸出某個級別的和輸出定義級別及以上級別的過濾器:
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level>// 只輸出INFO級別的日誌 <onMatch>ACCEPT</onMatch> // 匹配就接受 <onMismatch>DENY</onMismatch> // 不匹配就拒絕 </filter>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> // 接受全部INFO及以上級別的日誌,WARN、ERROR </filter>
最後:實踐
pom配置:
slf4j:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.28</version> </dependency>
<!--logback--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.11</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.11</version> </dependency>
在工程src目錄下創建logback.xml
注:
1.logback首先會試着查找logback.groovy文件;
2.當沒有找到時,繼續試着查找logback-test.xml文件;
3.當沒有找到時,繼續試着查找logback.xml文件;
4.若是仍然沒有找到,則使用默認配置(打印到控制檯)。
logback.xml配置介紹
appender:主要用於指定日誌的輸出目的地,目的地能夠是控制檯、文件、遠程套接字服務器、MySQL等
logger:用來設置某一個包或具體的某一個類的日誌打印級別,以及指定<appender>,<logger>僅有一個name屬性,一個可選的level和一個可選的addtivity屬性,能夠包含零個或
多個<appender-ref>元素,標識這個appender將會添加這個logger
root:也是logger元素,是全部logger的上級,只有一個level屬性
pattern:
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}|%thread|%-5level|%X{threadId}|%r|%C|%msg%n</pattern>
%表示日期
| 表示分隔符,能夠本身指定其餘分隔符
%t/thread表示線程名
%-5level:表示顯示日誌的級別,從左顯示5個字符寬度
%X{threadId}:threadId是本身定義的線程號,在代碼中使用MDC.put()開始,MDC.remove()結束
MDC.put("threadId", UUID.randomUUID().toString().replaceAll("-", ""));
...
MDC.remove("threadId");
%r/relative:輸出應用程序啓動到建立日誌事件所花費的毫秒數
%C/class:表示輸出日誌所在類的全路徑
%msg/m/message:表示日誌信息
%n:換行符
%L/line:輸出發起日誌請求所在的行號
%M/method:輸出發起日誌請求的方法名
一個簡單的配置:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定義日誌文件的存儲地址 勿在 LogBack 的配置中使用相對路徑-->
<property name="LOG_HOME" value="/logback/LogFile"/>
<!--控制檯輸出-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}|%thread|%-5level|%r|%X{threadId}|%C|%msg%n</pattern>
</encoder>
</appender>
<!--<logger name=""-->
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
項目中稍複雜的配置
<?xml version="1.0" encoding="UTF-8"?> <!--默認每隔一分鐘掃描此配置文件的修改並從新加載--> <configuration> <!--定義日誌文件的存儲地址 勿在LogBack的配置中使用相對路徑--> <property name="LOG_HOME" value="xxx/logs"/> <!--控制檯輸出--> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}|%t|%highlight(%-5level)|%green(%X{threadId})|%cyan(%C{0}#%M:%L)|%msg%n</pattern> </encoder> </appender> <!--輸出日誌到文件中--> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/info.log</file> <!--不輸出ERROR級別的日誌--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <!--根據日期滾動輸出日誌策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/info.log.%d{yyyy-MM-dd}</fileNamePattern> <!--日誌保留天數--> <maxHistory>360</maxHistory> </rollingPolicy> <encoder> <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}|%t|%-5level|%X{threadId}|%C{0}#%M:%L|%msg%n</pattern> </encoder> </appender> <!--錯誤日誌輸出文件--> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/error.log</file> <!--只輸出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_HOME}/error.log.%d{yyyy-MM-dd}</fileNamePattern> <!--日誌保留天數--> <maxHistory>360</maxHistory> </rollingPolicy> <encoder> <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}|%t|%-5level|%X{threadId}|%C{0}#%M:%L|%msg%n</pattern> </encoder> </appender> <!--異步打印日誌,任務放在阻塞隊列中,若是隊列達到80%,將會丟棄TRACE,DEBUG,INFO級別的日誌任務,對性能要求不是過高的話不用啓用--> <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1000</queueSize> <!--設爲0表示隊列達到80%,也不丟棄任務--> <discardingThreshold>0</discardingThreshold> <!--日誌上下文關閉後,AsyncAppender繼續執行寫任務的時間,單位毫秒--> <maxFlushTime>1000</maxFlushTime> <!--隊列滿了直接丟棄要寫的消息--> <neverBlock>true</neverBlock> <!--是否包含調用方的信息,false則沒法打印類名方法名行號等--> <includeCallerData>true</includeCallerData> <!--One and only one appender may be attached to AsyncAppender,添加多個的話後面的會被忽略--> <appender-ref ref="FILE"/> </appender> <appender name="ERROR_ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>256</queueSize> <!--設爲0表示隊列達到80%,也不丟棄任務--> <discardingThreshold>0</discardingThreshold> <!--日誌上下文關閉後,AsyncAppender繼續執行寫任務的時間,單位毫秒--> <maxFlushTime>1000</maxFlushTime> <!--隊列滿了直接丟棄要寫的消息,不阻塞寫入隊列--> <neverBlock>true</neverBlock> <!--是否包含調用方的信息,false則沒法打印類名方法名行號等--> <includeCallerData>true</includeCallerData> <!--One and only one appender may be attached to AsyncAppender,添加多個的話後面的會被忽略--> <appender-ref ref="ERROR_FILE"/> </appender> <!--指定一些依賴包的日誌輸出級別,全部的logger會繼承root,爲了不日誌重複打印,需指定additivity="false",將不會繼承root的append-ref--> <!-- <logger name="com.xxx" level="ERROR" additivity="false"> <appender-ref ref="STDOUT"/> <!–<appender-ref ref="ERROR_FILE"/>–> </logger>--> <root level="INFO"> <!--<appender-ref ref="STDOUT"/>--> <appender-ref ref="FILE"/> <appender-ref ref="ERROR_FILE"/> <!--使用異步打印日誌--> <!--<appender-ref ref="ASYNC"/>--> <!--<appender-ref ref="ERROR_ASYNC"/>--> </root> </configuration>