Spring boot2.0 实现日志集成的方法(3)
前言
上一章Spring boot2.0 实现日志集成的方法(2)主要讲解了将日志信息根据类别输出到不同的文件中,实际开发中我们需要通过日志来监控用户的操作行为、请求的耗时情况,针对耗时久的请求进行性能分析,提升系统性能。
具体实现
采用的Spring Aop切面技术来实现控用户的操作行为、请求的耗时情况。
定义日志注解
@Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LogAnnotation { // 模块 String model() default ""; // 功能 String func() default ""; //描述 String desc() default ""; }
定义日志切面
@Aspect @Component public class LogAspect { //请求监控日志,输出到不同日志文件 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; //可以通过配置设置异常调用请求时间 long costTime=3; operationLog.setCostTime(endTime); String logStr = JSON.toJSONString(operationLog); //将异常请求数据插入数据库 if(endTime>costTime){ //saveOpetionLog(operationLog); } logger.info("invoke finish message:{}",logStr); Object obj = jp.proceed(); return obj; } /** * 方法之后调用 * @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="根据用户名称") @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":"根据用户名称", "version": 0 }
对于一些敏感的信息需要进行加密处理。针对异常的请求进行分析和性能优化。
总结
上述日志信息虽然记录的比较详细,但是缺少了请求的来源,尤其是跨服务之间的调用,则无法进行追踪。链路追踪可以采用Spring Boot +logbck+MDC来实现。
到此这篇关于Spring boot2.0 实现日志集成的方法(3)的文章就介绍到这了,更多相关Spring boot 日志集成内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
解决子线程无法访问父线程中通过ThreadLocal设置的变量问题
这篇文章主要介绍了解决子线程无法访问父线程中通过ThreadLocal设置的变量问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-07-07SpringBoot监听Nacos动态修改日志级别的操作方法
线上系统的日志级别一般都是 INFO 级别,有时候需要查看 WARN 级别的日志,所以需要动态修改日志级别,微服务项目中使用 Nacos 作为注册中心,我们可以监听 Nacos 配置,修改日志级别,这篇文章主要介绍了SpringBoot监听Nacos动态修改日志级别的操作方法,需要的朋友可以参考下2023-12-12Java线程池队列PriorityBlockingQueue原理分析
这篇文章主要介绍了Java线程池队列PriorityBlockingQueue原理分析,PriorityBlockingQueue队列是 JDK1.5 的时候出来的一个阻塞队列,但是该队列入队的时候是不会阻塞的,永远会加到队尾,需要的朋友可以参考下2023-12-12
最新评论