Spring Boot 日志概念及使用詳解
一、為什么要學(xué)習(xí)日志
日志對(duì)我們來(lái)說(shuō)并不陌生,從JavaSE部分,我們就在使用 System.out.print 來(lái)打印日志了.通過(guò)打
印日志來(lái)發(fā)現(xiàn)和定位問(wèn)題,或者根據(jù)日志來(lái)分析程序的運(yùn)行過(guò)程.在 Spring 的學(xué)習(xí)中,也經(jīng)常根據(jù)控制臺(tái)的日志來(lái)分析和定位問(wèn)題.
隨著項(xiàng)目的復(fù)雜度提升,我們對(duì)日志的打印也有了更高的需求,而不僅僅是定位排查問(wèn)題.
比如需要記錄一些用戶的操作記錄(一些審計(jì)公司會(huì)要求),也可能需要使用日志來(lái)記錄用戶的一些喜好,把日志持久化,后續(xù)進(jìn)行數(shù)據(jù)分析等.但是 System.out.print 不能很好的滿足我們的需求,我們就需要使用一些專門日志框架(專業(yè)的事情交給專業(yè)的人去做).
二、認(rèn)識(shí)日志格式
1??時(shí)間日期:精確到毫秒
2??日志級(jí)別:ERROR,WARN,INFO,DEBUG或TRACE
3??進(jìn)程 ID
4??線程名
5??Logger 名(通常使用源代碼的類名)
6??日志內(nèi)容
三、日志使用
SpringBoot 內(nèi)置了日志框架 Slf4j ,我們可以直接在程序中調(diào)用 Slf4j 來(lái)輸出日志
打印日志
步驟
• 在程序中得到日志對(duì)象.
需要使用志工廠 LoggerFactory
private static Logger logger = LoggerFactory.getLogger(CaptchaController.class);
LoggerFactory.getLogger 需要傳遞?個(gè)參數(shù), 標(biāo)識(shí)這個(gè)日志的名稱. 這樣可以更清晰的知道是哪個(gè)類輸出的日志. 當(dāng)有問(wèn)題時(shí), 可以更方便直觀的定位到問(wèn)題類
• 使用日志對(duì)象輸出要打印的內(nèi)容.
日志對(duì)象的打印方法有很多種,我們可以先使用 info() 方法來(lái)輸出日志
logger.info("Logger生成驗(yàn)證碼: " + code);
日志框架介紹
SLF4J不同于其他日志框架, 它不是一個(gè)真正的日志實(shí)現(xiàn), 而是一個(gè)抽象層, 對(duì)日志框架制定的一種規(guī)范, 標(biāo)準(zhǔn), 接口. 所有SLF4J并不能獨(dú)立使用, 需要和具體的日志框架配合使用.
門面模式(外觀模式)
SLF4J是門面模式的典型應(yīng)用(但不僅僅使用了門面模式).
門面模式(Facade Pattern)又稱為外觀模式,提供了一個(gè)統(tǒng)一的接口,用來(lái)訪問(wèn)子系統(tǒng)中的一群接口.其主要特征是定義了一個(gè)高層接口,讓子系統(tǒng)更容易使用.
門面模式主要包含2種角色:
外觀角色(Facade):也稱門面角色,系統(tǒng)對(duì)外的統(tǒng)一接口.
子系統(tǒng)角色(SubSystem):可以同時(shí)有一個(gè)或多個(gè)SubSystem.每個(gè)SubSytem都不是一個(gè)單獨(dú)的類,
而是一個(gè)類的集合.SubSystem并不知道Facade的存在,對(duì)于SubSystem而言,F(xiàn)acade只是另一個(gè)客戶端而已(即Facade對(duì)SubSystem透明)
門面模式的實(shí)現(xiàn)
場(chǎng)景: 回家, 我們會(huì)開各個(gè)屋的燈. 離開家時(shí), 會(huì)關(guān)閉各個(gè)屋的燈. 如果家里設(shè)置?個(gè)總開關(guān), 來(lái)控制整個(gè)屋的燈就會(huì)很方便.
沒建門面前
package com.example.demo.facade; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public interface Light { void on(); void off(); } public HallLight implements Light { private static Logger logger = LoggerFactory.getLogger(HallLight.class); @Override public void on() { logger.info("打開走廊燈"); } @Override public void off() { logger.info("關(guān)閉走廊燈"); } } public LivingRoomLight implements Light { private static Logger logger = LoggerFactory.getLogger(LivingRoomLight.class); @Override public void on() { logger.info("打開客廳燈"); } @Override public void off() { logger.info("關(guān)閉客廳燈"); } } public BedRoomLight implements Light { private static Logger logger = LoggerFactory.getLogger(BedRoomLight.class); @Override public void on() { logger.info("打開臥室燈"); } @Override public void off() { logger.info("關(guān)閉臥室燈"); } } public class Main { public static void main(String[] args) { HallLight hallLight = new HallLight(); LivingRoomLight livingRoomLight = new LivingRoomLight(); BedRoomLight bedRoomLight = new BedRoomLight(); hallLight.on(); livingRoomLight.on(); bedRoomLight.on(); } }
我們使用門面模式的實(shí)現(xiàn)
package com.example.demo.facade; public class LightFacade { void lightOn() { HallLight hallLight = new HallLight(); LivingRoomLight livingRoomLight = new LivingRoomLight(); BedRoomLight bedRoomLight = new BedRoomLight(); hallLight.on(); livingRoomLight.on(); bedRoomLight.on(); } void lightOff() { HallLight hallLight = new HallLight(); LivingRoomLight livingRoomLight = new LivingRoomLight(); BedRoomLight bedRoomLight = new BedRoomLight(); hallLight.off(); livingRoomLight.off(); bedRoomLight.off(); } }
package com.example.demo.facade; public class Main { public static void main(String[] args) { LightFacade lightFacade = new LightFacade(); lightFacade.lightOn(); lightFacade.lightOff(); } }
門面模式的優(yōu)點(diǎn)
●減少了系統(tǒng)的相互依賴,實(shí)現(xiàn)了客戶端與子系統(tǒng)的耦合關(guān)系,這使得子系統(tǒng)的變化不會(huì)影響到調(diào)用它的客戶端.
●提高了靈活性,簡(jiǎn)化了客戶端對(duì)子系統(tǒng)的使用難度,客戶端無(wú)需關(guān)心子系統(tǒng)的具體實(shí)現(xiàn)方式,而只需要和門面對(duì)象交互即可.
●提高了安全性,可以靈活設(shè)定訪問(wèn)權(quán)限,不在門面對(duì)象中開通方法,就無(wú)法訪問(wèn).
SLF4J 就是其他日志框架的門面. SLF4J 可以理解為是提供日志服務(wù)的統(tǒng)一API接口, 并不涉及到具體的日志邏輯實(shí)現(xiàn).
四、日志級(jí)別
日志級(jí)別代表著日志信息對(duì)應(yīng)問(wèn)題的嚴(yán)重性, 為了更快的篩選符合目標(biāo)的日志信息.
日志級(jí)別分類
日志的級(jí)別從高到低依次為:FATAL、ERROR、WARN、INFO、DEBUG、TRACE
??FATAL: 致命信息,表示需要立即被處理的系統(tǒng)級(jí)錯(cuò)誤.
??ERROR: 錯(cuò)誤信息,級(jí)別較高的錯(cuò)誤日志信息,但仍然不影響系統(tǒng)的繼續(xù)運(yùn)行.
??WARN: 警告信息,不影響使用,但需要注意的問(wèn)題.
??INFO: 普通信息,用于記錄應(yīng)用程序正常運(yùn)行時(shí)的一些信息,例如系統(tǒng)啟動(dòng)完成、請(qǐng)求處理完成等.
??DEBUG: 調(diào)試信息,需要調(diào)試時(shí)候的關(guān)鍵信息打印.
??TRACE: 追蹤信息,比 DEBUG 更細(xì)粒度的信息事件(除非有特殊用意,否則請(qǐng)使用 DEBUG級(jí)別替代).
日志級(jí)別的使用
package com.example.demo.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/logger") @RestController public class LoggerLevelController { private static Logger logger = LoggerFactory.getLogger(LoggerLevelController.class); @RequestMapping("/print") public String print() { logger.trace("trace級(jí)別日志......"); logger.debug("debug級(jí)別日志......"); logger.info("info級(jí)別日志......"); logger.warn("warn級(jí)別日志......"); logger.error("error級(jí)別日志......"); return "打印日志"; } }
結(jié)果發(fā)現(xiàn), 只打印了info, warn和error級(jí)別的日志.
這與日志級(jí)別的配置有關(guān), 日志的輸出級(jí)別默認(rèn)是 info 級(jí)別, 所以只會(huì)打印大于等于此級(jí)別的日志, 也就是 info, warn和error.
日志配置
配置日志級(jí)別
logging: level: root: debug
日志級(jí)別也可以分類來(lái)設(shè)置
logging: level: root: info com: example: demo: controller: trace
日志持久化
以上的日志都是輸出在控制臺(tái)上的, 然日在線上環(huán)境中, 我們需要把日志保存下來(lái), 以便出現(xiàn)問(wèn)題之后追溯問(wèn)題. 把日志保存下來(lái)就叫持久化.
日志持久化有兩種方式
1??配置日志文件名
logging: file: name: logger/springboot.log
后?可以跟絕對(duì)路徑或者相對(duì)路徑
2??配置日志的存儲(chǔ)目錄
logging: file: path: D:/temp
logging: file: path: D:/temp/aaa/springboot.log
這種方式只能設(shè)置日志的路徑, 文件名為固定的 spring.log
??logging.file.name 和 logging.file.path 兩個(gè)都配置的情況下, 只生效其一, 以 logging.file.name 為準(zhǔn).
配置日志文件分割
如果我們的日志都放在一個(gè)文件中, 隨著項(xiàng)目的運(yùn)行, 日志文件會(huì)越來(lái)越大, 需要對(duì)日志文件進(jìn)行分割.
logging: file: #path: D:/temp/aaa/springboot.log name: logger/springboot.log logback: rollingpolicy: max-file-size: 1KB file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
1.日志文件超過(guò) 1KB 就分割(設(shè)置 1KB 是為了更好展示.企業(yè)開發(fā)通常設(shè)置為200M,500M等,此處沒有明確標(biāo)準(zhǔn))
2.分割后的日志文件名為:日志名.日期.索引
五、更簡(jiǎn)單的日志輸出
每次都使用 LoggerFactory.getLogger(xxx.class) 很繁瑣, 且每個(gè)類都添加一遍, lombok 給我們提供了?種更簡(jiǎn)單的方式.
1??添加 lombok 框架支持
2??使用 @Slf4j 注解輸出日志
lombok 提供的 @Slf4j 會(huì)幫我們提供?個(gè)日志對(duì)象 log, 我們直接使用就可以.
package com.example.demo.controller; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RequestMapping("/logger2") @RestController public class LoggerLevelController2 { //private static Logger logger = LoggerFactory.getLogger(LoggerLevelController2.class); @RequestMapping("/print") public String print() { log.trace("trace級(jí)別日志......"); log.debug("debug級(jí)別日志......"); log.info("info級(jí)別日志......"); log.warn("warn級(jí)別日志......"); log.error("error級(jí)別日志......"); return "打印日志"; } }
到此這篇關(guān)于Spring Boot 日志的文章就介紹到這了,更多相關(guān)Spring Boot 日志內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot日志的使用與多個(gè)日志框架沖突問(wèn)題及解決
- SpringBoot日志的使用解讀
- SpringBoot使用ResponseBodyEmitter處理流式日志和進(jìn)度條
- SpringBoot使用TraceId進(jìn)行日志鏈路追蹤的實(shí)現(xiàn)步驟
- springboot項(xiàng)目使用nohup將日志指定輸出文件過(guò)大問(wèn)題及解決辦法
- SpringBoot使用@Slf4j注解實(shí)現(xiàn)日志輸出的示例代碼
- SpringBoot中使用AOP實(shí)現(xiàn)日志記錄功能
- SpringBoot+logback默認(rèn)日志的配置和使用方式
相關(guān)文章
springboot 實(shí)現(xiàn)記錄業(yè)務(wù)日志和異常業(yè)務(wù)日志的操作
這篇文章主要介紹了springboot 實(shí)現(xiàn)記錄業(yè)務(wù)日志和異常業(yè)務(wù)日志的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07java獲取指定開始時(shí)間與結(jié)束時(shí)間之間的所有日期
這篇文章主要為大家詳細(xì)介紹了java獲取指定開始時(shí)間與結(jié)束時(shí)間之間的所有日期,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05SpringBoot任務(wù)調(diào)度器的實(shí)現(xiàn)代碼
SpringBoot自帶了任務(wù)調(diào)度器,通過(guò)注解的方式使用。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12idea sql的xml文件出現(xiàn)紅色警告符的處理方式
這篇文章主要介紹了idea sql的xml文件出現(xiàn)紅色警告符處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04FeignClient設(shè)置動(dòng)態(tài)url方式
文章介紹了如何在Spring Cloud環(huán)境下使用FeignClient實(shí)現(xiàn)負(fù)載均衡,通過(guò)配置Nacos和FeignClient屬性,可以實(shí)現(xiàn)服務(wù)間的負(fù)載均衡調(diào)用2024-11-11簡(jiǎn)單聊聊工作中常用的Java?Lambda表達(dá)式
日常開發(fā)中,我們很多時(shí)候需要用到Java?8的Lambda表達(dá)式,它允許把函數(shù)作為一個(gè)方法的參數(shù),讓我們的代碼更優(yōu)雅、更簡(jiǎn)潔。所以整理了一波工作中常用的Lambda表達(dá)式??赐暌欢〞?huì)有幫助的2022-11-11