统一日志格式方便查看定位问题又方便统计收集。定义一个LogObject对象,里面定义日志的各个字段。例如:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
public class LogObject {
@JsonProperty(index = 1)
private String eventName;//事件名称,一般就是业务方法名称
@JsonProperty(index = 2)
private String traceId; //调用链id,多个服务间传递此ID,可以通过traceId查询所有日志
@JsonProperty(index = 3)
private String msg; //消息内容
@JsonProperty(index = 4)
private long costTime; //接口响应时间
@JsonProperty(index = 6)
private Integer userId; //用户id
@JsonProperty(index = 7)
private Object others; //其他业务参数
@JsonProperty(index = 8)
private Object request; //接口请求入参
@JsonProperty(index = 9)
private Object response; //接口返回值
public Integer getUserId() {
return userId;
}
public LogObject setUserId(Integer userId) {
this.userId = userId;
return this;
}
public Object getRequest() {
return request;
}
public LogObject setRequest(Object request) {
this.request = request;
return this;
}
//......
使用链式的风格,方便设置字段的值:
long endTime = System.currentTimeMillis();
LogObject logObject = new LogObject();
logObject.setEventName(methodName)
.setMsg(msg)
.setTraceId(traceId)
.setUserId(userId)
.setRequest(orderReqDto)
.setResponse(response)
.setCostTime((endTime - beginTime));
LOGGER.info(JSON.toJSonString(logObject));
2.实现方案
2.1.业务方法的 try-catch-finally中加入日志
//示例代码
public String sayHello(String name){
long beginTime = System.currentTimeMillis();
LogObject logObject = new LogObject();
try {
//业务逻辑代码
logObject.setMsg("200");
}catch (Exception e){
logObject.setMsg("500");
}finally {
//统一日志收集代码
logObject.setEventName("sayHello")
.setTraceId("sayHello" + "_" + beginTime)
.setUserId(userId)
.setRequest("name:" + name)
.setResponse("response")
.setCostTime(System.currentTimeMillis() - beginTime);
}
return "hello_" + name;
}
2.2.aop中拦截,但是会影响一点性能
#1引入AOP依赖#2.添加AOP配置,监听环绕通知 @Aspect @Component public class LogAspect { @Around("execution(* com.zypcy.first1.controller.*.*(..))") public Object aroundMethod(ProceedingJoinPoint pjp) { long beginTime = System.currentTimeMillis(); ResponseData responseData = new ResponseData(); LogObject logObject = new LogObject(); Object result = null; String methodName = pjp.getSignature().getName(); //执行目标方法 try { //前置通知 result = pjp.proceed(); responseData.setSuccess(true).setCode(ResponseCodeEnum.SUCCESS).setData(result); } catch (Throwable e) { //异常通知 responseData.setSuccess(false).setCode(ResponseCodeEnum.FAIL).setMsg(e.getMessage()); }finally { logObject.setEventName(methodName) .setMsg(responseData.getCode()) .setTraceId(methodName + "_" + beginTime) .setUserId(1) .setRequest(JSON.toJSonString(pjp.getArgs())) .setResponse(JSON.toJSonString(responseData)) .setCostTime(System.currentTimeMillis() - beginTime); } //后置通知 System.out.println("The method " + methodName + " exec ends , logObject : " + JSON.toJSonString(logObject)); return result; } } org.springframework.boot spring-boot-starter-aop
源码下载



