SpringBoot應(yīng)用自定義logback日志詳解
概述
默認(rèn)情況下,SpringBoot內(nèi)部使用logback作為系統(tǒng)日志實(shí)現(xiàn)的框架,將日志輸出到控制臺(tái),不會(huì)寫(xiě)到日志文件。如果在application.properties或application.yml配置,這樣只能配置簡(jiǎn)單的場(chǎng)景,保存路徑、日志格式等。復(fù)雜的場(chǎng)景(區(qū)分 info 和 error 的日志、每天產(chǎn)生一個(gè)日志文件等)滿(mǎn)足不了,只能自定義配置文件logback-spring.xml或者logback.xml。本篇文章主要講解下如何自定義logabck.xml以及對(duì)logback文件中配置做一個(gè)詳解。
logback配置詳解
首先我們先了解下logback。
logback 主要分為三個(gè)模塊:
- logback-core:是其他兩個(gè)模塊的基礎(chǔ)模塊
- logback-classic:是對(duì) core 模塊的擴(kuò)展,相當(dāng)于 log4j 的改良版。classic 模塊實(shí)現(xiàn)了 Slf4j 的 API 因此可以便于和其他日志框架直接切換
- logback-access:與Servlet容器集成,以提供http訪問(wèn)日志功能。
官網(wǎng)配置文檔地址:https://logback.qos.ch/manual/configuration.html
配置內(nèi)容概念介紹
Logger Context
LoggerContext負(fù)責(zé)制造logger,也負(fù)責(zé)以樹(shù)結(jié)構(gòu)排列各logger。其他所有l(wèi)ogger也通過(guò)org.slf4j.LoggerFactory 類(lèi)的靜態(tài)方法getLogger取得。 getLogger方法以 logger名稱(chēng)為參數(shù)。
Logger
Logger作為日志的記錄器,把它關(guān)聯(lián)到應(yīng)用的對(duì)應(yīng)的context上后,主要用于存放日志對(duì)象,也可以定義日志類(lèi)型、級(jí)別。
Appender
Appender主要用于指定日志輸出的目的地,目的地可以是控制臺(tái)、文件、遠(yuǎn)程套接字服務(wù)器、 MySQL、PostreSQL、 Oracle和其他數(shù)據(jù)庫(kù)、 JMS和遠(yuǎn)程UNIX Syslog守護(hù)進(jìn)程等。
Layout
負(fù)責(zé)把事件轉(zhuǎn)換成字符串,格式化的日志信息的輸出。
配置介紹
配置文件的基本結(jié)構(gòu):以開(kāi)頭,后面有零個(gè)或多個(gè)元素,有零個(gè)或多個(gè)元素,有最多一個(gè)元素。
默認(rèn)配置的步驟
- 嘗試在 classpath下查找文件logback-test.xml;
- 如果文件不存在,則查找文件logback.xml;
- 如果兩個(gè)文件都不存在,logback用BasicConfigurator自動(dòng)對(duì)自己進(jìn)行配置,這會(huì)導(dǎo)致記錄輸出到控制臺(tái)。
<?xml version="1.0" encoding="UTF-8"?> <!-- scan:當(dāng)此屬性設(shè)置為true時(shí),配置文件如果發(fā)生改變,將會(huì)被重新加載,默認(rèn)值為true。 scanPeriod:設(shè)置監(jiān)測(cè)配置文件是否有修改的時(shí)間間隔,如果沒(méi)有給出時(shí)間單位,默認(rèn)單位是毫秒。當(dāng)scan為true時(shí),此屬性生效。默認(rèn)的時(shí)間間隔為1分鐘。 debug:當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息,實(shí)時(shí)查看logback運(yùn)行狀態(tài)。默認(rèn)值為false。 --> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 運(yùn)行環(huán)境,dev:開(kāi)發(fā),test:測(cè)試,pre:預(yù)生產(chǎn),pro:生產(chǎn) --> <property name="system_host" value="dev" /> <property file="system.properties" /> <!-- 上下文變量設(shè)置,用來(lái)定義變量值,其中name的值是變量的名稱(chēng),value的值時(shí)變量定義的值。 通過(guò)<property>定義的值會(huì)被插入到logger上下文中。定義變量后,可以使“${}”來(lái)使用變量。 --> <property name="CONTEXT_NAME" value="logback-test" /> <!-- 日志文件存放路徑設(shè)置,絕對(duì)路徑 --> <property name="logs.dir" value="/opt/logs" /> <!-- 日志文件存放路徑設(shè)置,tomcat路徑 --> <property name="logs.dir" value="${catalina.base}/logs" /> <!-- 定義日志文件 相對(duì)輸入位置 --> <property name="log_dir" value="log" /> <!-- 日志輸出格式設(shè)置 --> <!-- %d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n Logger: %logger Class: %class File: %file Caller: %caller Line: %line Message: %m Method: %M Relative: %relative Thread: %thread Exception: %ex xException: %xEx nopException: %nopex rException: %rEx Marker: %marker newline:%n --> <property name="CUSTOM_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n" /> <!-- 上下文名稱(chēng):<contextName>, 每個(gè)logger都關(guān)聯(lián)到logger上下文, 默認(rèn)上下文名稱(chēng)為“default”。但可以使用<contextName>設(shè)置成其他名字,用于區(qū)分不同應(yīng)用程序的記錄。 一旦設(shè)置,不能修改。 --> <contextName>${CONTEXT_NAME}</contextName> <!-- <appender>是<configuration>的子節(jié)點(diǎn),是負(fù)責(zé)寫(xiě)日志的組件。 有兩個(gè)必要屬性name和class。 name指定appender名稱(chēng), class指定appender的實(shí)現(xiàn)類(lèi)。 --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!-- 對(duì)日志進(jìn)行格式化。 --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 按天來(lái)回滾,如果需要按小時(shí)來(lái)回滾,則設(shè)置為{yyyy-MM-dd_HH} --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>log/testC.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 如果按天來(lái)回滾,則最大保存時(shí)間為30天,30天之前的都將被清理掉 --> <maxHistory>30</maxHistory> <!-- 按時(shí)間回滾的同時(shí),按文件大小來(lái)回滾 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 過(guò)濾器,只記錄WARN級(jí)別的日志 --> <!-- 果日志級(jí)別等于配置級(jí)別,過(guò)濾器會(huì)根據(jù)onMath 和 onMismatch接收或拒絕日志。 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 設(shè)置過(guò)濾級(jí)別 --> <level>WARN</level> <!-- 用于配置符合過(guò)濾條件的操作 --> <onMatch>ACCEPT</onMatch> <!-- 用于配置不符合過(guò)濾條件的操作 --> <onMismatch>DENY</onMismatch> </filter> <!-- 日志輸出格式 --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="log_file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 被寫(xiě)入的文件名,可以是相對(duì)目錄,也可以是絕對(duì)目錄,如果上級(jí)目錄不存在會(huì)自動(dòng)創(chuàng)建,沒(méi)有默認(rèn)值。 --> <file>${logs.dir}/logback-test.log</file> <!-- 按照固定窗口模式生成日志文件,當(dāng)文件大于20MB時(shí),生成新的日志文件。窗口大小是1到3,當(dāng)保存了3個(gè)歸檔文件后,將覆蓋最早的日志 --> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <!-- 必須包含“%i”例如,假設(shè)最小值和最大值分別為1和2,命名模式為 mylog%i.log,會(huì)產(chǎn)生歸檔文件mylog1.log和mylog2.log。還可以指定文件壓縮選項(xiàng),例如,mylog%i.log.gz 或者 沒(méi)有l(wèi)og%i.log.zip --> <FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern> <!-- 窗口索引最小值 --> <minIndex>1</minIndex> <!-- 窗口索引最大值 --> <maxIndex>3</maxIndex> </rollingPolicy> <!-- 日志級(jí)別過(guò)濾器 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 日志級(jí)別過(guò)濾器 --> <level>INFO</level> <!-- 符合要求的日志級(jí)別,過(guò)濾,ACCEPT:接受 --> <onMatch>ACCEPT</onMatch> <!-- 不符合要求的日志級(jí)別,過(guò)濾,DENY:拒絕 --> <onMismatch>DENY</onMismatch> </filter> <!-- 激活滾動(dòng)的條件。 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <!-- 活動(dòng)文件的大小,默認(rèn)值是10MB --> <maxFileSize>30MB</maxFileSize> </triggeringPolicy> <!-- 對(duì)記錄事件進(jìn)行格式化。 --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 異步輸出 --> <appender name="ASYNC_logback" class="ch.qos.logback.classic.AsyncAppender"> <!-- 不丟失日志.默認(rèn)的,如果隊(duì)列的80%已滿(mǎn),則會(huì)丟棄TRACT、DEBUG、INFO級(jí)別的日志 --> <!-- <discardingThreshold>0</discardingThreshold> --> <!-- 更改默認(rèn)的隊(duì)列的深度,該值會(huì)影響性能.默認(rèn)值為256 --> <!-- <queueSize>256</queueSize> --> <!-- 添加附加的appender,最多只能添加一個(gè) --> <appender-ref ref="log_file" /> </appender> <!-- 指定包輸出路徑 --> <!-- 用來(lái)設(shè)置某一個(gè) 包 或者具體的某一個(gè) 類(lèi) 的日志打印級(jí)別、以及指定<appender>, name:用來(lái)指定受此logger約束的某一個(gè)包或者具體的某一個(gè)類(lèi)。 level:用來(lái)設(shè)置打印級(jí)別,大小寫(xiě)無(wú)關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個(gè)特俗值INHERITED或者同義詞NULL,代表強(qiáng)制執(zhí)行上級(jí)的級(jí)別。如果未設(shè)置此屬性,那么當(dāng)前l(fā)oger將會(huì)繼承上級(jí)的級(jí)別。 additivity:是否向上級(jí)logger傳遞打印信息。默認(rèn)是true。(這個(gè)logger的上級(jí)就是上面的root) <logger>可以包含零個(gè)或多個(gè)<appender-ref>元素,標(biāo)識(shí)這個(gè)appender將會(huì)添加到這個(gè)logger。 --> <logger name="org.logback.test" level="DEBUG" additivity="true"> <appender-ref ref="stdout" /> </logger> <!-- 特殊的<logger>元素,是根logger。只有一個(gè)level屬性,應(yīng)為已經(jīng)被命名為"root". level:設(shè)置打印級(jí)別,大小寫(xiě)無(wú)關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設(shè)置為INHERITED或者同義詞NULL。默認(rèn)是DEBUG。 <root>可以包含零個(gè)或多個(gè)<appender-ref>元素,標(biāo)識(shí)這個(gè)appender將會(huì)添加到這個(gè)loger。 --> <root> <level value="WARN" /> <!-- if表達(dá)式,需要Janino jar --> <!-- Janino 2.6.0版本開(kāi)始,除了janino.jar之外, commons-compiler.jar也需要在類(lèi)路徑中 --> <if condition='property("system_host").contains("dev")'> <then> <appender-ref ref="stdout" /> </then> </if> <appender-ref ref="file" /> </root> </configuration>
SpringBoot中自定義logback
SpringBoot啟用自定義logback有3種方式:
- classpath下存在logback-spring.xml
- classpath下有l(wèi)ogback.xml
- 配置文件中通過(guò)配置項(xiàng)指定文件:
logging.config: ./logback-rule.xml
如果可能,我們建議您為日志記錄配置使用-spring變體或者通過(guò)配置項(xiàng)的方式(例如,logback-spring.xml而不是logback.xml)。如果使用標(biāo)準(zhǔn)配置,Spring不能完全控制日志初始化。
我們本例使用logback-spring.xml作為配置文件演示。
在 src/main/resources 下創(chuàng)建 logback-spring.xml 文件,分開(kāi)記錄系統(tǒng)輸出日志和Error日志。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <!--彩色日志輸出格式--> <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}){magenta} %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <!--非彩色日志輸出格式--> <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" /> <!--dev文件路徑:src同級(jí)目錄logs,如果上級(jí)目錄不存在會(huì)自動(dòng)創(chuàng)建--> <property name="DEV_FILE_PATH" value="./logs" /> <!-- pro文件路徑 --> <property name="PRO_FILE_PATH" value="./logs-prod" /> <!-- 控制臺(tái)輸出 --> <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> </encoder> </appender> <!-- 按照每天生成輸出日志文件 --> <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <encoder> <!--格式化輸出:%d表示日期,%thread表示線程,%-5level:級(jí)別從左顯示五個(gè)字符寬度,%logger{36}:logger是class的全名,后面的數(shù)字代表限制最長(zhǎng)的字符,%msg:日志消息,%n換行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> <!--滾動(dòng)策略按照時(shí)間滾動(dòng)--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- rollover daily 文件名稱(chēng) --> <fileNamePattern>${DEV_FILE_PATH}/output-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB --> <!--單個(gè)文件大小--> <maxFileSize>10MB</maxFileSize> <!--日志文件保留天數(shù)--> <maxHistory>60</maxHistory> <!--用來(lái)指定日志文件的上限大小,到了這個(gè)值就會(huì)刪除舊日志-->a <totalSizeCap>2GB</totalSizeCap> </rollingPolicy> </appender> <!-- 按照每天生成錯(cuò)誤日志文件 --> <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 此日志文件只記錄ERROR級(jí)別的 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> <!--輸出日志到src同級(jí)目錄logs中的error.log文件中--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--基于大小和時(shí)間的輪轉(zhuǎn)策略,當(dāng)日志內(nèi)容超出文件大小限制后,會(huì)自動(dòng)生成一個(gè)文件來(lái)繼續(xù)記錄和重命名--> <fileNamePattern>${DEV_FILE_PATH}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB --> <maxFileSize>10MB</maxFileSize> <maxHistory>60</maxHistory> <totalSizeCap>2GB</totalSizeCap> </rollingPolicy> </appender> <root level="INFO"> <appender-ref ref="consoleAppender" /> <appender-ref ref="fileAppender" /> <appender-ref ref="errorAppender" /> </root> </configuration>
java中打印日志:
@SpringBootApplication @Slf4j public class LogbackApp { public static void main(String[] args) { SpringApplication.run(LogbackApp.class, args); log.trace("Trace 日志..."); log.debug("Debug 日志..."); log.info("Info 日志..."); log.warn("Warn 日志..."); log.error("Error 日志..."); } }
輸出結(jié)果:
SpringBoot官方建議使用logback-spring.xml作為logback框架的自定義日志配置文件,使用logback-spring.xml而不是logback.xml,因?yàn)閹?spring后綴的配置文件可以使用一些擴(kuò)展的功能。
多環(huán)境輸出日志文件
Logback 配置文件中的 節(jié)點(diǎn)指令允許您根據(jù)配置文件激活參數(shù)(active) 選擇性的包含和排查部分配置信息。根據(jù)不同環(huán)境來(lái)定義不同的日志輸出,在 logback-spring.xml中使用 節(jié)點(diǎn)來(lái)定義,方法如下:
<!--開(kāi)發(fā)環(huán)境:打印控制臺(tái)--> <springProfile name="dev"> <root level="DEBUG"> <appender-ref ref="consoleAppender" /> <appender-ref ref="fileAppender" /> <appender-ref ref="errorAppender" /> </root> </springProfile> <!--生產(chǎn)環(huán)境:輸出到文件--> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="consoleAppender" /> <appender-ref ref="fileAppender" /> <appender-ref ref="errorAppender" /> </root> </springProfile>
配置文件添加配置項(xiàng):
結(jié)果:
打印出了debug日志,說(shuō)明dev的配置生效了。
讀取配置文件配置
本文通過(guò)讀取配置文件中的配置修改輸出的日志文件名來(lái)演示。
1.配置文件中添加配置項(xiàng)
2.logback-spring.xml中添加配置內(nèi)容如下:
<springProperty scope="context" name="logFileName" source="log.file.name" defaultValue="output"/>
- scope: 使用范圍
- name: 變量名
- source: 讀取的配置項(xiàng)名
- defaultValue: 默認(rèn)名稱(chēng)
3.通過(guò)${....}使用配置
4.結(jié)果,成功修改了輸出的日志文件名
文章代碼地址:https://github.com/alvinlkk/springboot-demo/tree/master/springboot-log-logback
以上就是SpringBoot應(yīng)用自定義logback日志詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot應(yīng)用自定義logback日志的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
如何解決@PutMapping或@PostMapping接收String類(lèi)型參數(shù)多兩個(gè)“引號(hào)問(wèn)題
這篇文章主要介紹了如何解決@PutMapping或@PostMapping接收String類(lèi)型參數(shù)多兩個(gè)“引號(hào)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08Java實(shí)現(xiàn)對(duì)象排序的兩種方式詳解
這篇文章主要介紹了Java實(shí)現(xiàn)對(duì)象排序的兩種方式詳解,在Java中經(jīng)常會(huì)涉及到對(duì)象數(shù)組的排序問(wèn)題,則就提到對(duì)象之間的比較問(wèn)題,今天我們就來(lái)看一下兩種不同排序方式之間的區(qū)別,需要的朋友可以參考下2023-09-09常用數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序及JDBC URL分享
這篇文章主要介紹了常用數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序及 JDBC URL,需要的朋友可以看下2014-01-01Java中的原子類(lèi)AtomicInteger使用詳解
這篇文章主要介紹了Java中的原子類(lèi)AtomicInteger使用詳解,原子操作是指不會(huì)被線程調(diào)度機(jī)制打斷的操作,這種操作一旦開(kāi)始,就一直運(yùn)行到結(jié)束,中間不會(huì)有任何線程上下文切換,需要的朋友可以參考下2023-12-12詳解Spring Data JPA中Repository的接口查詢(xún)方法
repository代理有兩種方式從方法名中派生出特定存儲(chǔ)查詢(xún):通過(guò)直接從方法名派生查詢(xún)和通過(guò)使用一個(gè)手動(dòng)定義的查詢(xún)。本文將通過(guò)示例詳細(xì)講解Spring Data JPA中Repository的接口查詢(xún)方法,需要的可以參考一下2022-04-04springboot 實(shí)現(xiàn)Http接口加簽、驗(yàn)簽操作方法
這篇文章主要介紹了springboot 實(shí)現(xiàn)Http接口加簽、驗(yàn)簽操作,服務(wù)之間接口調(diào)用,通過(guò)簽名作為安全認(rèn)證來(lái)保證API的安全性,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09idea配置多環(huán)境啟動(dòng)方式dev、test、prod
這篇文章主要介紹了idea配置多環(huán)境啟動(dòng)方式dev、test、prod,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09