springboot 日志實(shí)現(xiàn)過(guò)程
日志
日志框架可以分為 日志門(mén)面(Facade) 和 日志實(shí)現(xiàn)(Implementation),Spring Boot 使用了 SLF4J 作為日志門(mén)面,Logback 或 Log4j2 作為日志實(shí)現(xiàn)。
日志門(mén)面以及日志實(shí)現(xiàn)
日志門(mén)面
日志門(mén)面(Facade)
日志門(mén)面 是一個(gè)設(shè)計(jì)模式中的“門(mén)面模式(Facade Pattern)”,它提供了統(tǒng)一的接口,簡(jiǎn)化了日志記錄的使用,屏蔽了不同日志框架之間的細(xì)節(jié)。
門(mén)面本身并不實(shí)現(xiàn)日志的具體記錄功能,它只是提供了日志記錄的 API 規(guī)范,開(kāi)發(fā)者通過(guò)這些規(guī)范來(lái)記錄日志。
典型的日志門(mén)面框架是 SLF4J(Simple Logging Facade for Java),它定義了一組通用的日志接口,開(kāi)發(fā)者通過(guò)這些接口來(lái)進(jìn)行日志記錄。
日志實(shí)現(xiàn)
日志實(shí)現(xiàn) 是實(shí)際執(zhí)行日志記錄的組件,它負(fù)責(zé)處理日志的輸出、格式化、存儲(chǔ)等具體功能。
日志實(shí)現(xiàn)提供了對(duì)日志的具體管理方式,包括日志級(jí)別、輸出位置、格式、日志文件的滾動(dòng)與清理等。
常見(jiàn)的日志實(shí)現(xiàn)框架有:
Logback:Spring Boot 默認(rèn)使用的日志框架,提供了功能豐富的日志管理和配置。
Log4j2:Apache 提供的日志框架,相較于 Logback 提供了更多的性能優(yōu)化(如異步日志處理)和擴(kuò)展性。
兩者關(guān)系
門(mén)面(Facade) 是日志框架的統(tǒng)一接口,開(kāi)發(fā)者通過(guò)它來(lái)調(diào)用日志功能。
實(shí)現(xiàn)(Implementation) 是執(zhí)行日志記錄、管理和配置的具體框架,處理如何生成、存儲(chǔ)和輸出日志。
springboot中日志的配置
Spring Boot 默認(rèn)配置 中,SLF4J 是日志門(mén)面,Logback 是默認(rèn)的日志實(shí)現(xiàn)框架。你無(wú)需做任何特別的配置,只要在 Spring Boot 項(xiàng)目中添加了相關(guān)依賴(lài),Spring Boot 會(huì)自動(dòng)配置日志系統(tǒng)。
當(dāng)你在代碼中使用 SLF4J 的日志接口時(shí)(例如:Logger logger = LoggerFactory.getLogger(YourClass.class)),日志實(shí)際上會(huì)被傳遞給 Logback(或者 Log4j2)。
如何使用slf4j進(jìn)行日志記錄
通過(guò) SLF4J 提供的日志接口進(jìn)行日志記錄
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyService { private static final Logger logger = LoggerFactory.getLogger(MyService.class); public void doSomething() { logger.info("Starting the task..."); try { // 執(zhí)行任務(wù) } catch (Exception e) { logger.error("An error occurred", e); } } }
LoggerFactory.getLogger(MyService.class) 獲取了一個(gè) Logger 實(shí)例,這個(gè)實(shí)例是通過(guò) SLF4J 提供的 API 來(lái)使用的。你通過(guò)這個(gè) Logger 來(lái)記錄日志(如 info, error 等)。
但是,日志實(shí)際的記錄過(guò)程是由 Logback 或 Log4j2 執(zhí)行的,這些框架提供了具體的日志輸出方式、格式化和管理機(jī)制。
優(yōu)化 使用Lombok 依賴(lài)
再pom.xml文件添加lombok依賴(lài)
<dependency> <groupId>org.project.lombok<groupId> <artifactId>lombok<artifactId> <dependency>
再類(lèi)上添加@Slf4j注解,然后直接使用log.info(“日志”);
@Service @Slf4j public class TestServiceImpl implements TestService{ @Resource(name = "poolExecutor") private ThreadPoolTaskExecutor executor; @Override public String test() { ThreadPoolTaskExecutor taskExecutor = executor; // 獲取線(xiàn)程池信息 int activeCount = taskExecutor.getActiveCount(); int corePoolSize = taskExecutor.getCorePoolSize(); int poolSize = taskExecutor.getPoolSize(); taskExecutor.execute(()->{ System.out.printf(activeCount+"--"+corePoolSize); }); log.info("日志"); return null; } }
如何控制日志輸出
控制日志輸出就需要日志實(shí)現(xiàn)了logback或者log4j2
這里使用logback舉例
Spring Boot 支持兩種日志配置方式:通過(guò) application.yml/application.properties 文件配置 和 通過(guò) logback-spring.xml 配置文件進(jìn)行詳細(xì)配置。這兩種方式各有不同的適用場(chǎng)景
application.yml
示例
logging: level: root: INFO # 根日志級(jí)別 com.example: DEBUG # 某個(gè)包的日志級(jí)別 file: name: E:\IDE\demlNewLog\myapp.log # 日志文件路徑 path: E:\IDE\demlNewLog pattern: console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n" # 控制臺(tái)輸出格式
logback-spring.xml
當(dāng)你需要更細(xì)致地控制日志行為(如日志的滾動(dòng)策略、異步日志、日志文件分割、過(guò)濾器等高級(jí)功能)時(shí),你可以使用 logback-spring.xml 配置文件。這種方式提供了非常靈活和強(qiáng)大的日志配置能力。
創(chuàng)建 logback-spring.xml 配置文件: 將 logback-spring.xml 文件放在 src/main/resources 目錄下,這樣 Spring Boot 會(huì)自動(dòng)讀取該文件。名字必須是 logback-spring.xml(springboot專(zhuān)有的)才能覆蓋logback配置
Spring Boot 自動(dòng)讀取 logback-spring.xml 配置:
如果存在 logback-spring.xml 配置文件,Spring Boot 會(huì)自動(dòng)加載它,覆蓋默認(rèn)的 Logback 配置。
logback-spring.xml 文件與普通的 logback.xml 文件的不同之處在于,logback-spring.xml 文件支持 Spring 的配置和屬性注入,例如可以使用 Spring 的 PropertySource 來(lái)動(dòng)態(tài)設(shè)置日志級(jí)別、輸出路徑等。
再resource目錄下創(chuàng)建logback-spring.xml文件
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="true"> <!-- appender是configuration的子節(jié)點(diǎn),是負(fù)責(zé)寫(xiě)日志的組件。 --> <!-- ConsoleAppender:把日志輸出到控制臺(tái) --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- 默認(rèn)情況下,每個(gè)日志事件都會(huì)立即刷新到基礎(chǔ)輸出流。 這種默認(rèn)方法更安全,因?yàn)槿绻麘?yīng)用程序在沒(méi)有正確關(guān)閉appender的情況下退出,則日志事件不會(huì)丟失。但是,為了顯著增加日志記錄吞吐量,可以將immediateFlush屬性設(shè)置為false --> <!--<immediateFlush>true</immediateFlush>--> <encoder> <!-- %37():如果字符沒(méi)有37個(gè)字符長(zhǎng)度,則左側(cè)用空格補(bǔ)齊 --> <!-- %-37():如果字符沒(méi)有37個(gè)字符長(zhǎng)度,則右側(cè)用空格補(bǔ)齊 --> <!-- %15.15():如果記錄的線(xiàn)程字符長(zhǎng)度小于15(第一個(gè))則用空格在左側(cè)補(bǔ)齊,如果字符長(zhǎng)度大于15(第二個(gè)),則從開(kāi)頭開(kāi)始截?cái)喽嘤嗟淖址?--> <!-- %-40.40():如果記錄的logger字符長(zhǎng)度小于40(第一個(gè))則用空格在右側(cè)補(bǔ)齊,如果字符長(zhǎng)度大于40(第二個(gè)),則從開(kāi)頭開(kāi)始截?cái)喽嘤嗟淖址?--> <!-- %msg:日志打印詳情 --> <!-- %n:換行符 --> <!-- %highlight():轉(zhuǎn)換說(shuō)明符以粗體紅色顯示其級(jí)別為ERROR的事件,紅色為WARN,BLUE為INFO,以及其他級(jí)別的默認(rèn)顏色。 --> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n</pattern> <!-- 控制臺(tái)也要使用UTF-8,不要使用GBK,否則會(huì)中文亂碼 --> <charset>UTF-8</charset> </encoder> </appender> <!-- info 日志文件--> <!-- RollingFileAppender:滾動(dòng)記錄文件,先將日志記錄到指定文件,當(dāng)符合某個(gè)條件時(shí),將日志記錄到其他文件 --> <!-- 以下的大概意思是: 1.先按日期存日志,日期變了,將前一天的日志文件名重命名為XXX%日期%索引,新的日志仍然是project_info.log 2.如果日期沒(méi)有發(fā)生變化,但是當(dāng)前日志的文件大小超過(guò)10MB時(shí),對(duì)當(dāng)前日志進(jìn)行分割 重命名--> <appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日志文件路徑和名稱(chēng)--> <File>E:\IDE\demlNewLog\info.log</File> <!--是否追加到文件末尾,默認(rèn)為true--> <append>true</append> <!-- 打印除了ERROR的日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <!-- 如果命中ERROR就禁止這條日志 --> <onMismatch>ACCEPT</onMismatch> <!-- 如果沒(méi)有命中就使用這條規(guī)則 --> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 日志文件的名字會(huì)根據(jù)fileNamePattern的值,每隔一段時(shí)間改變一次 --> <!-- 文件名示例:logs/project_info.2017-12-05.0.log --> <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是強(qiáng)制性的,必須存在,否則報(bào)錯(cuò) --> <fileNamePattern>logs/project_info.%d.%i.log</fileNamePattern> <!-- 每產(chǎn)生一個(gè)日志文件,該日志文件的保存期限為30天 --> <!-- 注:maxHistory的單位是根據(jù)fileNamePattern中的翻轉(zhuǎn)策略自動(dòng)推算出來(lái)的,例如上面選用了yyyy-MM-dd,則單位為天,如果上面選用了yyyy-MM,則單位為月。另外上面的單位默認(rèn)為yyyy-MM-dd--> <maxHistory>30</maxHistory> <!-- 每個(gè)日志文件到10mb的時(shí)候開(kāi)始切分,最多保留30天,但最大到20GB,哪怕沒(méi)到30天也要?jiǎng)h除多余的日志 --> <totalSizeCap>20GB</totalSizeCap> <!-- maxFileSize:這是活動(dòng)文件的大小,默認(rèn)值是10MB,測(cè)試時(shí)可改成5KB看效果 --> <maxFileSize>10MB</maxFileSize> </rollingPolicy> <!--編碼器--> <encoder> <!-- pattern節(jié)點(diǎn),用來(lái)設(shè)置日志的輸入格式 ps:日志文件中不要設(shè)置顏色,否則顏色部分會(huì)有ESC[0:39em等亂碼--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern> <!-- 記錄日志的編碼:此處設(shè)置字符集 - --> <charset>UTF-8</charset> </encoder> </appender> <!-- error 日志文件--> <appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日志文件路徑和名稱(chēng)--> <File>E:\IDE\demlNewLog\error.log</File> <!--是否追加到文件末尾,默認(rèn)為true--> <append>true</append> <!-- ThresholdFilter過(guò)濾低于指定閾值的事件。 對(duì)于等于或高于閾值的事件,ThresholdFilter將在調(diào)用其decision()方法時(shí)響應(yīng)NEUTRAL。 但是,將拒絕級(jí)別低于閾值的事件 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <!-- 低于ERROR級(jí)別的日志(debug,info)將被拒絕,等于或者高于ERROR的級(jí)別將相應(yīng)NEUTRAL --> <level>ERROR</level> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 活動(dòng)文件的名字會(huì)根據(jù)fileNamePattern的值,每隔一段時(shí)間改變一次 --> <!-- 文件名示例:logs/project_error.2017-12-05.0.log --> <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是強(qiáng)制性的,必須存在,要不會(huì)報(bào)錯(cuò) --> <fileNamePattern>logs/project_error.%d.%i.log</fileNamePattern> <!-- 每產(chǎn)生一個(gè)日志文件,該日志文件的保存期限為30天 --> <maxHistory>30</maxHistory> <!-- 每個(gè)日志文件到10mb的時(shí)候開(kāi)始切分,最多保留30天,但最大到20GB,哪怕沒(méi)到30天也要?jiǎng)h除多余的日志 --> <totalSizeCap>20GB</totalSizeCap> <!-- maxFileSize:這是活動(dòng)文件的大小,默認(rèn)值是10MB,測(cè)試時(shí)可改成5KB看效果 --> <maxFileSize>10MB</maxFileSize> </rollingPolicy> <!--編碼器--> <encoder> <!-- pattern節(jié)點(diǎn),用來(lái)設(shè)置日志的輸入格式--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern> <!-- 記錄日志的編碼:此處設(shè)置字符集 - --> <charset>UTF-8</charset> </encoder> </appender> <!-- configuration中最多允許一個(gè)root,別的logger如果沒(méi)有設(shè)置級(jí)別則從父級(jí)別root繼承 --> <root level="INFO"> <appender-ref ref="STDOUT" /> </root> <!-- name屬性指定項(xiàng)目中某個(gè)包,當(dāng)有日志操作行為時(shí)的日志記錄級(jí)別 --> <logger name="com.example.demonew.controller" level="INFO"> <appender-ref ref="info_log" /> <appender-ref ref="error_log" /> </logger> <!-- 利用logback輸入mybatis的sql日志, 注意:如果不加 additivity="false" 則此logger會(huì)將輸出轉(zhuǎn)發(fā)到自身以及祖先的logger中,就會(huì)出現(xiàn)日志文件中sql重復(fù)打印--> <logger name="com.example.demonew.service" level="DEBUG" additivity="false"> <appender-ref ref="info_log" /> <appender-ref ref="error_log" /> </logger> <!-- additivity=false代表禁止默認(rèn)累計(jì)的行為,即com.atomikos中的日志只會(huì)記錄到日志文件中,不會(huì)輸出層次級(jí)別更高的任何appender--> <logger name="com.example" level="INFO" additivity="false"> <appender-ref ref="info_log" /> <appender-ref ref="error_log" /> </logger> </configuration>
到此這篇關(guān)于springboot 日志實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot 日志實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot使用TraceId進(jìn)行日志鏈路追蹤的實(shí)現(xiàn)步驟
- SpringBoot使用@Slf4j注解實(shí)現(xiàn)日志輸出的示例代碼
- Springboot日志配置的實(shí)現(xiàn)示例
- springboot項(xiàng)目配置logback-spring.xml實(shí)現(xiàn)按日期歸檔日志的方法
- 在SpringBoot框架中實(shí)現(xiàn)打印響應(yīng)的日志
- SpringBoot中使用AOP實(shí)現(xiàn)日志記錄功能
- SpringBoot項(xiàng)目實(shí)現(xiàn)日志打印SQL的常用方法(包括SQL語(yǔ)句和參數(shù))
- Springboot MDC+logback實(shí)現(xiàn)日志追蹤的方法
- SpringBoot集成logback打印彩色日志的代碼實(shí)現(xiàn)
相關(guān)文章
Java動(dòng)態(tài)代理實(shí)現(xiàn)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
動(dòng)態(tài)代理作為代理模式的一種擴(kuò)展形式,廣泛應(yīng)用于框架(尤其是基于AOP的框架)的設(shè)計(jì)與開(kāi)發(fā),本文將通過(guò)實(shí)例來(lái)講解Java動(dòng)態(tài)代理的實(shí)現(xiàn)過(guò)程2017-08-08Java利用redis zset實(shí)現(xiàn)延時(shí)任務(wù)詳解
zset作為redis的有序集合數(shù)據(jù)結(jié)構(gòu)存在,排序的依據(jù)就是score。本文就將利用zset score這個(gè)排序的這個(gè)特性,來(lái)實(shí)現(xiàn)延時(shí)任務(wù),感興趣的可以了解一下2022-08-08詳解SpringBoot緩存的實(shí)例代碼(EhCache 2.x 篇)
這篇文章主要介紹了詳解SpringBoot緩存的實(shí)例代碼(EhCache 2.x 篇),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Springboot應(yīng)用中線(xiàn)程池配置詳細(xì)教程(最新2021版)
這篇文章主要介紹了Springboot應(yīng)用中線(xiàn)程池配置教程(2021版),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03SpringBoot3整合Druid監(jiān)控功能的項(xiàng)目實(shí)踐
Druid連接池作為一款強(qiáng)大的數(shù)據(jù)庫(kù)連接池,提供了豐富的監(jiān)控和管理功能,成為很多Java項(xiàng)目的首選,本文主要介紹了SpringBoot3整合Druid監(jiān)控功能的項(xiàng)目實(shí)踐,感興趣的可以了解一下2024-01-01SpringBoot實(shí)現(xiàn)的Mongodb管理工具使用解析
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)的Mongodb管理工具使用解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Java中Array、List、Map相互轉(zhuǎn)換的方法詳解
這篇文章主要介紹了Java中Array、List、Map相互轉(zhuǎn)換的方法詳解,在實(shí)際項(xiàng)目開(kāi)發(fā)中或者一些算法面試題目中經(jīng)常需要用到Java中這三種類(lèi)型的相互轉(zhuǎn)換,比如對(duì)于一個(gè)整型數(shù)組中尋找一個(gè)整數(shù)與所給的一個(gè)整數(shù)值相同,需要的朋友可以參考下2023-08-08SpringBoot jackson 精度處理問(wèn)題解決
由于JavaScript處理的最大數(shù)值限制,較大的雪花ID在JS中容易溢出,為解決此問(wèn)題,可在SpringMVC或SpringBoot中使用@RequestBody注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10深入學(xué)習(xí)SpringCloud之SpringCloud簡(jiǎn)介
Spring Cloud是一個(gè)一站式的開(kāi)發(fā)分布式系統(tǒng)的框架,為開(kāi)發(fā)者提供了一系列的構(gòu)建分布式系統(tǒng)的工具集,本文給大家介紹springcloud的相關(guān)知識(shí),感興趣的朋友跟隨一起看看吧2021-04-04