Springboot 利用AOP编程实现切面日志
生活随笔
收集整理的這篇文章主要介紹了
Springboot 利用AOP编程实现切面日志
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言
踏入Springboot這個坑,你就別想再跳出來。這個自動配置確實是非常地舒服,幫助我們減少了很多的工作。使得編寫業(yè)務代碼的時間占比相對更大。那么這里就講一下面向切面的日志收集。筆者使用lombok插件,這也是一款非常不錯的插件,需要在pom引入依賴。
導入依賴
<!-- apo --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
創(chuàng)建日志對象
@Data@NoArgsConstructor@Accessors(chain = true)public class SysOperLog {/*** 日志主鍵*/private Long id;/*** 接口名稱*/private String title;/*** 操作名稱*/private String operName;/*** 接口類名稱*/private String className;/*** 操作人員*/private String operUser;/*** 請求URL*/private String operUrl;/*** 請求方式*/private String requestMethod;/*** 主機地址*/private String operIp;/*** 源端口*/private Integer operPort;/*** 操作地點*/private String operLocation;/*** 請求參數(shù)*/private String operParam;/*** 返回參數(shù)*/private String jsonResult;/*** 操作狀態(tài)(0正常 1異常)*/private Boolean status;/*** 錯誤消息*/private String errorMsg;/*** 操作時間*/private Date operTime;}
具體實現(xiàn)代碼
@Aspect
@Component
public class LogAdvice {@Resourceprivate SysOperLogService sysOperLogService;// 定義切面private static final String POINT_CUT = "execution(* cn.example.project.controller.*.*(..))";@Pointcut(POINT_CUT)public void controllerAspect() {}private void handler(JoinPoint joinPoint, Object result, Exception e) {// 獲得requestHttpServletRequest request = ((ServletRequestAttributes) (Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))).getRequest();// 獲得接口所屬模塊Class<?> cls = joinPoint.getSignature().getDeclaringType();Api annotation = AnnotationUtils.findAnnotation(cls, Api.class);String title = "遺失的接口標題";if (annotation != null) {title = annotation.tags()[0];}// 獲得接口名稱Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();String operName = method.getAnnotation(ApiOperation.class).value();// 獲得接口所在類String className = joinPoint.getSignature().getDeclaringTypeName();className = className.substring(className.lastIndexOf(".") + 1);// 獲得請求用戶String loginName = request.getHeader("token");loginName = Pattern.compile("^Bearer ").matcher(loginName).replaceFirst("");// 獲得請求urlString requestURI = request.getRequestURI();// 獲得請求方法String requestMethod = request.getMethod();// 獲得請求IPString requestIp = IPUtils.getIpAddr(request);// 獲得請求參數(shù): 連接在url后面的參數(shù)String params = getParamsString(joinPoint, request);// 獲得源端口int requestPort = request.getRemotePort();// 日志請求是否正常boolean status = e == null;// 封裝操作日志SysOperLog sysOperLog = new SysOperLog();sysOperLog.setTitle(title).setOperName(operName).setClassName(className).setOperUser(loginName).setOperUrl(requestURI).setRequestMethod(requestMethod).setOperIp(requestIp).setOperPort(requestPort).setOperLocation(IPUtils.getLocation(requestIp)).setOperParam(params).setStatus(status).setErrorMsg(status ? null : e.getMessage()).setOperTime(new Date());// 保存sysOperLogService.add(sysOperLog);}private String getParamsString(JoinPoint joinPoint, HttpServletRequest request) {StringBuilder params = new StringBuilder();// 獲得請求體參數(shù)if (Pattern.compile("post|put|patch", Pattern.CASE_INSENSITIVE).matcher(request.getMethod()).find()) {Object[] args = joinPoint.getArgs();for (Object o: args) {String string = JSON.toJSONString(o);params.append(string);}}// 獲得queryStringif (StringUtils.isNotBlank(request.getQueryString())) {params.append(request.getQueryString());}return params.toString();}// 返回之后的處理@AfterReturning(value = "controllerAspect()", returning = "returnResult")public void afterReturning(JoinPoint joinPoint, Object returnResult) {handler(joinPoint, returnResult, null);}// 拋出異常的處理@AfterThrowing(value = "controllerAspect()", throwing = "e")public void afterThrowing(JoinPoint joinPoint, Exception e) {handler(joinPoint, null, e);}}
其中的參數(shù)獲得,是獲得url后面的和請求體的。如果使用restful接口,直接作為url一部分的需要根據(jù)自己的業(yè)務去匹配。日志也添加了接口描述,這個描述來源于swagger注解。
具體結果:
獲得的還有些信息,并未一一渲染到頁面,原因是頁面撐不下了啊。
注意: 其中的獲得ip歸屬地,需要自己去獲得,通過httpclient請求ip查詢接口。幾個好用的ip查詢接口見另一篇博客:分享2020 幾個好用的ip地址歸屬地查詢
總結
以上是生活随笔為你收集整理的Springboot 利用AOP编程实现切面日志的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享2020 几个好用的ip地址归属地查
- 下一篇: 经常使用的npm命令