springboot自定义注解收集操作日志

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: springboot自定义注解收集操作日志


image.png

对于日志收集,是系统离不开的功能,那么如何实现简易的日志收集呢。市面上最常见的就是使用自定义注解。本文将介绍如何使用自定义注解收集日志。

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中,可在后续文章看到。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
打赏
0
0
0
0
27
分享
相关文章
|
15天前
|
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
98 26
SpringBoot缓存注解使用
Spring Boot 提供了一套方便的缓存注解,用于简化缓存管理。通过 `@Cacheable`、`@CachePut`、`@CacheEvict` 和 `@Caching` 等注解,开发者可以轻松地实现方法级别的缓存操作,从而提升应用的性能和响应速度。合理使用这些注解可以大大减少数据库的访问频率,优化系统性能。
163 89
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
181 73
|
5天前
|
SpringBoot:SpringBoot通过注解监测Controller接口
本文详细介绍了如何通过Spring Boot注解监测Controller接口,包括自定义注解、AOP切面的创建和使用以及具体的示例代码。通过这种方式,可以方便地在Controller方法执行前后添加日志记录、性能监控和异常处理逻辑,而无需修改方法本身的代码。这种方法不仅提高了代码的可维护性,还增强了系统的监控能力。希望本文能帮助您更好地理解和应用Spring Boot中的注解监测技术。
33 16
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
60 21
|
2月前
|
.net 自定义日志类
在.NET中,创建自定义日志类有助于更好地管理日志信息。示例展示了如何创建、配置和使用日志记录功能,包括写入日志文件、设置日志级别、格式化消息等。注意事项涵盖时间戳、日志级别、JSON序列化、线程安全、日志格式、文件处理及示例使用。请根据需求调整代码。
53 13
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
Spring MVC核心:深入理解@RequestMapping注解
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的核心,它将HTTP请求映射到控制器的处理方法上。本文将深入探讨`@RequestMapping`注解的各个方面,包括其注解的使用方法、如何与Spring MVC的其他组件协同工作,以及在实际开发中的应用案例。
65 4
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
231 2

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等