当前位置 博文首页 > 无限迭代中......:Spring Boot——基于AOP的HTTP操作日志解决方
package com.hailiu.web.aop;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hailiu.model.Log;
import com.hailiu.security.user.AuthenticationUser;
import com.hailiu.service.ILogService;
import com.hailiu.web.bean.ResponseBean;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* AOP记录用户操作日志
*
* @author ShenTuZhiGang
* @version 1.0.0
* @date 2021-03-21 18:34
*/
@Aspect
@Component
public class WebLogAspect {
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(WebLogAspect.class);
private final ObjectMapper objectMapper;
private final ILogService iLogService;
public WebLogAspect(ObjectMapper objectMapper, ILogService iLogService) {
this.objectMapper = objectMapper;
this.iLogService = iLogService;
}
/**
* Controller层切点
*/
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void controllerAspect(){
}
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) {
logger.info("before");
}
@Around("controllerAspect()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Signature signature = pjp.getSignature();
Log log = new Log();
log.setHttpMethod(request.getMethod());
log.setHttpUri(request.getRequestURI());
log.setHttpUserAgent(request.getHeader("User-Agent"));
log.setHttpRemoteHost(request.getRemoteHost());
log.setClassName(signature.getDeclaringTypeName());
log.setMethodName(signature.getName());
// 处理请求参数
StringBuilder params = new StringBuilder();
String[] paramNames = ((MethodSignature) signature).getParameterNames();
Object[] paramValues = pjp.getArgs();
int paramLength = null == paramNames ? 0 : paramNames.length;
if (paramLength == 0) {
log.setHttpParams("{}");
} else {
params.append("[");
for (int i = 0; i < paramLength ; i++) {
if(i > 0){
params.append(",");
}
params.append(paramNames[i]).append("=")
.append(objectMapper.writeValueAsString(paramValues[i]));
}
params.append("]");
}
log.setHttpParams(params.toString());
log.setOperator(-1);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
AuthenticationUser user = (AuthenticationUser) authentication.getPrincipal();
if(user != null){
log.setOperator(user.getId());
}
}
log.setOperationName("普通操作");
Long start = System.currentTimeMillis();
try{
logger.info("before around");
Object o = pjp.proceed();
logger.info("after around");
if(o instanceof ResponseBean){
ResponseBean<?> response = (ResponseBean<?>) o;
log.setStatus(response.getStatus());
log.setMsg(response.getMsg());
log.setIsFail(response.getStatus() != 200);
}else{
log.setIsFail(false);
}
log.setIsError(false);
return o;
}catch (Exception e){
log.setStatus(500);
log.setMsg("内部错误");
log.setIsFail(true);
log.setIsError(true);
//return ResponseBean.error("内部错误");
throw e;
}finally {
Long end = System.currentTimeMillis();
log.setExecuteTime((int) (end - start));
iLogService.save(log);
}
}
@After("controllerAspect()")
public void doAfter(JoinPoint joinPoint){
logger.info("after");
}
@AfterThrowing(pointcut = "controllerAspect()",throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint,Throwable e){
logger.info("after throwing");
}
@AfterReturning(pointcut = "controllerAspect()",returning = "response")
public void doAfterReturning(JoinPoint joinPoint, ResponseBean<?> response){
logger.info("after returning");
}
}
springboot + AOP 日志
springboot项目使用切面记录用户操作日志
Spring Boot启用http请求日志记录(访问日志)
cs