Java自动日志监控框架auto-log详解

1. 需求概述

日常开发中,不管是单体还是分布式微服务,服务监控是必不可少的环节,没有监控的应用是很可怕的,你不知道应用服务处于什么状态,有什么风险,什么时候会宕掉。服务监控除了一些大型的监控工具,比如ELK,Zabbx,Prometheus,Arthas等工具外,本文要讲的是轻量级的日志监控工具,轻量到可以不引入Spring,就是一个简单的请求前后出入参以及异常的打印,以及自定义一些过滤器拦截器,traceID等功能,而不必每个服务的每个方法都手动处理。

实现本身也很简单,只需要通过切面+注解实现,github上发现auto-log无论是从架构设计,到实现,规范,注释,包括使用方式都值得推荐,感谢大佬,这里只做引荐,简单梳理使用验证。

2. auto-log简介

2.1 auto-log定义

auto-log 是一款为 java 设计的自动日志监控框架。

2.2 auto-log目的

经常会写一些工具,有时候手动加一些日志很麻烦,引入 spring 又过于大材小用。
所以希望从从简到繁实现一个工具,便于平时使用。

2.3 auto-log特性

  • 基于注解+字节码,配置灵活
  • 自动适配常见的日志框架
  • 支持编程式的调用
  • 支持注解式,完美整合 spring
  • 支持整合 spring-boot
  • 支持慢日志阈值指定,耗时,入参,出参,异常信息等常见属性指定
  • 支持 traceId 特性
  • 支持类级别定义注解
  • 支持自定义拦截器和过滤器

2.4 注解说明

@AutoLog
核心注解 @AutoLog 的属性说明如下:
在这里插入图片描述@TraceId
@TraceId 放在需要设置 traceId 的方法上,比如 Controller 层,mq 的消费者,rpc 请求的接受者等。

属性 类型 默认值 说明
id Class 默认为 uuid traceId 的实现策略
putIfAbsent boolean false 是否在当前线程没有值的时候才设置值
enable boolean true 是否启用
interceptor Class[] 默认实现 拦截器实现,支持指定多个和自定义

2.5 自定义拦截器

内置拦截器
AutoLogInterceptor 默认实现。

自定义拦截器
1.直接继承自 AbstractAutoLogInterceptor 类,并且实现对应的方法即可。
2.使用的时候指定自定义拦截器。
@AutoLog(interceptor = MyAutoLogInterceptor.class)

2.6 自定义过滤器

内置过滤器
WebParamFilter 主要用于过滤 HttpRequest HttpServlet 等无法直接 JSON 序列化的对象。

自定义过滤器
1.直接继承 AbstractParamFilter 类实现对应的方法即可。
2.使用的时候指定自定义过滤器。
@AutoLog(paramFilter = MyParamFilter.class)

2.7 注意事项

1.auto-log默认是开启的@EnableAutoLog,无需再次开启,多次开启也不影响使用。
2.集成springboot只需要引入stater即可,无需任何配置。

2.8 开源地址

Github: https://github.com/houbb/auto-log
Gitee: https://gitee.com/houbinbin/auto-log

3.实现验证

3.1 引入依赖

<!--autolog-->
 <dependency>
 	<groupId>com.github.houbb</groupId>
	<artifactId>auto-log-springboot-starter</artifactId>
	<version>0.0.15</version>
 </dependency>

只需要引入 jar 即可,其他的什么都不用配置。
使用方式和 spring 一致。

3.2 代码实现

LogController

package com.zrj.autolog.controller;

import com.github.houbb.auto.log.annotation.AutoLog;
import com.github.houbb.auto.log.annotation.TraceId;
import com.zrj.autolog.entity.Log;
import com.zrj.autolog.entity.Response;
import com.zrj.autolog.filter.MyLogParamFilter;
import com.zrj.autolog.interceptor.MyLogInterceptor;
import com.zrj.autolog.service.LogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * 用户控制类
 *
 * @author zrj
 * @since 2021-06-21 16:44:24
 */
@Slf4j
@RestController
@RequestMapping("/log")
@Api(tags = "日志管理", description = "日志管理")
public class LogController {
    
    

    @Resource
    private LogService logService;

    /**
     * 测试接口
     * 自定义过滤器,拦截器
     */
    @TraceId
    @GetMapping("/test")
    @ApiOperation(value = "测试接口")
    @AutoLog(description = "测试接口", costTime = true, interceptor = MyLogInterceptor.class, paramFilter = MyLogParamFilter.class)
    public Response<String> test() {
    
    
        return Response.success("日志管理测试成功", null);
    }

    /**
     * 自动日志管理
     */
    @TraceId
    @AutoLog(description = "自动日志管理", costTime = true)
    @PostMapping("/autolog")
    @ApiOperation(value = "自动日志管理测试")
    public Response<Log> autolog(@RequestBody Log log) {
    
    
        Log build = logService.getLog();
        if (build != null) {
    
    
            return Response.success("查询成功", build);
        }
        return Response.fail("查询失败");
    }

}

MyLogParamFilter

package com.zrj.autolog.filter;

import com.github.houbb.auto.log.core.support.filter.param.AbstractParamFilter;

/**
 * 自定义入参过滤器(paramFilter)
 *
 * @author zrj
 * @since 2021/11/10
 **/
public class MyLogParamFilter extends AbstractParamFilter {
    
    
    /**
     * 执行参数过滤
     *
     * @param params 入参
     * @return 结果
     * @since 0.0.12
     */
    @Override
    protected Object[] doFilter(Object[] params) {
    
    
        Object[] newParams = new Object[1];
        newParams[0] = "自定义过滤器设置我我想要的值";
        return newParams;
    }
}

MyLogInterceptor

package com.zrj.autolog.interceptor;

import com.github.houbb.auto.log.annotation.AutoLog;
import com.github.houbb.auto.log.api.IAutoLogInterceptorContext;
import com.github.houbb.auto.log.core.support.interceptor.autolog.AbstractAutoLogInterceptor;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;

/**
 * 自定义日志拦截器(interceptor)
 *
 * @author zrj
 * @since 2021/11/10
 **/
@Slf4j
public class MyLogInterceptor extends AbstractAutoLogInterceptor {
    
    
    /**
     * 方法执行以前
     * @param autoLog 注解
     * @param context 上下文
     * @since 0.0.10
     */
    @Override
    protected void doBefore(AutoLog autoLog, IAutoLogInterceptorContext context) {
    
    
        log.info("我的自定义入参:" + Arrays.toString(context.filterParams()));
    }

    /**
     * 方法执行以后
     * @param autoLog 注解
     * @param result  方法执行结果
     * @param context 上下文
     * @since 0.0.10
     */
    @Override
    protected void doAfter(AutoLog autoLog, Object result, IAutoLogInterceptorContext context) {
    
    
        log.info("我的自定义出参:" + result);
    }

    /**
     * 异常处理
     * @param autoLog   注解
     * @param exception 异常信息
     * @param context   上下文
     * @since 0.0.10
     */
    @Override
    protected void doException(AutoLog autoLog, Exception exception, IAutoLogInterceptorContext context) {
    
    
        log.info("我的自定义异常:");
        exception.printStackTrace();
    }
}

3.3 处理结果

MyLogInterceptor       : 我的自定义入参:[自定义过滤器设置我我想要的值]
MyLogInterceptor       : 我的自定义出参:Response(message=日志管理测试成功, data=null, code=200)
AutoLogInterceptor     : [f4794449d6454e13807fdd5a5fffc2dd] <自动日志管理>入参: [{
    
    "des":"日志描述","level":"日志级别","name":"日志名称","id":"日志ID"}].
e.impl.LogServiceImpl  : 这里保存日志信息
AutoLogInterceptor     : [f4794449d6454e13807fdd5a5fffc2dd] <自动日志管理>出参:{
    
    "code":"200","data":{
    
    "des":"测试啦","id":"20211109001","level":"info","name":"自动日志"},"message":"查询成功"}.
AutoLogInterceptor     : [f4794449d6454e13807fdd5a5fffc2dd] <自动日志管理>耗时:70ms.

猜你喜欢

转载自blog.csdn.net/m0_37583655/article/details/121242927