参考csdn原文博客:https://blog.csdn.net/qq_32495261/article/details/108489712
自定义注解实现记录请求日志
- 在annotation包下新建 注解 ControllerEndpoint
/**
* 自定义注解,用于标注在controller的方法上,异步记录日志
* create by xiaopan
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ControllerEndpoint {
String operation() default "";
String exceptionMessage() default "系统内部异常";
}
- 编写切面类,在aspect 包下新建类 ControllerEndpointAspect
/**
* 系统日志切面
*
* @author xiaopan
*/
@Slf4j
@Aspect//标注为一个切面类
@Component
public class ControllerEndpointAspect extends AspectSupport {
private Log sysLog = new Log();
private long startTime;
@Autowired
private LogService logService;
//定义切入点为用了@ControllerEndpoint 的类
@Pointcut("@annotation(com.coderman.common.annotation.ControllerEndpoint)")
public void pointcut() {
}
/**
* 环绕通知
*
* @param joinPoint
*/
@Around("pointcut()")
public Object saveSysLog(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
//开始时间
startTime = System.currentTimeMillis();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
//获取注解
ControllerEndpoint controllerEndpoint = method.getAnnotation(ControllerEndpoint.class);
if (controllerEndpoint != null) {
String operation = controllerEndpoint.operation();
//注解上的操作描述
sysLog.setOperation(operation);
}
//请求的参数
Object[] args = joinPoint.getArgs();
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
sysLog.setParams("paramName:" + Arrays.toString(paramNames) + ",args:" + Arrays.toString(args));
//请求的IP
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ipAddr = IPUtil.getIpAddr(request);
sysLog.setIp(ipAddr);
//地理位置
sysLog.setLocation(AddressUtil.getCityInfo(ipAddr));
//操作人
ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
sysLog.setUsername(activeUser.getUser().getUsername());
//添加时间
sysLog.setCreateTime(new Date());
//执行目标方法
result = joinPoint.proceed();
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()\n"
+ "\nresponse:" + postHandle(result));
//执行耗时
sysLog.setTime(System.currentTimeMillis() - startTime);
//保存系统日志
logService.saveLog(sysLog);
//打印请求的url
log.info("请求的URL: {}", request.getRequestURL().toString());
//打印操作描述信息
log.info("操作描述: {}", controllerEndpoint.operation());
return result;
}
/**
* 返回数据
*
* @param retVal
* @return
*/
private String postHandle(Object retVal) {
if (null == retVal) {
return "";
}
return JSON.toJSONString(retVal);
}
}
- 数据库对应的实体类
@Data
@Table(name = "tb_log")
public class Log {
@Id
private Long id;
private String username;
private Long time;
private String ip;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private String location;
private String operation;
private String method;
private String params;
}
- 在controller使用
/**
* 添加用户
* @return
*/
@ControllerEndpoint(exceptionMessage = "添加用户失败", operation = "添加用户")
@PostMapping("/add")
public ResponseBean add(@RequestBody @Validated User user) throws BusinessException {
return ResponseBean.success();
}