在做数据埋点时,我们应当充分利用前后端之间衔接的一些会话工具。比如cookie and session,后端有过滤器拦截器。那么这些原始带有的信息。即记录日志无需修改业务,全局控制。是能够很好地将日志业务进行结合,而同时能够全方位的记录业务的具体动向。那么借助session可以帮助我记录用户在连接状态,连接时长。那么ServletRequest当中一般也会包括一些用户的基本信息,ID以及IP等等。
而过滤器和拦截器当中,对于业务系统的发送方。我们应当尽量做的轻量化。避免在业务系统进行表关联,避免阻塞的业务接口调用,将所需信息进行充分记录。那么具体的日志处理系统可以进行表关联。
在日志系统当中,如果需要较为复杂的表关联或者更为快速的日志处理速度。我们可以将数据库里的信息预先加载到redis乃至内存当中。
对于SpringBoot,可以有基于AOP的日志拦截,代码如下:
@Around("pointcut()")
public Object sendLog(ProceedingJoinPoint joinPoint) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String ipAddress = getRemoteHost(request);
String url = request.getRequestURI();
String loginUserId = getAccountId(request.getHeader("userId"));
if (joinPoint.getArgs().length != 0) {
String reqParam = preFirstHandle(joinPoint);
log.info(url);
long begin = System.currentTimeMillis();
String[] uri = url.split("/");
String apiName = uri[2];
Object result = joinPoint.proceed();
LogVo logVo = new LogVo();
logVo.setIpAddress(ipAddress);
logVo.setOperationObject(apiName);
logVo.setNewValue(reqParam);
logVo.setUserId(loginUserId);
String respParam = postHandle(result);
logVo.setResponseBody(respParam);
KafkaTemplate.send(logTopic, JSON.toJSONString(logVo));
log.info("日志发送成功", logVo.toString());
return result;
} else {
Object result = joinPoint.proceed();
return result;
}
}