Log4j,Log4j2,logback,slf4j日志框架比較

主要參考:https://blog.csdn.net/zwj1030711290/article/details/81010320

Log4j

是Apache的一個(gè)開放源代碼項(xiàng)目,通過使用Log4j,我們可以控制日志信息輸送的目的地是控制臺(tái)、文件、數(shù)據(jù)庫等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志信息的級(jí)別,我們能夠更加細(xì)致地控制日志的生成過程。
Log4j有7種不同的log級(jí)別,按照等級(jí)從低到高依次為:TRACE、DEBUG、INFO、WARN、ERROR、FATAL、OFF。如果配置為OFF級(jí)別,表示關(guān)閉log。
Log4j支持兩種格式的配置文件:properties和xml。包含三個(gè)主要的組件:Logger、appender、Layout。
①Logger:日志記錄器,負(fù)責(zé)收集處理日志記錄,可以有選擇的啟動(dòng)和禁用日志的輸出。
②Appender:日志輸出目的地,負(fù)責(zé)日志的輸出,一個(gè)輸出源就叫一個(gè)Appender,appender的類別有:Console(控制臺(tái))File(文件)JDBC、JMS等,logger可以通過方法logger.addAppender(appender);配置多個(gè)appender,對(duì)logger來說,每個(gè)有效的日志請(qǐng)求結(jié)果都將輸出到logger本身以及父logger的appender上。
③Layout:日志格式化,負(fù)責(zé)對(duì)輸出的日志格式化。
一個(gè)logger可以對(duì)應(yīng)多個(gè)appender,一個(gè)appender只能對(duì)應(yīng)一個(gè)layout。
org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以靈活地指定布局模式)
org.apache.log4j.SimpleLayout(包含日志信息的級(jí)別和信息字符串)
org.apache.log4j.TTCCLayout(包含日志產(chǎn)生的時(shí)間、線程、類別等等信息)
控制臺(tái)輸出:
通過如下配置,設(shè)定root日志的輸出級(jí)別為INFO,appender為控制臺(tái)輸出stdout

# LOG4J配置
log4j.rootLogger=INFO,stdout
# 控制臺(tái)輸出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n

輸出到文件:
在開發(fā)環(huán)境,我們只是輸出到控制臺(tái)沒有問題,但是到了生產(chǎn)或測試環(huán)境,或許持久化日志內(nèi)容,方便追溯問題原因??梢酝ㄟ^添加如下的appender內(nèi)容,按天輸出到不同的文件中去,同時(shí)還需要為log4j.rootLogger添加名為file的appender,這樣root日志就可以輸出到logs/springboot.log文件中了。輸出到文件和輸出到控制臺(tái)是可以并行存在的。

# LOG4J配置
log4j.rootLogger=INFO,stdout,file
# 日志輸出到文件
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.file.file=logs/springboot.log 
log4j.appender.file.DatePattern='.'yyyy-MM-dd 
log4j.appender.file.layout=org.apache.log4j.PatternLayout 
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n 

分類輸出:
當(dāng)我們?nèi)罩玖枯^多的時(shí)候,查找問題會(huì)非常困難,常用的手段就是對(duì)日志進(jìn)行分類,比如:
可以按不同package進(jìn)行輸出。通過定義輸出到logs/my.log的appender,并對(duì)com.test包下的日志級(jí)別設(shè)定為DEBUG級(jí)別、appender設(shè)置為輸出到logs/my.log的名為testlog的appender。

# com.test包下的日志配置
log4j.logger.com.test=DEBUG, testlog
# com.test下的日志輸出
log4j.appender.testlog=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.testlog.file=logs/my.log 
log4j.appender.testlog.DatePattern='.'yyyy-MM-dd 
log4j.appender.testlog.layout=org.apache.log4j.PatternLayout 
log4j.appender.testlog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n

可以對(duì)不同級(jí)別進(jìn)行分類,比如對(duì)ERROR級(jí)別輸出到特定的日志文件中,具體配置可以如下:

# LOG4J配置
log4j.rootCategory=INFO, stdout,errorfile
log4j.logger.error=errorfile
 
# error日志輸出
log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.errorfile.file=logs/error.log
log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd
log4j.appender.errorfile.Threshold = ERROR
log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout
log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n %5p %c{1}:%L - %m%n

輸出到數(shù)據(jù)庫
將日志文件輸出到數(shù)據(jù)庫配置:

# LOG4J配置
log4j.rootCategory=INFO,stdout,jdbc
# 數(shù)據(jù)庫輸出
log4j.appender.jdbc=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.jdbc.driver=com.mysql.jdbc.Driver
log4j.appender.jdbc.URL=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=true
log4j.appender.jdbc.user=root
log4j.appender.jdbc.password=root
log4j.appender.jdbc.sql=insert into log_icecoldmonitor(level,category,thread,time,location,note) values('%p','%c','%t','%d{yyyy-MM-dd HH:mm:ss:SSS}','%l','%m')

引入收據(jù)庫驅(qū)動(dòng):

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

創(chuàng)建表:

CREATE TABLE `log_icecoldmonitor` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `level` varchar(255) NOT NULL DEFAULT '' COMMENT '優(yōu)先級(jí)',
  `category` varchar(255) NOT NULL DEFAULT '' COMMENT '類目',
  `thread` varchar(255) NOT NULL DEFAULT '' COMMENT '進(jìn)程',
  `time` varchar(30) NOT NULL DEFAULT '' COMMENT '時(shí)間',
  `location` varchar(255) NOT NULL DEFAULT '' COMMENT '位置',
  `note` text COMMENT '日志信息',
  PRIMARY KEY (`Id`)
)

這樣就可以保存到日志到數(shù)據(jù)庫了,可能會(huì)出現(xiàn)如下異常信息:
Java連接Mysql數(shù)據(jù)庫警告:Establishing SSL connection
原因是MySQL在高版本需要指明是否進(jìn)行SSL連接。解決方案如下:
在mysql連接字符串url中加入ssl=true或者false即可,如下所示。
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=true

Log4j2

Spring Boot1.4以及之后的版本已經(jīng)不支持log4j,log4j也很久沒有更新了,現(xiàn)在已經(jīng)有很多其他的日志框架對(duì)Log4j進(jìn)行了改良,比如說SLF4J、Logback等。而且Log4j 2在各個(gè)方面都與Logback非常相似,那么為什么我們還需要Log4j 2呢?
  1. 插件式結(jié)構(gòu)。Log4j 2支持插件式結(jié)構(gòu)。我們可以根據(jù)自己的需要自行擴(kuò)展Log4j 2. 我們可以實(shí)現(xiàn)自己的appender、logger、filter。
  2. 配置文件優(yōu)化。在配置文件中可以引用屬性,還可以直接替代或傳遞到組件。而且支持json格式的配置文件。不像其他的日志框架,它在重新配置的時(shí)候不會(huì)丟失之前的日志文件。
  3. Java 5的并發(fā)性。Log4j 2利用Java 5中的并發(fā)特性支持,盡可能地執(zhí)行最低層次的加鎖。解決了在log4j 1.x中存留的死鎖的問題。
  4. 異步logger。Log4j 2是基于LMAX Disruptor庫的。在多線程的場景下,和已有的日志框架相比,異步的logger擁有10倍左右的效率提升。

官方建議一般程序員查看的日志改成異步方式,一些運(yùn)營日志改成同步。日志異步輸出的好處在于,使用單獨(dú)的進(jìn)程來執(zhí)行日志打印的功能,可以提高日志執(zhí)行效率,減少日志功能對(duì)正常業(yè)務(wù)的影響。異步日志在程序的classpath需要加載disruptor-3.0.0.jar或者更高的版本。

<!-- log4j2異步日志需要加載disruptor-3.0.0.jar或者更高的版本 -->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.6</version>
        </dependency>

異步日志分為兩種:
a.全異步模式
這種異步日志方式,不需要修改修改原理的配置文件,Logger仍然使用<root> and <logger>
只需要在主程序代碼開頭,加一句系統(tǒng)屬性的代碼:

System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");  

b.異步和非異步混合輸出模式
在配置文件中Logger使用<asyncRoot> or <asyncLogger>

<loggers>  
     <AsyncLogger name="AsyncLogger" level="trace" includeLocation="true">  
        <appender-ref ref="Console" />  
        <appender-ref ref="debugLog" />  
        <appender-ref ref="errorLog" />  
    </AsyncLogger>  
 
    <asyncRoot level="trace" includeLocation="true">  
        <appender-ref ref="Console" />  
    </asyncRoot>   
</loggers> 

log4j2.xml配置 有一點(diǎn)需要注意的是,假如想要在application.properties中指定日志文件存放路徑或日志文件名,在log4j2.xml中使用{LOG_PATH}或者{LOG_FILE}來引用,是無法獲取到的(在logback中可以盡情使用)。log4j2支持xml、json、yaml等格式的配置文件。

SLF4J

SLF4J,即簡單日志門面(Simple Logging Facade for Java),不是具體的日志解決方案,而是通過Facade Pattern提供一些Java logging API,它只服務(wù)于各種各樣的日志系統(tǒng)。按照官方的說法,SLF4J是一個(gè)用于日志系統(tǒng)的簡單Facade,允許最終用戶在部署其應(yīng)用時(shí)使用其所希望的日志系統(tǒng)。作者創(chuàng)建SLF4J的目的是為了替代Jakarta Commons-Logging。

實(shí)際上,SLF4J所提供的核心API是一些接口以及一個(gè)LoggerFactory的工廠類。在使用SLF4J的時(shí)候,不需要在代碼中或配置文件中指定你打算使用那個(gè)具體的日志系統(tǒng)。類似于Apache Common-Logging,SLF4J是對(duì)不同日志框架提供的一個(gè)門面封裝,可以在部署的時(shí)候不修改任何配置即可接入一種日志實(shí)現(xiàn)方案。但是,他在編譯時(shí)靜態(tài)綁定真正的Log庫。使用SLF4J時(shí),如果你需要使用某一種日志實(shí)現(xiàn),那么你必須選擇正確的SLF4J的jar包的集合(各種橋接包)。SLF4J提供了統(tǒng)一的記錄日志的接口,只要按照其提供的方法記錄即可,最終日志的格式、記錄級(jí)別、輸出方式等通過具體日志系統(tǒng)的配置來實(shí)現(xiàn),因此可以在應(yīng)用中靈活切換日志系統(tǒng)。

那么什么時(shí)候使用SLF4J比較合適呢?
如果你開發(fā)的是類庫或者嵌入式組件,那么就應(yīng)該考慮采用SLF4J,因?yàn)椴豢赡苡绊懽罱K用戶選擇哪種日志系統(tǒng)。在另一方面,如果是一個(gè)簡單或者獨(dú)立的應(yīng)用,確定只有一種日志系統(tǒng),那么就沒有使用SLF4J的必要。假設(shè)你打算將你使用log4j的產(chǎn)品賣給要求使用JDK 1.8 Logging的用戶時(shí),面對(duì)成千上萬的log4j調(diào)用的修改,相信這絕對(duì)不是一件輕松的事情。但是如果開始便使用SLF4J,那么這種轉(zhuǎn)換將是非常輕松的事情。

Logback

Logback,一個(gè)“可靠、通用、快速而又靈活的Java日志框架”。logback當(dāng)前分成三個(gè)模塊:logback-core,logback- classic和logback-access。logback-core是其它兩個(gè)模塊的基礎(chǔ)模塊。logback-classic是log4j的一個(gè)改良版本。此外logback-classic完整實(shí)現(xiàn)SLF4J API使你可以很方便地更換成其它日志系統(tǒng)如log4j或JDK Logging。logback-access訪問模塊與Servlet容器集成提供通過Http來訪問日志的功能。

  1. logback-core: Joran, Status, context, pattern parsing
  2. logback-classic: developer logging
  3. logback-access: The log generated when a user accesses a web-page on a web server. Integrates seamlessly with Jetty and Tomcat.

選擇logback的理由:

  1. logback比log4j要快大約10倍,而且消耗更少的內(nèi)存。
  2. logback-classic模塊直接實(shí)現(xiàn)了SLF4J的接口,所以我們遷移到logback幾乎是零開銷的。
  3. logback不僅支持xml格式的配置文件,還支持groovy格式的配置文件。相比之下,Groovy風(fēng)格的配置文件更加直觀,簡潔。
  4. logback-classic能夠檢測到配置文件的更新,并且自動(dòng)重新加載配置文件。
  5. logback能夠優(yōu)雅的從I/O異常中恢復(fù),從而我們不用重新啟動(dòng)應(yīng)用程序來恢復(fù)logger。
  6. logback能夠根據(jù)配置文件中設(shè)置的上限值,自動(dòng)刪除舊的日志文件。
  7. logback能夠自動(dòng)壓縮日志文件。
  8. logback能夠在配置文件中加入條件判斷(if-then-else)??梢员苊獠煌拈_發(fā)環(huán)境(dev、test、uat…)的配置文件的重復(fù)。
  9. logback帶來更多的filter。
  10. logback的stack trace中會(huì)包含詳細(xì)的包信息。
  11. logback-access和Jetty、Tomcat集成提供了功能強(qiáng)大的HTTP-access日志。
    配置文件:需要在項(xiàng)目的src目錄下建立一個(gè)logback.xml。
    注:(1)logback首先會(huì)試著查找logback.groovy文件;
    (2)當(dāng)沒有找到時(shí),繼續(xù)試著查找logback-test.xml文件;
    (3)當(dāng)沒有找到時(shí),繼續(xù)試著查找logback.xml文件;
    (4)如果仍然沒有找到,則使用默認(rèn)配置(打印到控制臺(tái))。

總結(jié)


接口:將所有日志實(shí)現(xiàn)適配到了一起,用統(tǒng)一的接口調(diào)用。
實(shí)現(xiàn):目前主流的日志實(shí)現(xiàn)。
舊日志到slf4j的適配器:如果使用了slf4j,但是只想用一種實(shí)現(xiàn),想把log4j的日志體系也從logback輸出,這個(gè)是很有用的。
slf4j到實(shí)現(xiàn)的適配器:如果想制定slf4j的具體實(shí)現(xiàn),需要這些包。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在應(yīng)用程序中添加日志記錄總的來說基于三個(gè)目的:監(jiān)視代碼中變量的變化情況,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 5,148評(píng)論 0 6
  • 作為Java開發(fā)人員,對(duì)于日志記錄框架一定非常熟悉。而且?guī)缀踉谒袘?yīng)用里面,一定會(huì)用到各種各樣的日志框架用來記錄程...
    意識(shí)流丶閱讀 14,457評(píng)論 0 13
  • 在應(yīng)用程序中添加日志記錄總的來說基于三個(gè)目的:監(jiān)視代碼中變量的變化情況,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 5,204評(píng)論 1 13
  • 在項(xiàng)目開發(fā)過程中,我們可以通過 debug 查找問題。而在線上環(huán)境我們查找問題只能通過打印日志的方式查找問題。因此...
    Java架構(gòu)閱讀 3,572評(píng)論 2 41
  • 前言 今天來介紹下Spring Boot如何配置日志logback,我剛學(xué)習(xí)的時(shí)候,是帶著下面幾個(gè)問題來查資料的 ...
    OzanShareing閱讀 1,101評(píng)論 0 2

友情鏈接更多精彩內(nèi)容