springboot自定义注解收集操作日志
Posted 小鲍侃java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot自定义注解收集操作日志相关的知识,希望对你有一定的参考价值。
对于日志收集,是系统离不开的功能,那么如何实现简易的日志收集呢。市面上最常见的就是使用自定义注解。本文将介绍如何使用自定义注解收集日志。
1.添加自定义注解
@Target(ElementType.PARAMETER, ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
/**
* 注释
*/
String operationName() default "";
2.使用AOP拦截注解
该类的含义是:没调用一个接口,都会判断该接口是否带有上文的自定义注解,如果带有,就会执行AOP中的功能,本文是获取入参,出参,sql,方法名,系统名,调用ip等参数,并打印。
@Component
public class LogAspect
private Logger logger = LoggerFactory.getLogger(LogAspect.class);
private String succeed = "true";
/**
* 在注释@log的方法中进入本类
*/
@Pointcut("@annotation(com.resource.business.modular.log.annotation.Log)")
public void logPointCut()
/**
* 前置通知 用于拦截操作,在方法返回后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
public void doAfter(JoinPoint joinPoint, Result jsonResult)
handleLog(joinPoint, jsonResult);
/**
* 拦截异常操作,有异常时执行
*
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfter(JoinPoint joinPoint, Exception e)
Log controllerLog = getAnnotationLog(joinPoint);
// 没有注解
if (controllerLog == null)
return;
// 处理入参
String args = this.argsArrayToString(joinPoint.getArgs());
// 获取请求上下文信息
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
HttpServletResponse response = attributes.getResponse();
// 获取时间
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 获取用户信息
String userName = (String.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal()));
// 组合入参信息
logger.error("|" + userName + "|" + controllerLog.operationName() + "|" + sd.format(new Date()) + "|"
+ IpUtil.getIpAddr() + "|" + "XXX系统" + "|" + "操作日志" + "|" + "null" + "|" + "null");
logger.error("|" + userName + "|" + controllerLog.operationName() + "|" + sd.format(new Date()) + "|"
+ IpUtil.getIpAddr() + "|" + "XXX系统" + "|" + "接口日志" + "|" + request.getRequestURI() + "|" + args);
logger.debug("错误信息为:" + e);
/**
* 判断是否有注解
*
* @param joinPoint
* @throws Exception
*/
private Log getAnnotationLog(JoinPoint joinPoint)
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature)signature;
Method method = methodSignature.getMethod();
if (method != null)
return method.getAnnotation(Log.class);
return null;
/**
* 功能描述:执行日志操作
*
* @param: joinPoint ,e ,response
* @return:
*/
private void handleLog(final JoinPoint joinPoint, Result jsonResult)
Log controllerLog = getAnnotationLog(joinPoint);
// 没有注解
if (controllerLog == null)
return;
// 处理入参
String args = this.argsArrayToString(joinPoint.getArgs());
// 获取请求上下文信息
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
HttpServletResponse response = attributes.getResponse();
// 获取时间
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 获取用户信息
String userName = (String.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal()));
// 组合入参信息
logger.info("|" + userName + "|" + controllerLog.operationName() + "|" + sd.format(new Date()) + "|"
+ IpUtil.getIpAddr() + "|" + "XXX系统" + "|" + "操作日志" + "|" + "null" + "|" + "null");
logger.info("|" + userName + "|" + controllerLog.operationName() + "|" + sd.format(new Date()) + "|"
+ IpUtil.getIpAddr() + "|" + "XXX系统" + "|" + "接口日志" + "|" + request.getRequestURI() + "|" + args);
logger.info("输出参数:" + JSONArray.toJSONString(jsonResult.getData()));
/**
* 组装入参
*
* @param paramsArray
* @return
*/
private String argsArrayToString(Object[] paramsArray)
String params = "";
if (paramsArray != null && paramsArray.length > 0)
for (int i = 0; i < paramsArray.length; i++)
if (!isFilterObject(paramsArray[i]))
Object jsonObj = JSON.toJSON(paramsArray[i]);
params += jsonObj.toString() + " ";
if (("").equals(params.trim()))
params = "无入参";
return params.trim();
/**
* 判断是否需要过滤的对象。
*
* @param o 对象信息。
* @return 如果是需要过滤的对象,则返回true;否则返回false。
*/
public boolean isFilterObject(final Object o)
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
注意:楼主使用elk收集了日志,输出在logstash中获取“|” 然后拆分成不同字段,并保存在es中,可在后续文章看到。
以上是关于springboot自定义注解收集操作日志的主要内容,如果未能解决你的问题,请参考以下文章