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