SpringBoot日志配置SLF4J和Logback的方法實(shí)現(xiàn)
一、前言
在開(kāi)發(fā) Java 應(yīng)用時(shí),日志記錄是不可或缺的一部分。日志可以記錄應(yīng)用的運(yùn)行狀態(tài)、錯(cuò)誤信息和調(diào)試信息,幫助開(kāi)發(fā)者快速定位和解決問(wèn)題。Spring Boot 項(xiàng)目默認(rèn)集成了 SLF4J 和 Logback,使得日志配置變得簡(jiǎn)單而靈活。本文將詳細(xì)介紹如何在 Spring Boot 項(xiàng)目中配置 SLF4J 和 Logback,包括基本的日志配置、日志文件的輸出路徑、日志級(jí)別、日志格式和環(huán)境區(qū)分配置。
日志的重要性
- 快速定位問(wèn)題:通過(guò)分析日志,開(kāi)發(fā)者可以迅速定位應(yīng)用程序中的錯(cuò)誤或性能問(wèn)題。
- 確保合規(guī)性:許多行業(yè)要求應(yīng)用程序符合特定標(biāo)準(zhǔn),日志記錄了應(yīng)用程序的運(yùn)行狀態(tài),便于審計(jì)和合規(guī)性檢查。
- 提高開(kāi)發(fā)效率:日志記錄了應(yīng)用程序的歷史行為,有助于快速?gòu)?fù)現(xiàn)問(wèn)題并優(yōu)化代碼。
日志框架介紹

門(mén)面模式(Facade Pattern)又稱為外觀模式
門(mén)面模式(Facade Pattern)又稱為外觀模式, 提供了一個(gè)統(tǒng)?的接口, ?來(lái)訪問(wèn)?系統(tǒng)中的?群接口.
其主要特征是定義了?個(gè)高層接口, 讓子系統(tǒng)更容易使用。
門(mén)面模式主要包含2種角色:
- 外觀角色(Facade): 也稱門(mén)面角色,系統(tǒng)對(duì)外的統(tǒng)?接口.
- 子系統(tǒng)角色(SubSystem): 可以同時(shí)有?個(gè)或多個(gè) SubSystem. 每個(gè) SubSytem 都不是?個(gè)單獨(dú)的類,而是?個(gè)類的集合. SubSystem 并不知道 Facade 的存在, 對(duì)于 SubSystem 而言, Facade 只是另?個(gè)客戶端而已(即 Facade 對(duì) SubSystem 透明)
比如去醫(yī)院看病,可能要去掛號(hào), 門(mén)診, 化驗(yàn), 取藥, 讓患者或患者家屬覺(jué)得很復(fù)雜, 如果有提供接待人員, 只讓接待?員來(lái)處理, 就很方便。

日志級(jí)別分類
1.Trace:最低級(jí)別的日志,追蹤, 指明程序運(yùn)行軌跡,比DEBUG更細(xì)粒度的信息事件(除非有特殊用意,否則請(qǐng)使用DEBUG級(jí)別替代)
2.Debug詳細(xì)調(diào)試信息,常用于調(diào)試過(guò)程中使用的調(diào)試信息
3.Info一般信息或狀態(tài)更新,常用于提供程序運(yùn)行的基本信息
4.Warning警告性信息,常用于提醒可能的問(wèn)題或性能優(yōu)化建議
5.ERROR錯(cuò)誤信息, 級(jí)別較高的錯(cuò)誤日志信息, 但仍然不影響系統(tǒng)的繼續(xù)運(yùn)行。
6.FATAL致命信息,表示需要立即被處理的系統(tǒng)級(jí)錯(cuò)誤。

二、案例一:初識(shí)日志
- 引入依賴Spring Boot 項(xiàng)目默認(rèn)已經(jīng)包含了 SLF4J 和 Logback 的依賴,如果你使用的是 Spring Initializr 初始化的項(xiàng)目,通常不需要額外添加依賴。如果你的項(xiàng)目中沒(méi)有這些依賴,可以在
pom.xml中添加如下依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
- 基本日志配置
Spring Boot 允許通過(guò)application.yml或application.properties文件進(jìn)行簡(jiǎn)單的日志配置。以下是一個(gè)基本的配置示例:
application.yml
logging:
level:
root: INFO
com.example.yourpackage: DEBUG # 你的項(xiàng)目包路徑
file:
name: application.log
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
application.properties
logging.level.root=INFO
logging.level.com.example.yourpackage=DEBUG # 你的項(xiàng)目包路徑
logging.file.name=application.log
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
以上配置將日志級(jí)別設(shè)置為INFO,并為你的項(xiàng)目包設(shè)置為DEBUG級(jí)別。同時(shí),設(shè)置了日志文件的名稱和日志輸出的格式。
- 日志的打印
LoggerController
注意創(chuàng)建的日志對(duì)象,Logger和LoggerFactory類都是來(lái)自于Slf4j包底下的類。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/logger")
public class LoggerController {
// 要想打印日志的前提是要有一個(gè)日志對(duì)象,日志對(duì)象來(lái)自于LoggerFactory類中
// 創(chuàng)建日志對(duì)象
private Logger logger= LoggerFactory.getLogger(LoggerController.class);
//打印不同級(jí)別的日志
@RequestMapping("/log")
public String log(){
logger.info("====日志內(nèi)容=====");
logger.trace("====日志內(nèi)容=====");
logger.debug("====日志內(nèi)容=====");
logger.error("====日志內(nèi)容=====");
logger.warn("====日志內(nèi)容=====");
return "打印日志";
}
}
代碼運(yùn)行結(jié)果:
因本項(xiàng)目端口為9000
故訪問(wèn)路徑:http://localhost:9000/logger/log

- 日志持久化
以上的日志都是輸出在控制臺(tái)上的, 然而在線上環(huán)境中, 我們需要把日志保存下來(lái), 以便出現(xiàn)問(wèn)題之后追溯問(wèn)題. 把日志保存下來(lái)就叫持久化。
日志持久化有兩種方式:
- 配置日志文件名
- 配置日志的存儲(chǔ)目錄
配置日志文件名:
yml配置
logging:
file:
# 在源目錄下創(chuàng)建日志文件
name: log/log.log

配置日志的保存路徑yml文件配置
logging:
file:
# 日志在指定路徑下面
path: d/loggeController
三、案例二:使用Lombok輸出日志
上面創(chuàng)建日志對(duì)象的方式還是比較麻煩的,如果程序中的類比較多的話,每個(gè)類都需要?jiǎng)?chuàng)建一個(gè)日志對(duì)象,就很繁瑣,此時(shí)我們可以借助lombok中的**@Slf4j**注解來(lái)更簡(jiǎn)單的輸出日志。
@RestController
@RequestMapping("/logger")
@Slf4j
public class LoggerController {
// @Slf4j 等同于
// private Logger log= LoggerFactory.getLogger(LoggerController.class);
@RequestMapping("/log")
public String log(){
// 添加@Slf4j注解后,類會(huì)自動(dòng)生成一個(gè)log對(duì)象
log.info("====日志內(nèi)容=====");
log.trace("====日志內(nèi)容=====");
log.debug("====日志內(nèi)容=====");
log.error("====日志內(nèi)容=====");
log.warn("====日志內(nèi)容=====");
return "打印日志";
}
}
四、案例三:配置Logback
Logback 是 SLF4J 的一個(gè)實(shí)現(xiàn),提供了更強(qiáng)大的日志配置功能。你可以通過(guò)logback-spring.xml文件進(jìn)行更詳細(xì)的日志配置。以下是一個(gè)示例配置文件:
1、logback-spring.xml
<configuration>
<!-- 定義日志文件的路徑和名稱 -->
<property name="LOG_PATH" value="/var/log/yourapp" />
<property name="LOG_FILE" value="${LOG_PATH}/application.log" />
<!-- 控制臺(tái)日志輸出配置 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 文件日志輸出配置 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件的滾動(dòng)策略 -->
<fileNamePattern>${LOG_PATH}/application-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory> <!-- 保留30天的日志文件 -->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 指定日志級(jí)別 -->
<logger name="org.apache.ibatis" level="DEBUG">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</logger>
<logger name="com.example.yourpackage" level="DEBUG">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</logger>
<!-- 根日志級(jí)別 -->
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
2、環(huán)境區(qū)分配置
在實(shí)際項(xiàng)目中,不同環(huán)境(如開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境)的日志配置需求可能會(huì)有所不同。Spring Boot 支持多配置文件來(lái)區(qū)分不同環(huán)境。你可以在src/main/resources目錄下創(chuàng)建多個(gè)配置文件,例如:
application-dev.yml:開(kāi)發(fā)環(huán)境配置application-test.yml:測(cè)試環(huán)境配置application-prod.yml:生產(chǎn)環(huán)境配置
application-dev.yml
spring:
config:
activate:
on-profile: dev
logging:
level:
root: DEBUG
com.example.yourpackage: DEBUG
file:
name: application-dev.log
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
application-test.yml
spring:
config:
activate:
on-profile: test
logging:
level:
root: INFO
com.example.yourpackage: INFO
file:
name: application-test.log
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
application-prod.yml
spring:
config:
activate:
on-profile: prod
logging:
level:
root: WARN
com.example.yourpackage: INFO
file:
path: /var/log/yourapp
name: application-prod.log
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} %thread %-5level %logger{36} - %msg%n"
啟動(dòng)應(yīng)用時(shí),可以通過(guò)命令行參數(shù)指定使用哪個(gè)配置文件:
java -jar -Dspring.profiles.active=prod yourapp.jar
3、日志文件路徑權(quán)限
確保 Spring Boot 應(yīng)用在服務(wù)器上有寫(xiě)日志文件的權(quán)限。你可以通過(guò)以下命令檢查和修改目錄權(quán)限:
# 檢查目錄權(quán)限 ls -ld /var/log/yourapp # 修改目錄權(quán)限 sudo chown -R youruser:yourgroup /var/log/yourapp sudo chmod -R 755 /var/log/yourapp
4、日志文件查看
啟動(dòng)應(yīng)用后,檢查日志文件是否正確生成并記錄了日志。你可以在服務(wù)器上使用以下命令查看日志文件:
# 查看日志文件 tail -f /var/log/yourapp/application-prod.log
5、使用自定義攔截器
如果你需要在日志中記錄特定的信息,例如 SQL 執(zhí)行時(shí)間,可以使用自定義攔截器。以下是一個(gè)示例攔截器:
SqlTimingInterceptor.java
package com.example.yourpackage.interceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.plugin.*;
import java.sql.Statement;
import java.util.Properties;
@Intercepts(@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}))
public class SqlTimingInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
long start = System.currentTimeMillis();
try {
return invocation.proceed();
} finally {
long end = System.currentTimeMillis();
long timeTaken = end - start;
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
String sql = (String) SystemMetaObject.forObject(statementHandler).getValue("delegate.boundSql.sql");
Log log = Slf4jImpl.create(this.getClass());
log.debug("SQL: " + sql);
log.debug("執(zhí)行時(shí)間: " + timeTaken + " ms");
}
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 可以設(shè)置一些自定義屬性
}
}
MyBatisConfig.java
package com.example.yourpackage.config;
import com.example.yourpackage.interceptor.SqlTimingInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@MapperScan("com.example.yourpackage.mapper")
public class MyBatisConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/yourdb");
dataSource.setUsername("yourusername");
dataSource.setPassword("yourpassword");
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
// 注冊(cè)攔截器
SqlTimingInterceptor sqlTimingInterceptor = new SqlTimingInterceptor();
Properties properties = new Properties();
properties.setProperty("someProperty", "someValue"); // 根據(jù)需要設(shè)置攔截器屬性
sqlTimingInterceptor.setProperties(properties);
factoryBean.setPlugins(new Interceptor[]{sqlTimingInterceptor});
return factoryBean.getObject();
}
}
到此這篇關(guān)于Spring Boot 日志 配置 SLF4J 和 Logback的文章就介紹到這了,更多相關(guān)Spring Boot 日志 配置 SLF4J 和 Logback內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring Boot 日志級(jí)別及配置詳解
- springboot中l(wèi)ogback日志配置的詳細(xì)說(shuō)明
- 一文帶你搞定SpringBoot Log4j2日志配置文件
- Spring?Boot整合log4j2日志配置的詳細(xì)教程
- SpringBoot日志配置全過(guò)程
- Spring?Boot日志打印配置詳細(xì)介紹
- Springboot日志配置的實(shí)現(xiàn)示例
- SpringBoot3配置Logback日志滾動(dòng)文件的方法
- 如何為?Spring?Boot?項(xiàng)目配置?Logback?日志
- Spring Boot配置日志的實(shí)現(xiàn)步驟
相關(guān)文章
Session過(guò)期后自動(dòng)跳轉(zhuǎn)到登錄頁(yè)面的實(shí)例代碼
這篇文章主要介紹了Session過(guò)期后自動(dòng)跳轉(zhuǎn)到登錄頁(yè)面實(shí)例代碼,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
java實(shí)現(xiàn)航班信息查詢管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)航班信息查詢管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
Spring BeanPostProcessor源碼示例解析
這篇文章主要為大家介紹了Spring BeanPostProcessor源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
java實(shí)現(xiàn)在性能測(cè)試中進(jìn)行業(yè)務(wù)驗(yàn)證實(shí)例
這篇文章主要為大家介紹了java實(shí)現(xiàn)在性能測(cè)試中進(jìn)行業(yè)務(wù)驗(yàn)證實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
java無(wú)鎖hashmap原理與實(shí)現(xiàn)詳解
本文主要介紹了java無(wú)鎖hashmap原理與實(shí)現(xiàn),大家參考使用吧2014-01-01
java對(duì)象與json對(duì)象之間互相轉(zhuǎn)換實(shí)現(xiàn)方法示例
這篇文章主要介紹了java對(duì)象與json對(duì)象之間互相轉(zhuǎn)換實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了java對(duì)象與json對(duì)象相互轉(zhuǎn)換實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-10-10
java中關(guān)于移位運(yùn)算符的demo與總結(jié)(推薦)
下面小編就為大家?guī)?lái)一篇java中關(guān)于移位運(yùn)算符的demo與總結(jié)(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05

