统一日志格式

亦凉 2022-09-14 14:24 243阅读 0赞

1.日志对象

统一日志格式方便查看定位问题又方便统计收集。定义一个LogObject对象,里面定义日志的各个字段。例如:

  1. import com.fasterxml.jackson.annotation.JsonInclude;
  2. import com.fasterxml.jackson.annotation.JsonInclude.Include;
  3. import com.fasterxml.jackson.annotation.JsonProperty;
  4. public class LogObject {
  5. @JsonProperty(index = 1)
  6. private String eventName;//事件名称,一般就是业务方法名称
  7. @JsonProperty(index = 2)
  8. private String traceId; //调用链id,多个服务间传递此ID,可以通过traceId查询所有日志
  9. @JsonProperty(index = 3)
  10. private String msg; //消息内容
  11. @JsonProperty(index = 4)
  12. private long costTime; //接口响应时间
  13. @JsonProperty(index = 6)
  14. private Integer userId; //用户id
  15. @JsonProperty(index = 7)
  16. private Object others; //其他业务参数
  17. @JsonProperty(index = 8)
  18. private Object request; //接口请求入参
  19. @JsonProperty(index = 9)
  20. private Object response; //接口返回值
  21. public Integer getUserId() {
  22. return userId;
  23. }
  24. public LogObject setUserId(Integer userId) {
  25. this.userId = userId;
  26. return this;
  27. }
  28. public Object getRequest() {
  29. return request;
  30. }
  31. public LogObject setRequest(Object request) {
  32. this.request = request;
  33. return this;
  34. }
  35. //......

使用链式的风格,方便设置字段的值:

  1. long endTime = System.currentTimeMillis();
  2. LogObject logObject = new LogObject();
  3. logObject.setEventName(methodName)
  4. .setMsg(msg)
  5. .setTraceId(traceId)
  6. .setUserId(userId)
  7. .setRequest(orderReqDto)
  8. .setResponse(response)
  9. .setCostTime((endTime - beginTime));
  10. LOGGER.info(JSON.toJSONString(logObject));

2.实现方案

2.1.业务方法的 try-catch-finally中加入日志
  1. //示例代码
  2. public String sayHello(String name){
  3. long beginTime = System.currentTimeMillis();
  4. LogObject logObject = new LogObject();
  5. try {
  6. //业务逻辑代码
  7. logObject.setMsg("200");
  8. }catch (Exception e){
  9. logObject.setMsg("500");
  10. }finally {
  11. //统一日志收集代码
  12. logObject.setEventName("sayHello")
  13. .setTraceId("sayHello" + "_" + beginTime)
  14. .setUserId(userId)
  15. .setRequest("name:" + name)
  16. .setResponse("response")
  17. .setCostTime(System.currentTimeMillis() - beginTime);
  18. }
  19. return "hello_" + name;
  20. }
2.2.aop中拦截,但是会影响一点性能
  1. #1引入AOP依赖
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-aop</artifactId>
  5. </dependency>
  6. #2.添加AOP配置,监听环绕通知
  7. @Aspect
  8. @Component
  9. public class LogAspect {
  10. /**
  11. * 环绕通知需要携带ProceedingJoinPoint类型的参数
  12. * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法
  13. * @return
  14. */
  15. @Around("execution(* com.zypcy.first1.controller.*.*(..))")
  16. public Object aroundMethod(ProceedingJoinPoint pjp) {
  17. long beginTime = System.currentTimeMillis();
  18. ResponseData responseData = new ResponseData();
  19. LogObject logObject = new LogObject();
  20. Object result = null;
  21. String methodName = pjp.getSignature().getName();
  22. //执行目标方法
  23. try {
  24. //前置通知
  25. result = pjp.proceed();
  26. responseData.setSuccess(true).setCode(ResponseCodeEnum.SUCCESS).setData(result);
  27. } catch (Throwable e) {
  28. //异常通知
  29. responseData.setSuccess(false).setCode(ResponseCodeEnum.FAIL).setMsg(e.getMessage());
  30. }finally {
  31. logObject.setEventName(methodName)
  32. .setMsg(responseData.getCode())
  33. .setTraceId(methodName + "_" + beginTime)
  34. .setUserId(1)
  35. .setRequest(JSON.toJSONString(pjp.getArgs()))
  36. .setResponse(JSON.toJSONString(responseData))
  37. .setCostTime(System.currentTimeMillis() - beginTime);
  38. }
  39. //后置通知
  40. System.out.println("The method " + methodName + " exec ends , logObject : " + JSON.toJSONString(logObject));
  41. return result;
  42. }
  43. }

源码下载

发表评论

表情:
评论列表 (有 0 条评论,243人围观)

还没有评论,来说两句吧...

相关阅读

    相关 统一日志处理

    一、日志 1、什么是日志 大家在学习Java开发的过程中,都要接触日志功能,不管是在打印控制台中还是记录到文件,我们都需要使用日志功能,通过日志查看程序运行过程,运

    相关 统一日志格式

    1.日志对象 统一日志格式方便查看定位问题又方便统计收集。定义一个LogObject对象,里面定义日志的各个字段。例如: import com.fasterxm

    相关 统一json返回格式

    springmvc控制器接受到一个用户登录的请求, 要判断用户名密码是否为空, 还要去数据库检查密码是否正确。 然后以json的格式返回到前台, 前台再根据状态码来判断是允许登