(目錄)
1. 日志的作用
日志是程式的重要組成部分,在程式報錯的時候,如果我們不看日志,是很難排查出錯誤的,除非你真的是很有經驗.是以日志最主要的作用就是 排除和定位問題.
日志提供的功能:
- 記錄⽤戶登入⽇志,⽅便分析⽤戶是正常登入還是惡意⽤戶。
- 記錄系統的操作⽇志,⽅便資料恢複和定位操作⼈。
- 記錄程式的執⾏時間,⽅便為以後優化程式提供資料⽀持
舉例:
記錄⽤戶登入⽇志,⽅便分析⽤戶是正常登入還是惡意⽤戶。
假設有一個平台,一天被登入了10萬次,登入日志暴增!
正常情況下,可能一天 ,頂多1 萬多點。
但是,此時我們發現這一天的登入日志暴增,并且查到有好幾個賬号,在這一天裡登入上萬次!這還需要想嘛?肯定有人對着幾個賬号進行了惡意登入!(盜号)
我們馬上就可以對其進行當機操作,讓真正的使用者修改密碼資訊後,才能恢複正常使用。
甚至說:直接拉黑名單。
記錄系統的操作⽇志,⽅便資料恢複和定位操作⼈。
試想一下:當某個人在某個時間段進行了一次錯誤操作,而記錄檔會把這個操作的具體資訊給記錄下來了(操作人,操作時間,執行的操作,資料改動的前後狀态)。
此時,我們就可以根據這個日志,鎖定 執行該操作的人(bb 他一頓),讓其 對 操作資料 進行 復原(還原) 操作【根據日志的記錄】。
記錄程式的執⾏時間,⽅便為以後優化程式提供資料⽀持。
你可以了解為:日志,記錄了每一個方法的執行時間(在一個統一的地方記錄)。
就是說:記錄每一個方法之前,我們先做一個攔截,每一個方法執行之後,再做一個攔截。
這樣我們就能記錄每一個方法的執行時間了。
那麼,記錄方法的執行時間有什麼作用呢?
可以友善我們以後 對 程式進行針對性的優化。
公司裡面的 主管/經理,每周都會做一件事:按照方法執行時間來對日志進行排序。
将執行時間最長的 前十個方法,挑出來進行優化。
要想進行優化,沒有日志,你怎麼知道哪些方法的運作時間很長。
更别提對這些方法進行優化,提升執行效率。
2. 日志怎麼用
在我們啟動 SpringBoot 項目的時候就會輸出日志:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iN2YzM0EDM1QTYyMDNzgDNzYzX4EjM1MjMzEzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
隻不過,上面這些日志,。
不具有持久化存儲的特性
【沒存儲到 硬碟中】
簡單來說:
上述的這些日志,就是進行一個簡單的列印,不會存儲到硬碟。
也就是說 啟動下一個項目的時候,上一次啟動項目的日志是沒有被記錄下來的。
通過上述⽇志資訊我們能發現以下 3 個問題:
1、Spring Boot 内置了⽇志架構(不然也輸出不了⽇志)。
2、預設情況下,輸出的⽇志并⾮是開發者定義和列印的,而是 系統輸出的日志,那開發者怎麼在程式中⾃定義列印⽇志呢?
有的可能會說:使用 sout 輸出語句進行列印,不就行了。
答案是不行的,因為 sout 語句 存在 幾個問題!
3、![]()
【SpringBoot】SpringBoot 日志配置、級别、持久化1. 日志的作用2. 日志怎麼用3. 自定義日志列印4. 日志級别5. 日志持久化6. 更簡單的實作自定義日志的列印總結: ,⽽控制台的⽇志是不能被儲存的,那麼
⽇志預設是列印在控制台上的
?
怎麼把⽇志永久的儲存下來呢
3. 自定義日志列印
主要分兩個步驟:
- 在一個類中先獲得列印日志對象(日志架構提供的日志對象,而日志架構預設已經內建到 SpringBoot 裡了)
- 使用日志對象提供的方法實作日志的列印
3.1 得到日志對象
得到日志對象
Logger ,它來自于 slf4j
,不要導錯了包,在程式中擷取⽇志對象需要使⽤⽇志⼯⼚
LoggerFactory
3.2 使用日志對象提供的方法列印日志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@ResponseBody
public class UserController {
//1. 先得到日志對象(來自 slf4j)
private static final Logger log =
LoggerFactory.getLogger(UserController.class); //設定目前的類型
@RequestMapping("/sayhi")
public void sayHi(){
//2. 使用日志對象提供的列印方法進行日志列印
log.trace("我是 trace");
log.debug("我是 debug");
log.info("我是 info");
log.warn("我是 warn");
log.error("我是 error");
}
}
有些沒列印,因為他隻會列印跟他同級别的或者比他級别高的日志,他這裡預設是 info 級别.
3.3 日志格式說明
日志具體表示什麼資訊呢?
4. 日志級别
回報一些需要的日志,
并不需要把所有的都列印出來
就像是如果你是一家 2 萬人的公司的老闆,需要每天看他們的回報資訊,難道每個人都看嗎?這顯然看不完,你隻需要看一些領頭的就行…
4.1 日志級别分類
日志級别分為:
: 微量,少許的意思(級别最低)
trace
: 調試日志
debug
: 普通資訊日志
info
: 警告日志
warn
: 錯誤日志
error
: 緻命的日志(系統輸出的日志,不能自定義列印)
fatal
日志級别的順序:
越往上接收到的消息就越少。
注意:
fatal 是不支援列印
的,因為你程式都崩潰了,你還列印個錘子。。。
而且, 日志對象 也沒有提供 關于 fatal 的 方法、
4.2 日志級别的配置
① 全局日志級别設定
⽇志級别配置
隻需要在配置⽂件中設定
“logging.level”
配置項即可:
# 設定全局的日志級别
logging.level.root=warn
# 設定局部檔案夾的日志級别
logging.level.com.example.demo.UserController=trace
之前的
info
級别日志就沒列印了.
② 局部日志級别設定
方法也很簡單!!!
還是通過 logger.lever 來進行設定!
不同的就是:
将 root 修改成 你進行局部設定日志級别的對象(檔案夾 / 類)。
現在有一個問題:
在全局日志級别 和 局部日志級别,都被設定的情況下,哪一個的優先級最高?
是 全局日志級别設定,直接全部覆寫! 局部日志級别設定,并沒有生效!
即: 全局日志級别設定 比 局部日志級别設定 的 優先級要高!
還是 全局日志等級 的 設定,雖然起到了作用。
但是 設定了 局部日志級别 的 對象,遵守的是局部日志級别的設定。
即:
。
局部日志級别設定,比 全局日志級别設定 的 優先級要高
日常開發中,關于日志級别的設定,不會精确到類的!
最多精确到 檔案夾級别。
5. 日志持久化
前面列印的日志,隻是一閃而過!【列印完就沒了!】
因為,以上的⽇志都是輸出在控制台上的,而控制台上的資訊是
不會被存儲到硬碟上
的。
項目重新開機之後,之前的日志資訊就沒了。
然⽽在,我們是需要
⽣産環境上
将⽇志儲存下來
的。
以便出現問題之後追溯問題,把⽇志儲存到磁盤的過程就叫做持久化。
日志持久化
(将日志永久的儲存到磁盤的某個位置)
- 在配置檔案中
,當設定了儲存路徑之後,那麼日志就會自動進行持久化存儲。
設定日志的儲存路徑
- 在配置檔案中
,日志也會自動進行持久化存儲。
設定日志儲存的檔案名
#設定日志儲存的目錄 寫法一
logging.file.path=D:\\log
# 設定日志儲存的目錄寫法二
logging.file.path=D:/log
這個我就直接示範了。 就是把 path 改成 name 了。
# 設定日志的儲存名稱
logging.file.name=G:\\log\\spring-boot.log
下面我們來驗證一下效果:
但是!還存在一個問題!!!
如果 日志檔案 很大
(将所有的日志資訊,都存儲到一個檔案夾裡).
那我們檢視起來,不就很麻煩了!!!
那麼,有什麼方法是可以限制 日志檔案的大小呢?
這個問題,不是我們該操心的!
因為,日志檔案的大小,
。
預設是 10MB
當日志檔案大小超過了 10MB 的時候,會自動建立新的 日志檔案。
其命名格式,就像我們建立副本一樣:
spring-boot(1).log,spring-boot(2).log,spring-boot(3).log…
另外,是可用通過上述的方法進行設定 日志檔案的大小的。
6. 更簡單的實作自定義日志的列印
每次都使⽤ LoggerFactory.getLogger(xxx.class) 很繁瑣
,且每個類都添加⼀遍,也很麻煩,這⾥講⼀ 種更好⽤的⽇志輸出⽅式,使⽤ lombok 來更簡單的輸出。
- 添加
⽀持。
lombok 架構
- 使⽤
輸出⽇志。
@slf4j 注解
6.1 準備工作,添加 lombok 到項目中
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<optional>true</optional>
</dependency>
6.2 使用 @Slf4j 得到日志對象
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@ResponseBody
@Slf4j //替代了之前需要通過 LoggerFactory.getLogger 操作
public class UserController {
//1. 先得到日志對象(來自 slf4j)
// private static final Logger log =
// LoggerFactory.getLogger(UserController.class); //設定目前的類型
@RequestMapping("/sayhi")
public void sayHi(){
//2. 使用日志對象提供的列印方法進行日志列印
log.trace("我是 trace");
log.debug("我是 debug");
log.info("我是 info");
log.warn("我是 warn");
log.error("我是 error");
}
}
注意:使⽤ @Slf4j 注解,在程式中使⽤ log 對象即可輸⼊⽇志,并且隻能使⽤ log 對象才能輸出,這 是 lombok 提供的對象名
6.3 lombok 原了解釋
為什麼 加上 @Slf4j,就可以省略第一步,直接得到一個 log 對象呢?
看 .class
檔案,他是給我們轉換了的:
Java 程式的運⾏原理:
Lombok 的作⽤如下圖所示:
6.4 lombok 更多注解說明
注解 | 作用 |
---|---|
@Getter | ⾃動添加 getter ⽅法 |
@Setter | ⾃動添加 setter ⽅法 |
@ToString | ⾃動添加 toString ⽅法 |
@EqualsAndHashCode | ⾃動添加 equals 和 hashCode ⽅法 |
@NoArgsConstructor | ⾃動添加⽆參構造⽅法 |
@AllArgsConstructor | ⾃動添加全屬性構造⽅法,順序按照屬性的定義順序 |
@NonNull | 屬性不能為 null |
@RequiredArgsConstructor | ⾃動添加必需屬性的構造⽅法,final + @NonNull 的屬性為必需 |
組合注解:
注解 | 作用 |
---|---|
@Data | @Getter + @Setter + @ToString +@EqualsAndHashCode +@RequiredArgsConstructor +@NoArgsConstructor |
日志注解:
注解 | 作⽤ |
---|---|
@Slf4j | 添加⼀個名為 log 的⽇志,使⽤ slf4j |
總結:
⽇志是程式中的重要組成部分,使⽤⽇志可以快速的發現和定位問題。
Spring Boot 内容了⽇志架構。
預設情況下使⽤的是 info ⽇志級别
将⽇志輸出到控制台的。
- trace:微量,少許的意思,級别最低;
- debug:需要調試時候的關鍵資訊列印;
- info:普通的列印資訊;
- warn:警告,不影響使⽤,但需要注意的問題;
- error:錯誤資訊,級别較⾼的錯誤⽇志資訊;
- fatal:緻命的,因為代碼異常導緻程式退出執⾏的事件。