spring 切片操作日志实现
spring 切片操作日志实现
-
依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> -
代码实现
package com.chaoyang.model; import lombok.Data; import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper=false) public class WebLog { /** * 操作描述 */ private String description; /** * 操作用户 */ private String username; /** * 消耗时间 */ private Integer spendTime; /** * 根路径 */ private String basePath; /** * URI */ private String uri; /** * URL */ private String url; /** * 请求类型 */ private String method; /** * IP地址 */ private String ip; /** * 请求参数 */ private Object parameter; /** * 返回结果 */ private Object result; }package com.chaoyang.aspect; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.URLUtil; import com.alibaba.fastjson.JSON; import com.chaoyang.model.WebLog; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.annotation.Order; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.HashMap; @Slf4j @Component @Aspect @Order(1) public class WebLogAspect { /** * 定义一个切入点 */ @Pointcut("execution(* com.chaoyang.controller.*.*(..))") public void webLog(){ } /** * 环绕通知 */ @Around("webLog()") public Object recordWebLog(ProceedingJoinPoint joinPoint) throws Throwable { Object result = null; WebLog webLog = new WebLog(); //接口请求时间 long start = System.currentTimeMillis(); //这个地方将全局的异常抛出去不然web层的全局异常就捕获不了了 result = joinPoint.proceed(joinPoint.getArgs()); //结束时间 long endTime = System.currentTimeMillis(); webLog.setSpendTime((int) (start - endTime) / 1000); //获取当前请求的request对象 ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); webLog.setUri(request.getRequestURI()); String url = request.getRequestURL().toString(); webLog.setUrl(url); webLog.setBasePath(StrUtil.removeSuffix(url, URLUtil.url(url).getPath())); //获取安全的上下文 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); webLog.setUsername(authentication == null ? "匿名用户" : authentication.getPrincipal().toString()); webLog.setIp(request.getRemoteAddr()); //todo //方法签名 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); //获取类的名称 String name = joinPoint.getTarget().getClass().getName(); ApiOperation annotation = method.getAnnotation(ApiOperation.class); webLog.setDescription(annotation == null ? "no desc" : annotation.value()); webLog.setMethod(name + "." + method.getName()); //这个地方方法参数做成k<->v的形式 webLog.setParameter(getParam(method, joinPoint.getArgs())); webLog.setResult(result); log.info(JSON.toJSONString(webLog)); return result; } private Object getParam(Method method, Object[] args) { HashMap<String, Object> map = new HashMap<>(); LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer(); //方法的新参名称 String[] parameterNames = discoverer.getParameterNames(method); if (parameterNames != null && parameterNames.length > 0) { for (int i = 0; i < parameterNames.length; i++) { map.put(parameterNames[i], args[i]); } } return map; } }

浙公网安备 33010602011771号