Spring?boot2.0?實(shí)現(xiàn)日志集成的方法(3)
前言
上一章Spring boot2.0 實(shí)現(xiàn)日志集成的方法(2)主要講解了將日志信息根據(jù)類(lèi)別輸出到不同的文件中,實(shí)際開(kāi)發(fā)中我們需要通過(guò)日志來(lái)監(jiān)控用戶的操作行為、請(qǐng)求的耗時(shí)情況,針對(duì)耗時(shí)久的請(qǐng)求進(jìn)行性能分析,提升系統(tǒng)性能。
具體實(shí)現(xiàn)
采用的Spring Aop切面技術(shù)來(lái)實(shí)現(xiàn)控用戶的操作行為、請(qǐng)求的耗時(shí)情況。
定義日志注解
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation
{
// 模塊
String model() default "";
// 功能
String func() default "";
//描述
String desc() default "";
}定義日志切面
@Aspect
@Component
public class LogAspect
{
//請(qǐng)求監(jiān)控日志,輸出到不同日志文件
public static Log logger = LogManager.getLogger("request-access");
/**
* 定義切面
*/
@Pointcut("@annotation(com.test.aspect.LogAnnotation)")
private void logPoinCut()
{
}
/**
*
* @param joinPoint
*/
@Before(value = "logPoinCut()")
public void doBefore(JoinPoint joinPoint)
{
String requestId =TraceIdUtil.getTraceId();
logger.info("Start invoke requestID:[{}]",requestId);
}
@Around(value = "logPoinCut()")
public Object doAround(ProceedingJoinPoint jp) throws Throwable
{
String requestId =TraceIdUtil.getTraceId();
logger.info("Enter request start requestId :[{}]",requestId);
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
MethodSignature signature = (MethodSignature) jp.getSignature();
Method method = signature.getMethod();
long startTime= System.currentTimeMillis();
OperationLog operationLog = new OperationLog();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
if (logAnnotation != null)
{
String model = logAnnotation.model();
String func = logAnnotation.func();
String desc = logAnnotation.desc();
operationLog.setModel(model);
operationLog.setFunc(func);
operationLog.setDesc(desc);
}
String className = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
String uri = request.getRequestURI();
String ip = IpUtil.getIpAddr(request);
operationLog.setClassName(className);
operationLog.setMethodName(methodName);
operationLog.setIp(ip);
operationLog.setUri(uri);
StringBuilder param = new StringBuilder();
Object[] args = jp.getArgs();
Object arg = null;
for (int i = 0, j = args.length; i < j; i++)
{
arg = args[i];
param.append(" ")
.append(arg == null ? null : args[i].toString());
if (i != (j - 1))
{
param.append(",").append("\n");
}
}
operationLog.setParam(param.toString());
operationLog.setCreateDate(new Date());
long endTime=System.currentTimeMillis()-startTime;
//可以通過(guò)配置設(shè)置異常調(diào)用請(qǐng)求時(shí)間
long costTime=3;
operationLog.setCostTime(endTime);
String logStr = JSON.toJSONString(operationLog);
//將異常請(qǐng)求數(shù)據(jù)插入數(shù)據(jù)庫(kù)
if(endTime>costTime){
//saveOpetionLog(operationLog);
}
logger.info("invoke finish message:{}",logStr);
Object obj = jp.proceed();
return obj;
}
/**
* 方法之后調(diào)用
* @param joinPoint
* @param returnValue 方法返回值
*/
@AfterReturning(pointcut = "logPoinCut()")
public void doAfterReturning(JoinPoint joinPoint)
{
String requestId=TraceIdUtil.getTraceId();
logger.info("End invoke request ID [{}]",requestId);
}
}基本使用
@LogAnnotation(model="用戶管理",func="查詢用戶信息",desc="根據(jù)用戶名稱")
@GetMapping("getUserByName")
public Result getUserByName(@RequestParam String name)
{
logger.info("getUserByName paramter name:[{}]",name);
return Result.success(userService.getUserByName(name));
}輸出信息
{
"className": "com.test.controller.UserController",
"costTime": 19,
"createDate": "2022/03/11 15:20:30",
"createUser": "xx",
"ip": "172.18.188.111",
"methodName": "getUserByName",
"param": " zhangsan",
"uri": "/user/getUserByName",
"model":"用戶管理",
"func":"查詢用戶信息",
"desc":"根據(jù)用戶名稱",
"version": 0
}對(duì)于一些敏感的信息需要進(jìn)行加密處理。針對(duì)異常的請(qǐng)求進(jìn)行分析和性能優(yōu)化。
總結(jié)
上述日志信息雖然記錄的比較詳細(xì),但是缺少了請(qǐng)求的來(lái)源,尤其是跨服務(wù)之間的調(diào)用,則無(wú)法進(jìn)行追蹤。鏈路追蹤可以采用Spring Boot +logbck+MDC來(lái)實(shí)現(xiàn)。
到此這篇關(guān)于Spring boot2.0 實(shí)現(xiàn)日志集成的方法(3)的文章就介紹到這了,更多相關(guān)Spring boot 日志集成內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mybatisplus開(kāi)啟sql打印的三種方式匯總
這篇文章主要介紹了mybatisplus開(kāi)啟sql打印的三種方式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
Java后臺(tái)批量生產(chǎn)echarts圖表并保存圖片
這篇文章主要介紹了Java后臺(tái)批量生產(chǎn)echarts圖表并保存圖片,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Java使用dom4j實(shí)現(xiàn)對(duì)xml簡(jiǎn)單的增刪改查操作示例
這篇文章主要介紹了Java使用dom4j實(shí)現(xiàn)對(duì)xml簡(jiǎn)單的增刪改查操作,結(jié)合實(shí)例形式詳細(xì)分析了Java使用dom4j實(shí)現(xiàn)對(duì)xml簡(jiǎn)單的增刪改查基本操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2020-05-05
Java序列化框架Kryo高效轉(zhuǎn)換對(duì)象為字節(jié)流面試精講
這篇文章主要為大家介紹了Java序列化框架Kryo高效轉(zhuǎn)換對(duì)象為字節(jié)流面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
Red?Hat?安裝JDK與IntelliJ?IDEA的詳細(xì)過(guò)程
YUM是基于Red Hat的Linux發(fā)行版的一個(gè)強(qiáng)大而用戶友好的包管理工具,這篇文章主要介紹了Red?Hat安裝JDK與IntelliJ IDEA,需要的朋友可以參考下2023-08-08
Java設(shè)計(jì)模式之Iterator模式介紹
所謂Iterator模式,即是Iterator為不同的容器提供一個(gè)統(tǒng)一的訪問(wèn)方式。本文以java中的容器為例,模擬Iterator的原理。需要的朋友可以參考下2013-07-07
基于java配置nginx獲取真實(shí)IP代碼實(shí)例
這篇文章主要介紹了基于java配置nginx獲取真實(shí)IP代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Java連接MySQL數(shù)據(jù)庫(kù)命令行程序過(guò)程
SQL編程包括兩種形式,一種是過(guò)程化編程,主要通過(guò)數(shù)據(jù)庫(kù)交互式工具,通過(guò)存儲(chǔ)過(guò)程、觸發(fā)器、函數(shù)等形式的編程;另一種是嵌入式SQL編程,將SQL語(yǔ)句嵌入到高級(jí)開(kāi)發(fā)語(yǔ)言,完成數(shù)據(jù)的各種操作2021-10-10

