SpringBoot集成slf4j2日志配置的實(shí)現(xiàn)示例
簡(jiǎn)介
本章節(jié)主要介紹springboot項(xiàng)目集成slf4j2,看完本章內(nèi)容可以輕松完成集成。另外說(shuō)一下,在對(duì)日志輸出場(chǎng)景比較多的情況下可以考慮將logback更換為log4j2。
1、pom引入依賴
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> <version>3.1.0</version> </dependency>
2、剔除依賴
在springboot 中默認(rèn)的日志管理就是logback,需要剔除原來(lái)的日志包引用,凡是相關(guān)的springboot都需要exclusion日志包,下面舉例說(shuō)明
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.7.13</version> <exclusions><!-- 去掉springboot默認(rèn)配置 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.13</version> <exclusions><!-- 去掉springboot默認(rèn)配置 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
3、創(chuàng)建log4j2.xml配置文件
在resource目錄下創(chuàng)建log4j2.xml文件,log4j2.xml配置詳情如下:
3.1、配置文件內(nèi)容
<?xml version="1.0" encoding="UTF-8"?> <!--Configuration后面的status,這個(gè)用于設(shè)置log4j2自身內(nèi)部的信息輸出,可以不設(shè)置,當(dāng)設(shè)置成trace時(shí),你會(huì)看到log4j2內(nèi)部各種詳細(xì)輸出--> <!--monitorInterval:Log4j能夠自動(dòng)檢測(cè)修改配置 文件和重新配置本身,設(shè)置間隔秒數(shù)--> <configuration > <!--日志級(jí)別以及優(yōu)先級(jí)排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--變量配置--> <Properties> <!-- 格式化輸出:%date表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度 %msg:日志消息,%n是換行符--> <!-- %logger{36} 表示 Logger 名字最長(zhǎng)36個(gè)字符 --> <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" /> <!-- 定義日志存儲(chǔ)的路徑 --> <property name="FILE_PATH" value="E:/logss" /> <property name="FILE_NAME" value="share" /> </Properties> <appenders> <console name="Console" target="SYSTEM_OUT"> <!--輸出日志的格式--> <PatternLayout pattern="${LOG_PATTERN}"/> <!--控制臺(tái)只輸出level及其以上級(jí)別的信息(onMatch),其他的直接拒絕(onMismatch)--> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> </console> <!--文件會(huì)打印出所有信息,這個(gè)log每次運(yùn)行程序會(huì)自動(dòng)清空,由append屬性決定,適合臨時(shí)測(cè)試用--> <File name="Filelog" fileName="${FILE_PATH}/test.log" append="false"> <PatternLayout pattern="${LOG_PATTERN}"/> </File> <!-- 這個(gè)會(huì)打印出所有的info及以下級(jí)別的信息,每次大小超過(guò)size,則這size大小的日志會(huì)自動(dòng)存入按年份-月份建立的文件夾下面并進(jìn)行壓縮,作為存檔--> <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz"> <!--控制臺(tái)只輸出level及以上級(jí)別的信息(onMatch),其他的直接拒絕(onMismatch)--> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <!--interval屬性用來(lái)指定多久滾動(dòng)一次,默認(rèn)是1 hour--> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <!-- DefaultRolloverStrategy屬性如不設(shè)置,則默認(rèn)為最多同一文件夾下7個(gè)文件開(kāi)始覆蓋--> <DefaultRolloverStrategy max="15"/> </RollingFile> <!-- 這個(gè)會(huì)打印出所有的warn及以下級(jí)別的信息,每次大小超過(guò)size,則這size大小的日志會(huì)自動(dòng)存入按年份-月份建立的文件夾下面并進(jìn)行壓縮,作為存檔--> <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz"> <!--控制臺(tái)只輸出level及以上級(jí)別的信息(onMatch),其他的直接拒絕(onMismatch)--> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <!--interval屬性用來(lái)指定多久滾動(dòng)一次,默認(rèn)是1 hour--> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <!-- DefaultRolloverStrategy屬性如不設(shè)置,則默認(rèn)為最多同一文件夾下7個(gè)文件開(kāi)始覆蓋--> <DefaultRolloverStrategy max="15"/> </RollingFile> <!-- 這個(gè)會(huì)打印出所有的error及以下級(jí)別的信息,每次大小超過(guò)size,則這size大小的日志會(huì)自動(dòng)存入按年份-月份建立的文件夾下面并進(jìn)行壓縮,作為存檔--> <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz"> <!--控制臺(tái)只輸出level及以上級(jí)別的信息(onMatch),其他的直接拒絕(onMismatch)--> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <!--interval屬性用來(lái)指定多久滾動(dòng)一次,默認(rèn)是1 hour--> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <!-- DefaultRolloverStrategy屬性如不設(shè)置,則默認(rèn)為最多同一文件夾下7個(gè)文件開(kāi)始覆蓋--> <DefaultRolloverStrategy max="15"/> </RollingFile> </appenders> <!--Logger節(jié)點(diǎn)用來(lái)單獨(dú)指定日志的形式,比如要為指定包下的class指定不同的日志級(jí)別等。--> <!--然后定義loggers,只有定義了logger并引入的appender,appender才會(huì)生效--> <loggers> <!--過(guò)濾掉spring和mybatis的一些無(wú)用的DEBUG信息--> <logger name="org.mybatis" level="info" additivity="false"> <AppenderRef ref="Console"/> </logger> <!--監(jiān)控系統(tǒng)信息--> <!--若是additivity設(shè)為false,則 子Logger 只會(huì)在自己的appender里輸出,而不會(huì)在 父Logger 的appender里輸出。--> <Logger name="org.springframework" level="info" additivity="false"> <AppenderRef ref="Console"/> </Logger> <root level="info"> <appender-ref ref="Console"/> <appender-ref ref="Filelog"/> <appender-ref ref="RollingFileInfo"/> <appender-ref ref="RollingFileWarn"/> <appender-ref ref="RollingFileError"/> </root> </loggers> </configuration>
3.2、配置參數(shù)詳解
日志等級(jí)說(shuō)明
等級(jí) | 說(shuō)明 |
---|---|
trace | 追蹤,就是程序推進(jìn)一下,可以寫個(gè)trace輸出 |
debug | 調(diào)試,一般作為最低級(jí)別,trace基本不用 |
info | 輸出重要的信息,使用較多 |
warn | 警告,有些信息不是錯(cuò)誤信息,但也要給程序員一些提示。 |
error | 錯(cuò)誤信息。用的也很多 |
fatal | 致命錯(cuò)誤 |
輸出源
類別 | 說(shuō)明 |
---|---|
CONSOLE | 輸出到控制臺(tái) |
FILE | 輸出到文件 |
格式
類別 | 說(shuō)明 |
---|---|
SimpleLayout | 以簡(jiǎn)單的形式顯示 |
HTMLLayout | 以HTML表格顯示 |
PatternLayout | 自定義形式顯示 |
PatternLayout自定義日志布局:
格式 | 說(shuō)明 |
---|---|
%d{HH:mm:ss.SSS} | 表示輸出到毫秒的時(shí)間 |
%t | 輸出當(dāng)前線程名稱 |
%-5level | 輸出日志級(jí)別,-5表示左對(duì)齊并且固定輸出5個(gè)字符,如果不足在右邊補(bǔ)0 |
%logger | 輸出logger名稱 |
%msg | 日志文本 |
%n | 換行 |
%F | 輸出所在的類文件名,如Test.java |
%L | 輸出行號(hào) |
%M | 輸出所在方法名 |
%l | 輸出語(yǔ)句所在的行數(shù), 包括類名、方法名、文件名、行數(shù) |
4、application.yml文件配置
需要指定加在的配置文件,因?yàn)槟J(rèn)加載的文件名為log4j2-spring.xml
logging: config: classpath:log4j2.xml level: root: trace
5、測(cè)試
寫一段測(cè)試代碼打印日志,啟動(dòng)項(xiàng)目進(jìn)行測(cè)試即可
@Slf4j public class Test { @GetMapping(value = "/testFeign", produces = MediaType.APPLICATION_JSON_VALUE) public Result<Boolean> testFeign() { log.info("測(cè)試feign調(diào)用------biz"); return Result.success(true); } }
6、附錄
6.1、集成異常一
如果啟動(dòng)的時(shí)候出現(xiàn)如下錯(cuò)誤,則需要
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”.
SLF4J: Defaulting to no-operation (NOP) logger implementation
解決方法:引入如下依賴即可
<!--slf4j-nop 日志開(kāi)關(guān),一旦引入依賴,所有日志實(shí)現(xiàn)框架將失效--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.7.36</version> </dependency>
6.2、 log4j2特性
(1)數(shù)據(jù)丟失少,可以用來(lái)做審計(jì)功能。自身內(nèi)部報(bào)的exception會(huì)被發(fā)現(xiàn),但是logback和log4j不會(huì);
(2)log4j2使用了disruptor技術(shù),在多線程環(huán)境下,性能高于logback等10倍以上;
(3)(garbage free)之前的版本會(huì)產(chǎn)生非常多的臨時(shí)對(duì)象,會(huì)造成GC頻繁,log4j2則在這方面上做了優(yōu)化,減少產(chǎn)生臨時(shí)對(duì)象。盡可能少的GC,其實(shí)也是基于disruptor技術(shù);
(4)支持lambda表達(dá)式;
(5)對(duì)filter的功能支持的更強(qiáng)大;
(6)系統(tǒng)日志(Syslog)協(xié)議支持TCP 和 UDP
(7)支持kafka queue
6.3、 log4j2異步日志的四種隊(duì)列
列出了log4j2異步日志的四種隊(duì)列,有興趣可以深入了解
ArrayBlockingQueue -- 默認(rèn)的隊(duì)列,通過(guò) java 原生的 ArrayBlockingQueue 實(shí)現(xiàn)。 LinkedTransferQueue -- 通過(guò) java7 以上原生支持的 LinkedTransferQueue 實(shí)現(xiàn)。 DisruptorBlockingQueue -- disruptor 包實(shí)現(xiàn)的高性能隊(duì)列。 JCToolsBlockingQueue -- JCTools 實(shí)現(xiàn)的無(wú)鎖隊(duì)列。
6.4 、log4j2使用了disruptor技術(shù)
Disruptor有三大殺器 CAS、消除偽共享、RingBuffer
Disruptor通過(guò)以下設(shè)計(jì)來(lái)解決隊(duì)列速度慢的問(wèn)題:
環(huán)形數(shù)組結(jié)構(gòu)
為了避免垃圾回收, 采用數(shù)組而非鏈表. 同時(shí), 數(shù)組對(duì)處理器的緩存機(jī)制更加友好。
類似的實(shí)現(xiàn)思想還有其他應(yīng)用:
disruptor | mysql | linux 內(nèi)核 |
---|---|---|
RingBuffer 環(huán)形隊(duì)列實(shí)現(xiàn) | redolog通過(guò)一個(gè)環(huán)形的存儲(chǔ)區(qū)域?qū)崿F(xiàn)其循環(huán)寫入 | 進(jìn)程間通信所使用的 fifo 通過(guò)環(huán)形存儲(chǔ)區(qū)域 |
元素位置定位
數(shù)組長(zhǎng)度2^n, 通過(guò)位運(yùn)算, 加快定位的速度. 下標(biāo)采取遞增的形式. 不用擔(dān)心index溢出的問(wèn)題. index是long類型, 即使100萬(wàn)QPS的處理速度, 也需要30萬(wàn)年才能用完。
無(wú)鎖設(shè)計(jì)
每個(gè)生產(chǎn)者或者消費(fèi)者線程, 會(huì)先申請(qǐng)可以操作的元素在數(shù)組中的位置, 申請(qǐng)到之后, 直接在該位置寫入或者讀取數(shù)據(jù)。
到此這篇關(guān)于SpringBoot集成slf4j2日志配置的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)SpringBoot slf4j2日志配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java并發(fā)編程專題(十一)----(JUC原子類)數(shù)組類型詳解
這篇文章主要介紹了JAVA JUC原子類 數(shù)組類型詳解的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07java 8 lambda表達(dá)式list操作分組、過(guò)濾、求和、最值、排序、去重代碼詳解
java8的lambda表達(dá)式提供了一些方便list操作的方法,主要涵蓋分組、過(guò)濾、求和、最值、排序、去重,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01搭建Springboot框架并添加JPA和Gradle組件的方法
這篇文章主要介紹了搭建Springboot框架并添加JPA和Gradle組件的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07Java實(shí)現(xiàn)常見(jiàn)排序算法的優(yōu)化
今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著Java實(shí)現(xiàn)常見(jiàn)排序算法的優(yōu)化展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-01-01java.lang.ExceptionInInitializerError異常的解決方法
這篇文章主要為大家詳細(xì)介紹了java.lang.ExceptionInInitializerError異常的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Java中Arrays工具類的一些常見(jiàn)方法總結(jié)
在Java中Arrays類是一個(gè)實(shí)用工具類,用于在數(shù)組上執(zhí)行各種操作,包括排序、搜索、比較等,這篇文章主要給大家介紹了關(guān)于Java中Arrays工具類的一些常見(jiàn)方法,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02Map 使用 Lambda 的 forEach 實(shí)現(xiàn)跳出循環(huán)操作
這篇文章主要介紹了Map 使用 Lambda 的 forEach 實(shí)現(xiàn)跳出循環(huán)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09