SpringBoot日志信息以及Lombok的常用注解詳析
一. 日志的介紹
1. 什么是日志
日志是我們程序重要組成部分,它是程序在運(yùn)行過程當(dāng)中輸出的一些提示或異常信息,我們可以通過日志來觀察程序執(zhí)行的情況,如果程序出現(xiàn) Bug,我們可以根據(jù)日志去發(fā)現(xiàn)和排查程序的 Bug。
SpringBoot 項(xiàng)目在啟動的時(shí)候,就會有默認(rèn)的日志輸出,如下圖所示:
之所以會有上面的輸出,是因?yàn)?SpringBoot 中內(nèi)置了日志框架。
SpringBoot 中內(nèi)置了 SLF4J 和 logback 兩個(gè)日志框架,用戶層面并不是直接操作具體的日志對象,而是使用 SLF4J 提供給用戶的 API 進(jìn)而由 logback 操作具體的日志對象實(shí)現(xiàn)日志。
SLF4J 這類框架是使用“門面模式”來實(shí)現(xiàn)的,SLF4J 其實(shí)和 JDBC 很像,我們知道使用 JDBC 操作數(shù)據(jù)庫,一套 JDBC 代碼就可以操作很多種數(shù)據(jù)庫,可以是 MySQL,Oracle,DB2,SqlServer等,而這個(gè)JDBC 就相當(dāng)于代理一樣,來代理去操作數(shù)據(jù)庫,我們不必關(guān)心各種數(shù)據(jù)庫的實(shí)現(xiàn),只需關(guān)注 JDBC 提供給我們的的 API 即可。
類似的,SLF4J 中也并不是真正完成了日志實(shí)現(xiàn)的框架,它只是一個(gè)門面或者一個(gè)代理,我們調(diào)用 SLF4J 的 API,SLF4J 中還會去調(diào)用 logback 這樣的日志實(shí)現(xiàn)框架,此時(shí)我們就不必關(guān)心日志實(shí)現(xiàn)的細(xì)節(jié),這一層面我們是感知不到的,這就是門面模式所帶來的好處,還有一個(gè)好處就是如果日志實(shí)現(xiàn)層出現(xiàn)了漏洞,只需要修改更換日志實(shí)現(xiàn)的框架即可,而 SLF4J 可以匹配相應(yīng)的日志框架,此時(shí)雖然日志實(shí)現(xiàn)的框架發(fā)生了改變,但我們寫的代碼仍然不受影響,這樣就使得系統(tǒng)的依賴性降低,利于系統(tǒng)更新和維護(hù)。
2. 日志的作用
- 能夠幫助程序猿排除程序的 Bug。
- 記錄用戶登錄日志,方便分析用戶是正常登錄還是惡意破解用戶。
- 記錄系統(tǒng)的操作日志,方便數(shù)據(jù)恢復(fù)和定位操作人。
- 記錄程序的執(zhí)行時(shí)間,方便為以后優(yōu)化程序提供數(shù)據(jù)支持。
二. 日志的使用
使用日志框架可以配置日志的級別來控制日志的輸出,而我們?nèi)粘J褂?code>System.out.printf來輸出日志是無法做到這一點(diǎn)的。
1. 日志格式說明
對于控制臺輸出的日志,它的各部分含義如下:
信息中的包名有部分是簡寫,取的是包名的第一個(gè)字母;
根據(jù)這些信息,我們就可以知道日志是發(fā)生在什么時(shí)間,在哪個(gè)線程,哪個(gè)類,以及具體的日志信息。
2. 自定義日志的輸出
1??第一步,在類中先獲取到日志對象,這個(gè)日志對象來自于日志框架SLF4J
。
假設(shè)我們在類LogController
設(shè)置自定義日志的輸出,則日志對象創(chuàng)建代碼如下:
每一個(gè)類都對應(yīng)一個(gè)日志對象,可以通過日志工廠LoggerFactory
獲取的,導(dǎo)包的時(shí)候要注意Logger
對象是在org.slf4j
包下的,不要導(dǎo)錯(cuò)。
// 獲取日志對象 private static Logger log = LoggerFactory.getLogger(LogController.class);
getLogger()
一般傳入傳入當(dāng)前類的類型,這里的參數(shù)用來定位日志的歸屬類,以方便日志輸出,輸出的日志信息中有了日志的定位, 才能更方便、更直觀的定位到問題類。
2??第二步,使用日志對象提供的方法來實(shí)現(xiàn)自定義日志的打印。
日志對象提供的方法有很多,可以設(shè)定不同級別的日志信息輸出。
??示例代碼:
@RestController
相當(dāng)于是將@Controller
和@ResponseBody
這兩個(gè)注解合起來的效果。
package com.example.springboot2.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LogController { // 獲取日志對象 private static Logger log = LoggerFactory.getLogger(LogController.class); @RequestMapping("/log") public void log() { log.trace("我是trace"); log.debug("我是debug"); log.info(("我是info")); log.warn("我是warn"); log.error("我是error"); } }
我們啟動程序后,訪問http://127.0.0.1:8080/log
后,控制臺就有相應(yīng)的日志輸出了。
觀察輸出結(jié)果,我們的代碼是寫了 5 個(gè)級別的日志輸出的,為什么這里結(jié)果只有 3 個(gè)結(jié)果呢?這是因?yàn)镾pringBoot 項(xiàng)目下,默認(rèn)日志級別為info
,低于info
日志級別的都不會輸出。
3. 日志級別
??日志級別分為一下幾種:
- trace:微量,少許的意思,級別最低。
- debug:需要調(diào)試時(shí)候的關(guān)鍵信息打印。
- info:普通的打印信息(默認(rèn)日志級別)。
- warn:警告,不影響使用,但需要注意的問題。
- error:錯(cuò)誤信息,級別較高的錯(cuò)誤日志信息。
- fatal:致命的,因?yàn)榇a異常導(dǎo)致程序退出執(zhí)行的事件,不支持用戶自定義。
SpringBoot 項(xiàng)目默認(rèn)的日志級別是info
,那么比info
日志級別低的是不能輸出的,也就是debug
與trace
的日志是不會輸出的,只有大于等于info
級別的日志才會輸出。
??日志級別的作用:
- 日志級別可以幫我們篩選出重要的信息,比如設(shè)置日志級別為 error,那么就可以只看程序的報(bào)錯(cuò)日志了,對于普通的調(diào)試日志和業(yè)務(wù)日志就可以忽略了,從而節(jié)省開發(fā)者信息篩選的時(shí)間。
- 日志級別可以控制不同環(huán)境下,?個(gè)程序是否需要打印日志,如開發(fā)環(huán)境我們就需要很詳細(xì)的日志信息, 而生產(chǎn)環(huán)境為了保證性能和安全性就會輸?盡量少的?志,通過日志的級別就可以實(shí)現(xiàn)此需求。
簡單來說,就是過濾信息,將業(yè)務(wù)不需要的日志屏蔽掉。
4. 日志級別的配置
日志級別是可以通過配置文件進(jìn)行設(shè)置的,日志級別包括兩類,一類是全局日志級別,另一類就是局部日志級別,全局日志級別可以影響全局日志的輸出,而局部日志級別只會影響一個(gè)局部的日志輸出,并且局部日志級別配置大于全局日志級別的配置。
??全局日志級別配置,如修改默認(rèn)日志級別為trace
:
properties 日志格式:
# 設(shè)置全局日志級別 logging.level.root=trace
yml 日志格式:
logging: level: root: trace
運(yùn)行上面我們的自定義日志代碼,此時(shí)就會發(fā)現(xiàn),我們所有的自定義日志信息都會輸出,并且隨著程序啟動相比較默認(rèn)情況下會有更多的日志信息輸出,畢竟這里設(shè)置的是全局的配置文件,會影響全局。
??下面來介紹局部日志級別的配置,我們將LogController
類的日志級別設(shè)置為warn
,此時(shí)只會LogController
類中日志輸出級別,并不會影響其他位置的日志信息輸出。
properties 格式配置文件:
# 設(shè)置夾局部的日志級別 (包名/包名+類名) logging.level.com.example.demo.controller.LogController=warn
yml 格式配置文件:
logging: level: com: example: demo: controller: LogController :warn
控制臺結(jié)果:
yml 格式配置文件可以一步設(shè)置全局和局部的日志級別,比如:
logging: level: root: info com: example: springboot2: controller: error service: warn
root
設(shè)置的是全局日志級別,項(xiàng)目中所有日志級別都是info
;和root
同級下可設(shè)置局部具體類的日志級別m這里就是com.example.springboot2.controller
和com.example.springboot2.service
包下的類,級別分別為error
和warn
。
5. 日志持久化
前面的介紹都是將日志輸出在控制臺上的,然而我們在生產(chǎn)環(huán)境下往往需要將日志保存下來,以便于后續(xù)出現(xiàn)問題時(shí)去追溯原因,將日志保存下來的過程就稱之為持久化。
實(shí)現(xiàn)日志持久化的方式就是將日志信息保存到磁盤,同樣可以通過設(shè)置配置文件實(shí)現(xiàn)。
??方式1:設(shè)置日志保存路徑
properties 格式配置文件:
logging.file.path=D:\\bit\\logs
yml 格式配置文件:
logging: file: path: D:\\bit\\logs
啟動程序,此時(shí) SpringBoot 就會將控制臺中打印的日志寫到對應(yīng)的目錄了,日志文件默認(rèn)名的為spring.log
。
??方式2:設(shè)置日志保存文件
properties 格式配置文件:
logging.file.name=D:\\bit\\log\\logging.log
yml 格式配置文件:
logging: file: name: D:\\bit\\log\\logging.log
效果如下:
還要注意,多次訪問程序產(chǎn)生的日志是以追加的形式保存到日志文件當(dāng)中的,SpringBoot 默認(rèn)保存日志文件的大小為10MB
**,**超出范圍就會自動創(chuàng)建新的日志文件,然后保存到新的日志文件當(dāng)中。
當(dāng)然,也可以通過配置文件自定義日志文件的大小,配置方式如下:
# properties格式 logging.logback.rollingpolicy.max-file-size=10MB # yml格式 logging: logback: rollingpolicy: max-file-size: 10MB
6. 更簡單的輸出日志-Lomok
每次都使? LoggerFactory.getLogger(xxx.class) 很繁瑣,且每個(gè)類都添加?遍,也很麻煩,在 Lombok 中有一個(gè)@Slf4j
注解,可以使用該注解更簡單的輸出日志。
準(zhǔn)備工作,首先要確保你的 IDEA 中有 Lombok 這個(gè)插件,沒有的話去下載一下。
然后,添加 Lombok 依賴,可以使用 Edit Starters 插件快捷添加。
刷新一下,依賴就添加好了。
??使用方法:在想打印日志的類上加上 @Slf4j 注解即可,它會為當(dāng)前類提供一個(gè) log 對象。
要注意使用 @Slf4j 注解,在程序中使用 log 對象即可輸??志,并且只能使? log 對象才能輸出,這是 lombok 提供的對象名;代碼中輸入 log 后就會有相關(guān)方法的提醒(前提是安裝了 lombok 插件)。
package com.example.springboot2.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j // 當(dāng)前的類中就可以直接使用 log 對象, @Slf4j 產(chǎn)生一個(gè) log 對象, 直接使用即可 public class LogController2 { @RequestMapping("/log2") public void log2(){ log.trace("我是trace"); log.debug("我是debug"); log.info(("我是info")); log.warn("我是warn"); log.error("我是error"); } }
啟動程序,訪問路路徑http://127.0.0.1:8080/log2
,同樣可以輸出日志,代碼更簡單。
@Slf4j 注解替代了日志對象獲取的代碼:
private final static Logger log = LoggerFactory.getLogger(LogController2.class);
7. Lombok框架實(shí)現(xiàn)原理以及其他常見注解
Lombok 框架其實(shí)在編譯的時(shí)候,將依據(jù)注解去替生成對應(yīng)的代碼,比如就像上面的日志對象創(chuàng)建,加上一個(gè) @Slf4j 注解后,在編譯時(shí)就會將類似與上面創(chuàng)建日志對象的代碼生成到我們所寫代碼里面去,包括Lombok 其他的注解,如生成 Setter 的注解 @Setter,生成 Getter 的注解 @Getter 等都是通過編譯時(shí)期間實(shí)現(xiàn)的。
??Lombok作用:
比如上面我們寫的代碼最終生成相應(yīng)的字節(jié)碼文件就在 target 目錄中,target 目錄中的代碼才是項(xiàng)目最終執(zhí)行的代碼,查看 target 目錄如下:
我們來對比一下我們LogController2.java
原文件代碼和程序運(yùn)行起來后生成LogController2.class
文件中的代碼(由 IDEA 反編譯顯示)。
發(fā)現(xiàn)代碼中的 @Slf4j 注解就不存存在了,被 log 對象替代了,所以,Lombok 是不會影響程序運(yùn)行的信能的,它要完成的工作都是在編譯生成字節(jié)碼文件前完成的。
??其他常用注解:
基本注解:
注解 | 作用 |
---|---|
@Setter | ?動添加 setter 方法 |
@Getter | ?動添加 getter 方法 |
@ToString | ?動添加 toString 方法 |
@EqualsAndHashCode | ?動添加 equals 和 hashCode 方法 |
@NoArgsConstructor | ?動添加?參構(gòu)造方法 |
@AllArgsConstructor | ?動添加全屬性構(gòu)造?法,順序按照屬性的定義順序 |
@NonNull | 屬性不能為 null |
@RequireArgsConstructor | ?動添加必需屬性的構(gòu)造方法,final + @NonNull 的 屬性為必需 |
組合注解:
注解 | 作用 |
---|---|
@Data | @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor |
日志注解:
注解 | 作用 |
---|---|
@Slf4j | 添加?個(gè)名為 log 的日志,使用 slf4j |
使用 Lombok 提供給我們的這些注釋,可以很好的幫助我們消除項(xiàng)目中大量冗余的代碼,可以使得我們的 Java 類可以看起來非常的干凈整潔。
總結(jié)
到此這篇關(guān)于SpringBoot日志信息以及Lombok的常用注解的文章就介紹到這了,更多相關(guān)SpringBoot日志信息Lombok注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot項(xiàng)目的logback日志配置(包括打印mybatis的sql語句)
- 基于logback 實(shí)現(xiàn)springboot超級詳細(xì)的日志配置
- springboot使用Logback把日志輸出到控制臺或輸出到文件
- Spring Boot異步輸出Logback日志方法詳解
- SpringBoot Logback日志記錄到數(shù)據(jù)庫的實(shí)現(xiàn)方法
- 在SpringBoot中使用Logback管理記錄日志
- 詳解Spring Boot配置使用Logback進(jìn)行日志記錄的實(shí)戰(zhàn)
- springboot配置logback日志管理過程詳解
相關(guān)文章
SpringBoot集成Aviator實(shí)現(xiàn)參數(shù)校驗(yàn)的示例代碼
在實(shí)際開發(fā)中,參數(shù)校驗(yàn)是保障系統(tǒng)穩(wěn)定和數(shù)據(jù)可靠性的重要措施,Aviator 是一個(gè)高性能的表達(dá)式引擎,它能夠簡化復(fù)雜的邏輯判斷并提升參數(shù)校驗(yàn)的靈活性,本文將介紹如何在 Spring Boot 中集成 Aviator,并利用它來實(shí)現(xiàn)靈活的參數(shù)校驗(yàn),需要的朋友可以參考下2025-02-02Spring boot中@Conditional和spring boot的自動配置實(shí)例詳解
本文通過實(shí)例給大家介紹了Spring boot中@Conditional和spring boot的自動配置,需要的朋友可以參考下2018-05-05SpringBoot中項(xiàng)目如何讀取外置logback配置文件
這篇文章主要介紹了SpringBoot中項(xiàng)目如何讀取外置logback配置文件問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11Spring 使用注解方式進(jìn)行事務(wù)管理配置方式
本篇文章主要介紹了Spring 使用注解方式進(jìn)行事務(wù)管理配置方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04java數(shù)據(jù)結(jié)構(gòu)與算法之中綴表達(dá)式轉(zhuǎn)為后綴表達(dá)式的方法
這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)與算法之中綴表達(dá)式轉(zhuǎn)為后綴表達(dá)式的方法,簡單分析了java中綴表達(dá)式轉(zhuǎn)為后綴表達(dá)式的相關(guān)實(shí)現(xiàn)方法與技巧,需要的朋友可以參考下2016-08-08Java集合框架Collections原理及用法實(shí)例
這篇文章主要介紹了Java集合框架Collections原理及用法實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08