基于aop的日志记录方式实现
作者:互联网
说明
最近有个项目需要增加日志记录功能,因为这个项目原来是基于spring开发的,在查阅了相关资料以后,我采用了spring aop的方式实现该需求,然后就有了本篇文章。
思路
我这边需求是这样的:要统计各个接口的调用次数,然后我想加上客户端ip、请求参数、返回结果等信息,而我的接口都是通过controller实现的,所以从原理上讲就是要通过aop拦截所有controller,实现日志记录。项目本身用到了swagger,每个接口都有ApiOperation注解,所以我的实现方式就变成了拦截ApiOperation注解,为什么要拦截ApiOperation,因为ApiOperation注解有对每个接口的描述信息,当然也是因为每个接口方法上都有ApiOperation注解,当然如果你愿意你也可以拦截RequestMapping,下面是我的aop实现:
package com.mytest.aop;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @program: publicCoreServer
* @description: aop 打印 接收参数日志
* @author: liu yan
* @create: 2019-11-21 09:15
*/
@Aspect
@Component//定义一个切面
public class LogRecordAspect {
private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
private static final String UTF_8 = "utf-8";
@Autowired
private UpmsLogService upmsLogService;
@Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveSysLog(point, beginTime, time, result);
return result;
}
/**
* 日志记录
*
* @param joinPoint
* @param beginTime 开始时间
* @param spendTime 用时
* @param result 返回结果
*/
private void saveSysLog(ProceedingJoinPoint joinPoint,long beginTime, long spendTime, Object result) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
UpmsLog upmsLog = new UpmsLog();
upmsLog.setLogId(UUIDUtil.getUUID());
upmsLog.setAppId("wx");
ApiOperation annotation = method.getAnnotation(ApiOperation.class);
if(annotation != null){
//注解上的描述
upmsLog.setDescription(annotation.value());
}
//请求的参数
Object[] args = joinPoint.getArgs();
String params = JSON.toJSONString(args[0]);
upmsLog.setParameter(params);
// 返回结果
String resultJson = JSON.toJSONString(result);
upmsLog.setResult(resultJson);
//获取request
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
//设置IP地址
upmsLog.setIp(IPUtils.getIpAddr(request));
// 请求路径
String requestUrl = request.getRequestURL().toString();
upmsLog.setUrl(requestUrl);
String requestURI = request.getRequestURI();
upmsLog.setUri(requestURI);
// 请求头
String agentString = request.getHeader("User-Agent");
upmsLog.setUserAgent(agentString);
// 请求方式
String authType = request.getMethod();
upmsLog.setMethod(authType);
//用户名
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) {
Object userId = subject.getPrincipal();
upmsLog.setUsername(userId.toString());
upmsLog.setUserId(userId.toString());
}
String path = request.getContextPath();
String baseURL = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
upmsLog.setBasePath(baseURL);
// 开始时间
upmsLog.setStartTime(beginTime);
// 用时
upmsLog.setSpendTime(spendTime);
upmsLog.setCreatetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//保存系统日志
logger.info("日志信息:"+ upmsLog);
upmsLogService.saveLog(upmsLog);
}
}
我的spring xml的配置如下:
<context:component-scan
base-package="com.mytest.aop">
<context:include-filter type="annotation"
expression="org.aspectj.lang.annotation.Aspect" />
</context:component-scan>
<!-- 设置AOP为自动代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
我的controller(部分)
@Api(value = "info", description = "相关控制器")
@Controller
@RequestMapping(value = "/test/getInfo")
public class InfoController {
@Autowired
private InfoService infoService;
@ApiOperation(value = "aop日志测试")
@RequestMapping("/getInfo")
@ResponseBody
public AjaxJson getInfo(String datas) {
JSONObject data = JSONObject.parseObject(datas);
AjaxJson result = infoService.getInfo(data.toString());
return result;
}
}
其他的servic、entity等代码这里就不放了,有需求的小伙伴可以留言。
标签:基于,String,aop,request,ApiOperation,upmsLog,org,import,日志 来源: https://www.cnblogs.com/caoleiCoding/p/11920879.html