spring boot 之 結合aop整合日志

AOP

該切面僅用于請求日志記錄,若有其他需求,在此基礎上擴展即可,不多逼逼,直接上代碼。

引入切面依賴

<!-- 切面 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

日志切面類

import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;@Slf4j
@Aspect
@Component
public class RequestAop {private static final String START_TIME = "request-start";// 按需修改需要掃描的controller層@Pointcut("execution(* com.example.controller..*.*(..))")public void pointCut() {//該方法僅用于掃描controller包下類中的方法,而不做任何特殊的處理。}@Before("pointCut()")public void doBefore(JoinPoint joinPoint) {HttpServletRequest request =((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();Long start = System.currentTimeMillis();request.setAttribute(START_TIME, start);}@Around("pointCut()")@SneakyThrowspublic Object doAround(ProceedingJoinPoint joinPoint) {Object result = joinPoint.proceed();try {// 獲取方法名稱String method = joinPoint.getSignature().getName();// 獲取類名稱String className = joinPoint.getSignature().getDeclaringTypeName();// 獲取請求HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();// 請求路徑String requestUrl = request.getRequestURL().toString();// 獲取請求參數進行打印Signature signature = joinPoint.getSignature();// 參數名數組String[] parameterNames = ((MethodSignature) signature).getParameterNames();// 構造參數組集合List<Object> argList = new ArrayList<>();for (Object arg : joinPoint.getArgs()) {// request/response無法使用toJSONif (arg instanceof HttpServletRequest) {argList.add("request");} else if (arg instanceof HttpServletResponse) {argList.add("response");} else {argList.add(JSON.toJSON(arg));}}log.info("類名:[{}] 方法名:[{}] 請求URL:[{}] 請求參數:{} -> {} 請求結果:{}", className, method, requestUrl, JSON.toJSON(parameterNames), JSON.toJSON(argList), JSON.toJSON(result));} catch (Exception e) {log.error("切面類參數獲取失敗: {}", e.getMessage());}return result;}@After("pointCut()")public void doAfter(JoinPoint joinPoint) {HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();Long start = (Long) request.getAttribute(START_TIME);Long end = System.currentTimeMillis();// 耗時long costTime = end - start;// 方法名String method = joinPoint.getSignature().getName();log.info("方法名:[{}] 請求耗時:[{}ms]", method, costTime);}
}

日志

級別

日志級別(Log Levels)是指日志消息的優先級或者重要程度,它用于對日志的不同類型和重要程度進行分類和過濾。
不同的日志框架可能使用不同的命名和數量的日志級別,但基本概念是相似的。以下是常見的幾個標準日志級別:

1,TRACE(追蹤):最低級別的日志,包含詳細的調試信息,用于追蹤代碼的執行流程,如方法的輸入參數、內部狀態等。
2,DEBUG(調試):用于輸出調試信息,在開發和調試階段使用,幫助排查問題和跟蹤代碼執行情況以及驗證程序的行為。
3,INFO(信息):提供程序運行過程中的重要信息,用于向用戶提供一些關鍵的操作狀態和進度,如程序啟動關閉、配置項變更等。
4,WARN(警告):表示潛在的問題或異常情況,不會阻止程序繼續執行,但可能會影響程序的正常運行,需要開發人員注意。
5,ERROR(錯誤):表示錯誤情況,通常表示某個功能或步驟無法正常完成,但程序仍然可以繼續運行,需要開發人員關注和解決。
6,FATAL(致命):最高級別的日志,表示最嚴重的錯誤,表示程序無法繼續運行,會導致應用程序的中斷或崩潰,如系統崩潰。

特別說明:以上日志級別由上往下依次增強,而日志級別越高,控制臺打印出的日志信息就越少,但打印出的日志信息越重要。

引入lombok依賴

引入lombok后,在需要記錄日志的類上添加@Slf4j注解即可。

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.32</version><scope>provided</scope>
</dependency>

日志配置文件

resources下新建目錄logslogs下新建logback-spring.xml文件。
僅配置了常用的infoerror級別,其余按需配置即可。

<?xml version="1.0" encoding="utf-8"?>
<configuration><!-- 引入默認得配置文件 --><include resource="org/springframework/boot/logging/logback/defaults.xml"/><!-- 模塊名標識日志名稱 --><springProperty scope="context" name="springAppName" source="spring.application.name"/><!-- info日志單文件大小限制 --><springProperty scope="context" name="logback.fileInfoLog.maxFileSize" source="logback.fileInfoLog.maxFileSize" defaultValue="1024MB" /><!-- info日志最大保留時長單位天 --><springProperty scope="context" name="logback.fileInfoLog.maxHistory" source="logback.fileInfoLog.maxHistory" defaultValue="30" /><!-- info日志文件總大小,超過該大小,舊得即將刪除 --><springProperty scope="context" name="logback.fileInfoLog.totalSizeCap" source="logback.fileInfoLog.totalSizeCap" defaultValue="10GB" /><!-- error日志單文件大小限制 --><springProperty scope="context" name="logback.fileErrorLog.maxFileSize" source="logback.fileErrorLog.maxFileSize" defaultValue="1024MB" /><!-- error日志最大保留時長單位天 --><springProperty scope="context" name="logback.fileErrorLog.maxHistory" source="logback.fileErrorLog.maxHistory" defaultValue="30" /><!-- error日志文件總大小,超過該大小,舊得即將刪除 --><springProperty scope="context" name="logback.fileErrorLog.totalSizeCap" source="logback.fileErrorLog.totalSizeCap" defaultValue="10GB" /><!-- 日志目錄 --><springProperty scope="context" name="logback.rootDir" source="logback.rootDir" defaultValue="logs"/><!-- 控制臺輸出得日志格式 --><property name="CONSOLE_LOG_PATTERN"value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/><!-- 日志文件輸出得日志格式 --><property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %t [%c:%L]-%m%n"/><!-- 控制臺輸出 --><appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"><layout class="ch.qos.logback.classic.PatternLayout"><pattern>${CONSOLE_LOG_PATTERN}</pattern></layout></appender><!-- info日志得設定 --><appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>DENY</onMatch><onMismatch>ACCEPT</onMismatch></filter><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><file>${logback.rootDir}/${springAppName}.log</file><!--滾動策略--><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" ><!--路徑--><fileNamePattern>${logback.rootDir}/%d{yyyy-MM,aux}/%d{yyyy-MM-dd,aux}/${springAppName}-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern><maxFileSize>${logback.fileInfoLog.maxFileSize}</maxFileSize><maxHistory>${logback.fileInfoLog.maxHistory}</maxHistory><totalSizeCap>${logback.fileInfoLog.totalSizeCap}</totalSizeCap><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy></appender><!-- 錯誤日志 --><appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>ERROR</level></filter><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><file>${logback.rootDir}/${springAppName}-error.log</file><!--滾動策略--><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" ><!--路徑--><fileNamePattern>${logback.rootDir}/%d{yyyy-MM,aux}/%d{yyyy-MM-dd,aux}/${springAppName}-error-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern><maxFileSize>${logback.fileErrorLog.maxFileSize}</maxFileSize><maxHistory>${logback.fileErrorLog.maxHistory}</maxHistory><totalSizeCap>${logback.fileErrorLog.totalSizeCap}</totalSizeCap><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy></appender><appender name="ASYNC_consoleLog" class="ch.qos.logback.classic.AsyncAppender"><appender-ref ref="consoleLog"/></appender><appender name="ASYNC_fileInfoLog" class="ch.qos.logback.classic.AsyncAppender"><appender-ref ref="fileInfoLog"/></appender><appender name="ASYNC_fileErrorLog" class="ch.qos.logback.classic.AsyncAppender"><appender-ref ref="fileErrorLog"/></appender><root level="info"><appender-ref ref="ASYNC_consoleLog" /><appender-ref ref="ASYNC_fileInfoLog" /><appender-ref ref="ASYNC_fileErrorLog" /></root></configuration>

application.yml配置

# spring.application.name 必須配置
# 因為上述日志配置文件指定了項目啟動后輸出的日志文件命名,即為該配置
spring:application:name: LogApplicationlogging:
# 指定自定義的配置文件config: classpath:logs/logback-spring.xml
# 指定輸出的日志級別
# trace < debug < info < warn < error
# 例如:指定輸出級別為info,則trace和debug均不會輸出level:root: info #該方式指定的是整個項目的日志輸出級別# com.example.controller: debug #也可以指定具體某個包下的日志輸出級別

結果展示

在這里插入圖片描述
以上述配置為例,項目啟動后會在項目下生成logs目錄,該目錄下會有兩個日志文件:LogApplication.logLogApplication-error.log,項目中所有log.error()日志都會輸出到LogApplication-error.log,其余日志則輸出到LogApplication.log.

拓展

將指定的類產生的日志輸出到指定的文件中。
示例:RequestAop切面中產生的是所有的請求記錄,將該類的日志放入指定的文件。

logback-spring.xml新增配置,未添加請求日志文件的大小限制、存放時間等配置,若有需求,按infoerror配置仿寫即可。

    <!-- 接口請求日志 --><appender name="requestLog" class="ch.qos.logback.core.rolling.RollingFileAppender"><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>DENY</onMatch><onMismatch>ACCEPT</onMismatch></filter><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><!--此處配置輸出文件名稱為 應用名-request.log --><file>${logback.rootDir}/${springAppName}-request.log</file><!--滾動策略--><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" ><!--路徑--><fileNamePattern>${logback.rootDir}/%d{yyyy-MM,aux}/%d{yyyy-MM-dd,aux}/${springAppName}-request-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern><maxFileSize>${logback.fileInfoLog.maxFileSize}</maxFileSize><maxHistory>${logback.fileInfoLog.maxHistory}</maxHistory><totalSizeCap>${logback.fileInfoLog.totalSizeCap}</totalSizeCap><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy></appender><appender name="ASYNC_requestLog" class="ch.qos.logback.classic.AsyncAppender"><appender-ref ref="requestLog"/></appender><!--將切面類所在包的位置配置上--><logger name="com.example.aop.RequestAop" additivity="false" level="INFO"><appender-ref ref="ASYNC_requestLog"/></logger>

在這里插入圖片描述
以上述配置為例,項目啟動后會在項目下生成logs目錄,該目錄下會有三個日志文件:LogApplication.logLogApplication-error.logLogApplication-request.log,項目中所有log.error()日志都會輸出到LogApplication-error.logRequestAop切面類的日志會輸出到LogApplication-request.log,其余日志則輸出到LogApplication.log.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/17264.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/17264.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/17264.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C++】set與map

目錄 一、鍵值對 二、set 1. set的模板參數列表 2. set的構造 3. set的迭代器 4. set的容量 5. set的修改 6. set的查找 三、map 1. map的模板參數列表 2. map的構造 3. map的迭代器 4. map的容量 5. map的修改 6. map的查找 一、鍵值對 用來表示具有一一對應關…

SARscape5.7已經支持3米陸探一號(LT-1)數據處理

SARsacpe5.6.2.1版本已經開始支持LT-1的數據處理&#xff0c;由于當時只獲取了12米的條帶模式2&#xff08;STRIP2&#xff09;例子數據&#xff0c;對3米條帶模式1&#xff08;STRIP1&#xff09;數據的InSAR處理軌道誤差挺大&#xff0c;可能會造成干涉圖異常。 SARsacpe5.7最…

三十篇:動脈脈搏:企業業務處理系統的生命力

動脈脈搏&#xff1a;企業業務處理系統的生命力 1. 引言 在數字經濟的浪潮下&#xff0c;企業之間的競爭已不僅僅是產品和服務的競爭&#xff0c;更是信息處理能力的競爭。業務處理系統&#xff08;Transaction Processing System, TPS&#xff09;是企業信息系統架構的基礎&a…

Python3 筆記:Python之禪

打開Python Shell&#xff0c;輸入import this&#xff0c;按回車鍵運行程序。 Beautiful is better than ugly. 優雅勝于丑陋。 Explicit is better than implicit. 明確勝于含糊。 Simple is better than complex. 簡單勝于復雜。

圖形學初識--紋理采樣和Wrap方式

文章目錄 前言正文1、為什么需要紋理采樣&#xff1f;2、什么是紋理采樣&#xff1f;3、如何進行紋理采樣&#xff1f;&#xff08;1&#xff09;假設繪制區域為矩形&#xff08;2&#xff09;假設繪制區域為三角形 4、什么是紋理的Wrap方式&#xff1f;5、有哪些紋理的Wrap方式…

洪師傅代駕系統開發 支持公眾號H5小程序APP 后端Java源碼

代駕流程圖 業務流程圖 管理端設置 1、首頁裝修 2、師傅獎勵配置 師傅注冊后,可享受后臺設置的新師傅可得的額外獎勵; 例:A注冊了師傅,新人獎勵可享受3天,第一天的第一筆訂單完成后可得正常傭金傭金*獎勵比例 完成第二筆/第三筆后依次可得正常傭金傭金*獎勵比例 完成的第四…

牛客NC166 連續子數組的最大和(二)【中等 前綴和數組+動態規劃 Java/Go/PHP/C++】

題目 題目鏈接&#xff1a; https://www.nowcoder.com/practice/11662ff51a714bbd8de809a89c481e21 思路 前綴和數組動態規劃Java代碼 import java.util.*;public class Solution {/*** 代碼中的類名、方法名、參數名已經指定&#xff0c;請勿修改&#xff0c;直接返回方法規…

小短片創作-優化場景并輸出短片(二)

1、什么是潮濕感 什么是潮濕感&#xff1a;基礎顏色變化粗糙度變化表面滲入性 1.基礎顏色變化&#xff1a;潮濕的地方顏色會變深 2.粗糙度變化&#xff1a;鏡面粗糙度為0&#xff0c;潮濕的地方粗糙度會變低 3.表面滲入性&#xff1a;主要看材質是否防水 2、調整場景材質增…

小抄 20240526

1 一些人焦慮的原因&#xff0c;可能是他也知道自己做的事無意義&#xff0c;但是又停不下來&#xff0c;于是一直在做無用功&#xff0c;空耗精神力量。 可以試著去做一些熱愛的、有價值的事情&#xff0c;焦慮就會慢慢消失。 2 人們看歷史的時候&#xff0c;很容易把自己代…

士大夫v產生的

一、前言 亂碼七糟 [lun qī bā zāo]&#xff0c;我時常懷疑這個成語是來形容程序猿的&#xff01; 無論承接什么樣的需求&#xff0c;是不是身邊總有那么幾個人代碼寫的爛&#xff0c;但是卻時常有測試小姐姐過來聊天(_求改bug_)、有產品小伙伴送吃的(_求寫需求_)、有業務小…

Java 寫入 influxdb

利用Python隨機生成一個1000行的csv文件 import csv import random from datetime import datetime, timedelta from random import randint, choice# 定義監控對象列表和指標名稱列表 monitor_objects [Server1, Server2, Server3, DB1] metric_names [CPUUsage, MemoryUsa…

網絡編程 —— Http進度條

第一種下載帶進度的方法 string url "https://nodejs.org/dist/v20.10.0/node-v20.10.0-x64.msi"; 1使用getASync獲取服務器響應數據 參數1請求的路徑&#xff0c; 參數2 HttpCompletionOption.ResponseHeadersRead 請求完成時候等待請求帶什么程度才…

耐高溫輸送帶的優勢

耐高溫輸送帶&#xff1a;工業運輸的革命性升級&#xff0c;助力生產線高效穩定運行 在現代化工業生產的浪潮中&#xff0c;耐高溫輸送帶以其獨特的優勢&#xff0c;正逐漸成為工業運輸領域的得力助手。它不僅能夠有效提升生產效率&#xff0c;更能確保生產線的安全穩定運行&a…

算法隨想錄第二十天打卡|654.最大二叉樹 , 617.合并二叉樹 ,700.二叉搜索樹中的搜索 , 98.驗證二叉搜索樹

654.最大二叉樹 又是構造二叉樹&#xff0c;昨天大家剛剛做完 中序后序確定二叉樹&#xff0c;今天做這個 應該會容易一些&#xff0c; 先看視頻&#xff0c;好好體會一下 為什么構造二叉樹都是 前序遍歷 題目鏈接/文章講解&#xff1a;代碼隨想錄 視頻講解&#xff1a;又是構…

「動態規劃」打家劫舍

力扣原題鏈接&#xff0c;點擊跳轉。 有一個小偷&#xff0c;要偷東西。假設有n個房間&#xff0c;每個房間都有現金&#xff0c;下標為i的房間內的現金數是nums[i]。不能同時偷相鄰的2個房間&#xff0c;其中第一個房間和最后一個房間是相鄰的。那么這個小偷最多能偷到多少現…

YOLOv8+PyQt5鳥類檢測系統完整資源集合(yolov8模型,從圖像、視頻和攝像頭三種路徑識別檢測,包含登陸頁面、注冊頁面和檢測頁面)

資源包含可視化的鳥類檢測系統&#xff0c;基于最新的YOLOv8訓練的鳥類檢測模型&#xff0c;和基于PyQt5制作的可視化鳥類檢測系統&#xff0c;包含登陸頁面、注冊頁面和檢測頁面&#xff0c;該系統可自動檢測和識別圖片或視頻當中出現的各種鳥類&#xff0c;以及自動開啟攝像頭…

Linux漢化Jupyter Notebook

要在Linux系統中使Jupyter Notebook漢化&#xff0c;可以通過安裝jupyterlab-language-pack-zh-CN擴展來實現。以下是具體步驟和示例代碼&#xff1a; 打開終端。 執行以下命令以安裝Jupyter Notebook的中文語言包&#xff1a; pip install jupyterlab-language-pack-zh-CN …

【CSharp】將ushort數組保存為1通道位深16bit的Tiff圖片

【CSharp】將ushort數組保存為1通道位深16bit的Tiff圖片 1.背景2.接口 1.背景 System.Drawing.Common 是一個用于圖像處理和圖形操作的庫&#xff0c;它是 System.Drawing 命名空間的一部分。由于 .NET Core 和 .NET 5 的跨平臺特性&#xff0c;許多以前內置于 .NET Framework…

基于Fluent和深度學習算法驅動的流體力學計算與應用

“基于Fluent和深度學習算法驅動的流體力學計算與應用”專題大綱 目錄 主要內容 機器學習與流體力學入門 一、流體力學基礎理論與編程實戰1、流體力學的發展概述 2、不可壓縮流體力學的基本方程 3、湍流理論與湍流模型簡介 4、傅里葉變換和流體的尺度分析 5、偽譜法求解不可壓…

Vue小程序項目知識積累(二)

1.wx.reLaunch(Object object) 關閉所有頁面&#xff0c;打開到應用內的某個頁面。 wx.reLaunch({url:/pages/positons/index}) 參數說明&#xff1a; 屬性類型默認值必填說明urlstring是需要跳轉的應用內頁面路徑 (代碼包路徑)&#xff0c;路徑后可以帶參數。參數與路徑之…