Spring boot2.0 实现日志集成的方法(3)

目录
  • 前言
  • 具体实现
  • 定义日志注解
  • 定义日志切面
  • 基本使用
  • 输出信息
  • 总结

前言

上一章Spring boot2.0 实现日志集成的方法(2)主要讲解了将日志信息根据类别输出到不同的文件中,实际开发中我们需要通过日志来监控用户的操作行为、请求的耗时情况,针对耗时久的请求进行性能分析,提升系统性能。

具体实现

采用的Spring Aop切面技术来实现控用户的操作行为、请求的耗时情况。

定义日志注解

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation
{
    // 模块
    String model() default "";

    // 功能
    String func() default "";

    //描述
    String desc() default "";
}

定义日志切面

@Aspect
@Component
public class LogAspect
{
    //请求监控日志,输出到不同日志文件
    public static Log logger = LogManager.getLogger("request-access");

    /**
     * 定义切面
     */
    @Pointcut("@annotation(com.test.aspect.LogAnnotation)")
    private void logPoinCut()
    {

    }

    /**
     *
     * @param joinPoint
     */
    @Before(value = "logPoinCut()")
    public void doBefore(JoinPoint joinPoint)
    {
        String requestId =TraceIdUtil.getTraceId();
        logger.info("Start invoke requestID:[{}]",requestId);
    }

    @Around(value = "logPoinCut()")
    public Object doAround(ProceedingJoinPoint jp) throws Throwable
    {
        String requestId =TraceIdUtil.getTraceId();
        logger.info("Enter request start requestId :[{}]",requestId);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        MethodSignature signature = (MethodSignature) jp.getSignature();
        Method method = signature.getMethod();
        long startTime= System.currentTimeMillis();
        OperationLog operationLog = new OperationLog();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        if (logAnnotation != null)
        {
            String model = logAnnotation.model();
            String func = logAnnotation.func();
            String desc = logAnnotation.desc();
            operationLog.setModel(model);
            operationLog.setFunc(func);
            operationLog.setDesc(desc);
        }

        String className = jp.getTarget().getClass().getName();
        String methodName = jp.getSignature().getName();
        String uri = request.getRequestURI();
        String ip = IpUtil.getIpAddr(request);
        operationLog.setClassName(className);
        operationLog.setMethodName(methodName);
        operationLog.setIp(ip);
        operationLog.setUri(uri);
        StringBuilder param = new StringBuilder();
        Object[] args = jp.getArgs();
        Object arg = null;
        for (int i = 0, j = args.length; i < j; i++)
        {
            arg = args[i];
            param.append("    ")
                    .append(arg == null ? null : args[i].toString());
            if (i != (j - 1))
            {
                param.append(",").append("\n");
            }
        }
        operationLog.setParam(param.toString());
        operationLog.setCreateDate(new Date());
        long endTime=System.currentTimeMillis()-startTime;
        //可以通过配置设置异常调用请求时间
        long costTime=3;
        operationLog.setCostTime(endTime);
        String logStr = JSON.toJSONString(operationLog);
         //将异常请求数据插入数据库
        if(endTime>costTime){
           //saveOpetionLog(operationLog);
        }
        logger.info("invoke finish message:{}",logStr);
        Object obj = jp.proceed();
        return obj;
    }

    /**
     * 方法之后调用
     * @param joinPoint
     * @param returnValue 方法返回值
     */
    @AfterReturning(pointcut = "logPoinCut()")
    public void  doAfterReturning(JoinPoint joinPoint)
    {
        String requestId=TraceIdUtil.getTraceId();
        logger.info("End invoke request ID [{}]",requestId);
    }
}

基本使用

    @LogAnnotation(model="用户管理",func="查询用户信息",desc="根据用户名称")
    @GetMapping("getUserByName")
    public Result getUserByName(@RequestParam String name)
    {
        logger.info("getUserByName paramter name:[{}]",name);
        return Result.success(userService.getUserByName(name));
    }

输出信息

{
     "className": "com.test.controller.UserController",
     "costTime": 19,
     "createDate": "2022/03/11 15:20:30",
     "createUser": "xx",
     "ip": "172.18.188.111",
     "methodName": "getUserByName",
     "param": "  zhangsan",
      "uri": "/user/getUserByName",
     "model":"用户管理",
     "func":"查询用户信息",
     "desc":"根据用户名称",
     "version": 0
}

对于一些敏感的信息需要进行加密处理。针对异常的请求进行分析和性能优化。

总结

上述日志信息虽然记录的比较详细,但是缺少了请求的来源,尤其是跨服务之间的调用,则无法进行追踪。链路追踪可以采用Spring Boot +logbck+MDC来实现。

到此这篇关于Spring boot2.0 实现日志集成的方法(3)的文章就介绍到这了,更多相关Spring boot 日志集成内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot项目集成日志的实现方法

    SpringBoot使用Commons Logging进行所有内部日志记录,但保留底层日志实现.默认提供了Java Util Logging, Log4j2 和Logback日志配置.在每种情况下,都预先配置为使用控制台输出,并且还提供了可选的文件输出.(来自官网) 日志格式 SpringBoot默认的日志输出如下所示: 2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine :

  • Spring boot2.0 实现日志集成的方法(2)

    目录 前言: logback.xml配置文件定义 引用自定义logback.xml文件 附加说明 前言: 上一章Spring boot2.0 日志集成方法分享(1)讲解了spring boot日志简单集成,将所有的日志都输出到一个文件中,但是在实际的项目中,我们需要将日志进行分类,常规日志.异常日志.监控日志等,需要将日志输出到不同的文件中.spring boot 日志默认采用的是sf4j+logback实现,默认配置文件为logback-spring.xml,如果需要输出到不同的文件,需要自定

  • Spring boot2.0 日志集成方法分享(1)

    目录 前言: 1.基本引用 2.基础配置 3.基本使用 前言: 项目开发中日志是不可缺少的一部分,通过日志能够定位和分析事故原因.目前流行日志框架包含了log4j.log4j2.logback等,另外 slf4j(Simple Logging Facade for Java) 则是一个日志门面框架,提供了日志系统中常用的接口,logback 和 log4j 则对slf4j 进行了实现.本文将讲述spring boot 中如何使用logback+slf4j实现日志. Java应用中,日志一般分为以

  • SpringBoot集成slf4j日志配置的方法

    目录 前言 1.slf4j概述 2.pom.xml的日志依赖 3.application.yml的日志配置 4.logback.xml配置文件定义 5.logback.xml配置文件解析 5.1 定义日志的存储路径 5.2 定义日志的输出格式 5.3 定义控制台输出 5.4 定义日志相关参数 5.5 定义日志的输出级别 6.测试日志输出 7.小结 前言 日志,作为一个应用系统的重要部分,然而并不会在项目预研或需求设计阶段就作为一个功能模块单独规划设计,但这丝毫不影响它在任何一个系统中的重要的地位

  • 解析springboot集成AOP实现日志输出的方法

    开发接口系统中主要的一环就是日志输出,如果系统出现问题,日志能帮我们去定位问题,最常见的日志是调用方 所调用的IP 接口地址 对应方法 参数值 以及接口方接收到请求 所返回的参数.如果这需要在每一个controller层去写的话代码过于重复,于是就使用AOP定义切面 对其接口调用前后进行拦截日志输出. 1.加入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spr

  • Spring boot2.0 实现日志集成的方法(3)

    目录 前言 具体实现 定义日志注解 定义日志切面 基本使用 输出信息 总结 前言 上一章Spring boot2.0 实现日志集成的方法(2)主要讲解了将日志信息根据类别输出到不同的文件中,实际开发中我们需要通过日志来监控用户的操作行为.请求的耗时情况,针对耗时久的请求进行性能分析,提升系统性能. 具体实现 采用的Spring Aop切面技术来实现控用户的操作行为.请求的耗时情况. 定义日志注解 @Target({ ElementType.METHOD }) @Retention(Retenti

  • spring boot2.0实现优雅停机的方法

    前期踩的坑 (spring boot 1.x) 1. 添加mavne依赖 <!-- springboot监控 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 2. 启用shutdown 在配置文件里添加下面的配置 #

  • spring boot2.0图片上传至本地或服务器并配置虚拟路径的方法

    最近写了关于图片上传至本地文件夹或服务器,上传路径到数据库,并在上传时预览图片.使用到的工具如下: 框架:spring boot 2.0 前端模板:thymeleaf 图片预览:js 首先,上传以及预览,js以及<input type="file">,以及预览图片的JS function Img(obj){ var imgFile = obj.files[0]; console.log(imgFile); var img = new Image(); var fr = ne

  • Spring Boot2.0使用Spring Security的示例代码

    一.Spring Secutity简介 Spring 是一个非常流行和成功的 Java 应用开发框架.Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案.一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分.用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.用户认证一般要求用户提供用户名和密码.系统通过校验用户名和密码来完成认证过程.用户授权指的是

  • 解决Spring boot2.0+配置拦截器拦截静态资源的问题

    第一次遇到这个问题的时候,简直是一脸蒙逼,写了一个拦截器以后,静态资源就不能访问了,到处查找才知道是版本问题 解决办法: 第一步:定义一个类实现 实现WebMvcConfigurer的类中拦截器中添加放行资源处添加静态资源文件路径: @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(sessionInterceptor).addPathPatterns("/&

  • spring boot2.0总结介绍

    从这篇文章开始以spring boot2为主要版本进行使用介绍. Spring boot 2特性 spring boot2在如下的部分有所变化和增强,相关特性在后续逐步展开. 特性增强 基础组件升级: JDK1.8+ tomcat 8+ Thymeleaf 3 Hibernate 5.2 spring framework 5 Reactive Spring Functional API Kotlin支持 Metrics Security 使用变化 配置属性变化 Gradle插件 Actuator

  • Spring Boot2.0中SpringWebContext找不到无法使用的解决方法

    前言 为了应对在SpringBoot中的高并发及优化访问速度,我们一般会把页面上的数据查询出来,然后放到redis中进行缓存.减少数据库的压力. 在SpringBoot中一般使用 thymeleafViewResolver.getTemplateEngine().process("goodlist", ctx); 进行页面的渲染,而这个ctx就是SpringWebContext对象,我们一般进行如下获取: SpringWebContext swc=new SpringWebContex

  • Spring Boot2.0整合ES5实现文章内容搜索实战

    一.文章内容搜索思路 上一篇讲了在怎么在 Spring Boot 2.0 上整合 ES 5 ,这一篇聊聊具体实战.简单讲下如何实现文章.问答这些内容搜索的具体实现.实现思路很简单: 基于「短语匹配」并设置最小匹配权重值 哪来的短语,利用 IK 分词器分词 基于 Fiter 实现筛选 基于 Pageable 实现分页排序 这里直接调用搜索的话,容易搜出不尽人意的东西.因为内容搜索关注内容的连接性.所以这里处理方法比较 low ,希望多交流一起实现更好的搜索方法.就是通过分词得到很多短语,然后利用短

随机推荐