Spring boot2.0 实现日志集成的方法(3)
时间:2023-03-21 09:47:21|栏目:JAVA代码|点击: 次
前言
上一章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来实现。
栏 目:JAVA代码
下一篇:Java中DataInputStream和DataOutputStream的使用方法
本文标题:Spring boot2.0 实现日志集成的方法(3)
本文地址:http://www.codeinn.net/misctech/227803.html