這個專欄給大家介紹一下 Java 家族的核心產(chǎn)品 - SSM 框架
JavaEE 進(jìn)階專欄Java 語言能走到現(xiàn)在 , 仍然屹立不衰的原因 , 有一部分就是因為 SSM 框架的存在
接下來 , 博主會帶大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相關(guān)知識點
并且?guī)ьI(lǐng)大家進(jìn)行環(huán)境的配置 , 讓大家真正用好框架、學(xué)懂框架
來上一篇文章復(fù)習(xí)一下吧
點擊即可跳轉(zhuǎn)到我的小秘密
學(xué)習(xí)目標(biāo)
- 輸出自定義日志信息
- 將日志持久化
- 通過設(shè)置日志的級別來篩選和控制日志的內(nèi)容
一 . 日志有什么用
日志只有一個作用 : 發(fā)現(xiàn)問題 定位問題
我們之前已經(jīng)使用了很多次的日志
除了發(fā)現(xiàn)和定位問題之外,我們還可以通過日志實現(xiàn)以下功能:
- 記錄用戶登錄日志,方便分析用戶是正常登錄還是惡意破解用戶。
- 記錄系統(tǒng)的操作 , 方便數(shù)據(jù)恢復(fù)和定位操作。
- 記錄程序的執(zhí)行時間 , 方便為以后優(yōu)化程序提供數(shù)據(jù)支持。
1.1 日志格式說明
日志打印級別 : 用來篩選有效信息
在日常調(diào)試和開發(fā)過程中 , 我們需要看的日志通常會比較多 , 在生產(chǎn)環(huán)境的時候 , 我們并不需要看調(diào)試日志以及開發(fā)日志 , 我們就可以把他屏蔽掉 , 也可以把 Spring Boot 展示給我們的日志(INFO) 也關(guān)閉掉 , 只展示報錯以及警告信息 , 那么我們就可以通過日志的級別來進(jìn)行篩選關(guān)鍵信息 . 而且打印日志也是會消耗一定資源的 , 所以在線上環(huán)境就盡量別弄出什么幺蛾子了 .
通過目前我們了解到的日志 , 我們發(fā)現(xiàn)三個問題 :
- 這是 Spring Boot 默認(rèn)的日志格式 , 目前我們打印出的都是系統(tǒng)自己的日志 , 那么我們怎么樣能讓控制臺打印我們自己的日志 ?
- 我們的日志是保存在我們的內(nèi)存上的 , 那么假如我們的線上環(huán)境出現(xiàn)了問題 , 我們也不能說讓人一直去看著 , 出現(xiàn)問題趕緊把開發(fā)人員叫過來查看日志 , 所以日志的持久化保存也是非常有必要的
- 我們需要通過日志的級別來篩選我們需要的信息
二 . 自定義日志打印
自定義日止的實現(xiàn)步驟 :
- 在程序中得到日志對象
- 使用日志對象的相關(guān)語法輸出要打印的內(nèi)容
我們思考一個問題 : 使用 sout 語句能否替代日志呢 ?
TestController.java
package com.example.demo.aa.bb;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// 這個注解什么意思先不用管
@RestController
public class TestController {
// 這個注解什么意思先不用管
@RequestMapping("/sayhi")
public String sayHi() {
System.out.println("這里正在測試日志");
return "日志";
}
}
我們這不也打印出相關(guān)信息了嗎 ?
但是感覺跟正常的日志差得有點多 , 感覺不太靠譜
- 只有打印的內(nèi)容 , 沒有其他的相關(guān)信息 , 比如打印的時間、打印的類(出處)
- 不能實現(xiàn)不同環(huán)境下的行為控制
比如我們的日志能夠通過日志級別篩選 , 讓線上環(huán)境或者開發(fā)環(huán)境展示出不同的信息 , 而 sout 語句不行 , 他會在哪里都打印的
所以使用 sout 語句是不能替代日志的 , 還是需要專業(yè)的人干專業(yè)的事的
2.1 得到日志對象
導(dǎo)入 Logger 對象
注意 : 一定要選擇 org.slf4j (颯樓否四節(jié))
然后使用 Logger 的 LoggerFactory 里面的 getLogger 方法, 參數(shù)填寫當(dāng)前類.class
2.2 使用日志對象提供的方法 , 輸出自定義的日志內(nèi)容
使用 log.
的方式 , 接下來我們就可以打印日志了
package com.example.demo.aa.bb;
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 TestController {
// 1. 得到日志對象
private static Logger log = LoggerFactory.getLogger(TestController.class);
@RequestMapping("/sayhi")
public String sayHi() {
// 2. 打印日志
log.info("Hi,Spring Boot Log.");//使用日志對象的方法輸出日志
return "日志";
}
}
那么我們上面告訴大家一定要用 slf4j , 那么 slf4j 是個什么東西 ?
我們的 slf4j 與 Spring Boot 是密切相關(guān)的 , slf4j 也是目前行業(yè)中的日志標(biāo)桿了 , 他的日志以我們目前對于 Spring Boot 的理解來說 , 還算是比較復(fù)雜的 . 但看似很簡單的日志 , 其實是由兩部分實現(xiàn)的
我們可以這樣理解 : 日志門面就是前端 , 日志實現(xiàn)就是后端
為什么一個簡簡單單的日志還要分解為日志門面還有日志實現(xiàn)呢 ?
最剛開始 , 其實日志是不分類的 , 后來發(fā)現(xiàn)了一個問題 : 我們的代碼通用性問題 , 假如我們最開始用 log4j 1/2 , 但是后來他就出現(xiàn)漏洞了 , 所以大家又轉(zhuǎn)戰(zhàn)到了 logback , 但是使用 logback 就出現(xiàn)了問題 : 我們之前所有調(diào)用日志代碼的地方就需要去更改 , 這樣日志就沒有通用性了 , 所以我們就再抽象一層 , 我們是從 slf4j 使用的 , slf4j 會自己幫我們解決好適配性問題 , 提高代碼的移植性
其實和我們 JDBC 的問題是一樣的 , 大家都是為了能夠提高代碼的通用性
2.3 日志的級別
我們不光可以打印普通日志 , 還可以打印其他等級的日志
package com.example.demo.aa.bb;
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 TestController {
// 1. 得到日志對象
private static Logger log = LoggerFactory.getLogger(TestController.class);
@RequestMapping("/sayhi")
public String sayHi() {
// 2. 打印日志
// 級別從上到下逐個提升的
log.trace("Hi,I am trace.");//痕跡日志
log.debug("Hi,I am debug.");//調(diào)試日志
log.info("Hi,I am info.");//普通日志
log.warn("Hi,I am warn.");//警告日志
log.error("Hi,I am error");//報錯
return "日志";
}
}
那為什么剩下兩個沒被打印呢 ?
這是因為默認(rèn)情況下日志級別是 info , 所以就把 trace debug 篩選下去了
那么我們都有哪些級別的日志呢 ?
- trace:微量,少許的意思,級別最低;
- debug:需要調(diào)試時候的關(guān)鍵信息打印;
- info:普通的打印信息;
- warn:警告,不影響使用,但需要注意的問題;
- error:錯誤信息,級別較高的錯誤日志信息;
- fatal:致命的,因為代碼異常導(dǎo)致程序退出執(zhí)行的事件。
那么我們上面只打印出來五種啊 , 咋沒打印第六種 .
可以看到 , 我們是調(diào)用不出來 fatal 的 . 這種致命的錯誤不是你說調(diào)就調(diào)出來的 , 當(dāng)發(fā)生異常情況導(dǎo)致終止的時候才能看到 fatal , 甚至說嚴(yán)重點 , 還沒有多少人見過他的芳容 .
三 . 日志持久化
3.1 在配置文件里面設(shè)置日志名稱
我們在 application.yml 里面添加這句配置項
# 設(shè)置日志文件的文件名
logging:
file:
name: springboot.log
接下來運(yùn)行查看一下效果
還可以這樣去看
如果有的同學(xué)沒看見日志在哪里 , 可以把 target 文件夾刪除 , 重新運(yùn)行再來看
接下來 , 我們就可以把項目停掉 , 來看一下咱們的日志
那么我們重新運(yùn)行 , 新的日志是追加在后面還是覆蓋掉 ?
肯定是追加在后面 , 不然還是有日志丟失的風(fēng)險 .
重新運(yùn)行后的日志就變多了
那么日志一直追加 , 越來越大 , 打開的速度就會變得非常慢 , 尋找日志就比較麻煩 , 那怎么辦呢 ?
當(dāng)日志比較大的時候 , 會自動分割成多個文件 , 所以不用去擔(dān)心
3.2 設(shè)置日志的保存目錄
# 設(shè)置日志文件的目錄
logging:
file:
path: D:\study\JavaCode
我們打開這個目錄看一下是否真的生成了 ?
那么我們把程序停止 , 看看日志里面有什么 ?
那么這種方式能不能追加日志呢 ?
也是可以追加的
四 . 日志級別的設(shè)置
日志級別的設(shè)置非常的精細(xì)化 , 可以針對于某個目錄設(shè)置日志級別 , 還可以設(shè)置一個全局的日志級別
日志級別配置只需要在配置文件中設(shè)置 “l(fā)ogging level” 配置項即可
logging:
level:
root: debug
注意 : 我們之前寫過 logging , 要是再寫一個 logging 的話就會報錯
所以我們可以在一個 logging 標(biāo)簽底下寫多個配置項
logging:
file:
path: D:\study\JavaCode
level:
root: warn # 根路徑
那么有的人只想看到自己的 DEBUG 日志 , 不想看到 Spring 的 DEBUG 日志 , 因為 Spring 的 DEBUG 日志實在是太多了 , 那么我們就可以把系統(tǒng)日志設(shè)置的級別高一些 , 可以讓 Spring 的日志級別設(shè)置成 warn , 我們自己的代碼的日志級別設(shè)置成 debug
logging:
file:
path: D:\study\JavaCode
level:
root: warn # 根路徑
com:
example:
demo: debug # com.example.demo 下面的所有類,日志級別都是 debug
那么我們想要自己的日志級別為 trace , 系統(tǒng)日志為 warn 怎么處理呢 , 同樣很簡單
logging:
file:
path: D:\study\JavaCode
level:
root: warn # 根路徑
com:
example:
demo: trace
接下來 , 我們模擬一下真實的開發(fā)環(huán)境
上節(jié)課我們學(xué)過多平臺的配置文件設(shè)置 , 那么我們就可以根據(jù)不同的環(huán)境打印出不同等級的日志了
首先 , 我們創(chuàng)建出三個不同的環(huán)境的配置文件
開發(fā)環(huán)境的配置文件 : application-dev.yml
測試環(huán)境的配置文件 : application-test.yml
生產(chǎn)環(huán)境的配置文件 : application-prod.yml
然后我們分別在每個配置文件中設(shè)置不一樣的端口 , 方便我們后續(xù)測試效果
然后接下來設(shè)置每個環(huán)境的日志等級
開發(fā)環(huán)境設(shè)置成系統(tǒng)日志為 warn , 自己的日志為 debug
測試環(huán)境設(shè)置成系統(tǒng)日志為 warn , 自己的日志為 info
生產(chǎn)環(huán)境設(shè)置成系統(tǒng)日志為 warn , 自己的日志為 warn
接下來在我們總的配置文件中調(diào)用每個單獨的配置文件
# 運(yùn)行環(huán)境設(shè)置
spring:
profiles:
active: dev
記得這里要去瀏覽器訪問 127.0.0.1:8888/sayhi
, 因為我們的開發(fā)環(huán)境配置文件端口號是 8888
這次訪問 127.0.0.1:9999/sayhi
# 運(yùn)行環(huán)境設(shè)置
spring:
profiles:
active: test
這次訪問 127.0.0.1:11111/sayhi
# 運(yùn)行環(huán)境設(shè)置
spring:
profiles:
active: prod
五 . 簡化日志的小技巧 - lombok
我們在 com.example.demo 包底下新建一個 StudentController 類
然后編寫代碼
package com.example.demo;
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 StudentController {
// 1. 得到日志對象
private static Logger logger = LoggerFactory.getLogger(StudentController.class);
@RequestMapping("/hi")
public String sayHi() {
// 2. 使用日志對象提供的方法進(jìn)行日志打印
logger.trace("Hi,I am trace.");
logger.debug("Hi,I am debug.");
return "Hi,Spring Boot.";
}
}
但是每次這樣寫 , 我們還覺得怪麻煩的
那我們的 Spring Boot 還是可以解決這個問題的
這就需要我們使用額外的庫 - lombok
我們之前不想寫 Getter Setter 方法 , 只要在上面加上 @Getter @Setter 注解 , 甚至直接加一個 @Data 注解即可
等到日志這里 , 我們發(fā)現(xiàn)唯一不同的 ,就是圖片里圈出來那部分 , lombok 發(fā)現(xiàn)了 , 只有類型不同 , 那么我們只需要拿到當(dāng)前類的類型唄 , 那我就通過一個注解幫你完成 , 注解內(nèi)部就是我們圖片里的這句代碼 , lombok 自動幫我們獲取類型了
那怎么使用 lombok 來更簡單的輸出呢 ?
5.1 lombok 的使用
- 添加 lombok 框架支持。
- 使用 @slf4j 注解輸出日志。
package com.example.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// 1. 引入 lombok 依賴
@Slf4j
@RestController
public class StudentController {
@RequestMapping("/hi")
public String sayHi() {
// 2. 使用日志對象提供的方法進(jìn)行日志打印
log.debug("Hi,I am debug.");
return "Hi,Spring Boot.";
}
}
有的同學(xué)可能調(diào)用不出來 lombok , 比如這樣
只需要添加 lombok 的依賴即可
右鍵 -> Generate
選擇 Dependency
搜索 lombok , 選擇第二個
這樣 lombok 依賴就自己添加進(jìn)去了
前提是 IDEA 版本是 2021.3.2+ , 其他版本我們也可以選擇裝一個插件 : EditStarters 實現(xiàn)依賴引入
這個頁面似曾相識
這樣依賴就添加進(jìn)去了 , 記得手動刷新一下
5.2 lombok 的原理
實際上 , 原理就是這樣
lombok 在編譯期間就開始干活了 , 這樣對于 JVM 來說是感知不到的 , 他就知道我們傳過來的代碼里面已經(jīng)有日志對象了
5.3 lombok 更多注解說明
基本注解 :
注解 | 作用 |
---|---|
@Getter | 自動添加 getter 方法 |
@Setter | 自動添加 setter 方法 |
@ToString | 自動添加 toString 方法 |
@EqualsAndHashCode | 自動添加 equals 和 hashCode 方法 |
@NoArgsConstructor | 自動添加 無參構(gòu)造 方法 |
@AllArgsConstructor | 自動添加 全屬性的構(gòu)造方法 方法 , 順序按照屬性的定義順序 |
@NonNull | 屬性設(shè)置成不能為 null |
@RequiredArgsConstructor | ?動添加必需屬性的構(gòu)造方法 , final + @NonNull 的屬性為必需 |
組合注解 :
注解 | 作用 |
---|---|
@Data | @Getter + @Setter + @ToString + |
@EqualsAndHashCode + | |
@RequiredArgsConstructor + | |
@NoArgsConstructor |
日志注解 :
注解 | 作用 |
---|---|
@Slf4j | 添加?個名為 log 的日志,使用 slf4j |
總結(jié)
日志是程序中的重要組成部分,試用日志可以快速的發(fā)現(xiàn)和定位問題,Spring Boot 提供了日志框架 , 默認(rèn)情況下使用的是 info 日志級別將日志輸出到控制臺的,我們可以通過 lombok 提供的 @Slf4j 注解和 log 對象快速的打印自定義日志,?日志包含 6 個級別:
- trace:微量,少許的意思,級別最低;
- info:普通的打印信息;
- debug:需要調(diào)試時候的關(guān)鍵信息打?。?/li>
- warn:警告,不影響使用,但需要注意的問題;
- error:錯誤信息,級別較高的錯誤日志信息;
- fatal:致命的,因為代碼異常導(dǎo)致程序退出執(zhí)行的事件。
日志級別依次提升 , 而日志級別越高,收到的日志信息也就越少,我們可以通過配置日志的保存名稱或保存目錄來將日志永久地保存下來。文章來源:http://www.zghlxwxcb.cn/news/detail-636712.html
至此 , Spring Boot 的日志文件就分享完畢 , 給個三連來救救小貓文章來源地址http://www.zghlxwxcb.cn/news/detail-636712.html
到了這里,關(guān)于Java EE 突擊 9 - Spring Boot 日志文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!