java 注解结合 spring aop 自动输出日志新增拦截器与过滤器
auto-log
auto-log 是一款为 java 设计的自动日志监控框架。
前面已经写过了两篇:
java 注解结合 spring aop 实现日志 traceId 唯一标识
经过前面2篇的代码实现,发现依然存在下列问题:
(1)注解的使用依然不够便捷。
如果每一个方法上都指定 @AutoLog,依然会比较麻烦。个人在使用的时候也不想这么麻烦。
于是想添加基于类的注解。
后期考虑是否可以基于包,动态指定 AOP 的扫描包范围。
(2)对于日志的处理过于单一。
比如我想添加所有操作的审计日志,然后存储到数据库。同时日志输出不变。
发现以前的日志框架,不能很好的支撑。于是想添加日志输出的拦截器。
(3)对于参数的过滤
以前是直接基于 toString() 实现,发现有些人比较懒不写 toString(比如我),那么参数打印的信息就没有意义。
于是替换成立 FastJSON,但是引来了新的问题,比如 HttpRequest 等参数直接序列化是会报错的,于是想添加基于参数的过滤器实现。
需求,才是最好的创作动力。
目前共计经过了 12 个版本的迭代,上面 3 个特性已经满足。
特性
基于注解+字节码,配置灵活
自动适配常见的日志框架
支持编程式的调用
支持注解式,完美整合 spring
支持整合 spring-boot
支持慢日志阈值指定,耗时,入参,出参,异常信息等常见属性指定
支持 traceId 特性
支持类级别定义注解
支持自定义拦截器和过滤器
快速开始
maven 引入
<dependency>
<group>com.github.houbb</group>
<artifact>auto-log-core</artifact>
<version>${最新版本}</version>
</dependency>
入门案例
UserService userService = AutoLogHelper.proxy(new UserServiceImpl());
userService.queryLog("1");
- 日志如下
[INFO] [2020-05-29 16:24:06.227] [main] [c.g.h.a.l.c.s.i.AutoLogMethodInterceptor.invoke] - public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) param is [1]
[INFO] [2020-05-29 16:24:06.228] [main] [c.g.h.a.l.c.s.i.AutoLogMethodInterceptor.invoke] - public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) result is result-1
代码
其中方法实现如下:
- UserService.java
public interface UserService {
String queryLog(final String id);
}
- UserServiceImpl.java
直接使用注解 @AutoLog 指定需要打日志的方法即可。
public class UserServiceImpl implements UserService {
@Override
@AutoLog
public String queryLog(String id) {
return "result-"+id;
}
}
TraceId 的例子
代码
UserService service = AutoLogProxy.getProxy(new UserServiceImpl());
service.traceId("1");
其中 traceId 方法如下:
@AutoLog
@TraceId
public String traceId(String id) {
return id+"-1";
}
测试效果
信息: [ba7ddaded5a644e5a58fbd276b6657af] <traceId>入参: [1].
信息: [ba7ddaded5a644e5a58fbd276b6657af] <traceId>出参:1-1.
其中 ba7ddaded5a644e5a58fbd276b6657af 就是对应的 traceId,可以贯穿整个 thread 周期,便于我们日志查看。
注解说明
@AutoLog
核心注解 @AutoLog 的属性说明如下:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| enable | boolean | true | 是否启用 |
| param | boolean | true | 是否打印入参 |
| result | boolean | true | 是否打印出参 |
| costTime | boolean | false | 是否打印耗时 |
| exception | boolean | true | 是否打印异常 |
| slowThresholdMills | long | -1 | 当这个值大于等于 0 时,且耗时超过配置值,会输出慢日志 |
| description | string | "" | 方法描述,默认选择方法名称 |
| interceptor | Class[] | 默认实现 | 拦截器实现,支持指定多个和自定义 |
| paramFilter | Class | 空 | 入参过滤器,支持自定义 |
@TraceId
@TraceId 放在需要设置 traceId 的方法上,比如 Controller 层,mq 的消费者,rpc 请求的接受者等。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| id | Class | 默认为 uuid | traceId 的实现策略 |
| putIfAbsent | boolean | false | 是否在当前线程没有值的时候才设置值 |
| enable | boolean | true | 是否启用 |
| interceptor | Class[] | 默认实现 | 拦截器实现,支持指定多个和自定义 |
自定义策略
自定义日志拦截器(interceptor)
内置拦截器
AutoLogInterceptor 默认实现
定义
直接继承自 AbstractAutoLogInterceptor 类,并且实现对应的方法即可。
public class MyAutoLogInterceptor extends AbstractAutoLogInterceptor {
@Override
protected void doBefore(AutoLog autoLog, IAutoLogInterceptorContext context) {
System.out.println("自定义入参:" + Arrays.toString(context.filterParams()));
}
@Override
protected void doAfter(AutoLog autoLog, Object result, IAutoLogInterceptorContext context) {
System.out.println("自定义出参:" + result);
}
@Override
protected void doException(AutoLog autoLog, Exception exception, IAutoLogInterceptorContext context) {
System.out.println("自定义异常:");
exception.printStackTrace();
}
}
使用
如下,这样日志输出,就会使用上面的指定策略。
@AutoLog(interceptor = MyAutoLogInterceptor.class)
public String my() {
return "自定义策略";
}
自定义入参过滤器(paramFilter)
内置
WebParamFilter 主要用于过滤 HttpRequest HttpServlet 等无法直接 JSON 序列化的对象。
自定义
直接继承 AbstractParamFilter 类实现对应的方法即可。
public class MyParamFilter extends AbstractParamFilter {
@Override
protected Object[] doFilter(Object[] params) {
Object[] newParams = new Object[1];
newParams[0] = "设置我我想要的值";
return newParams;
}
}
使用
指定对应的参数过滤器。这样,无论入参是什么,都会变成我们指定的 [设置我我想要的值]。
@AutoLog(paramFilter = MyParamFilter.class)
public String paramFilter() {
return "自定义入参过滤器";
}
spring 整合使用
完整示例参考 SpringServiceTest
注解声明
使用 @EnableAutoLog 启用自动日志输出
@Configurable
@ComponentScan(basePackages = "com.github.houbb.auto.log.test.service")
@EnableAutoLog
public class SpringConfig {
}
测试代码
@ContextConfiguration(classes = SpringConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringServiceTest {
@Autowired
private UserService userService;
@Test
public void queryLogTest() {
userService.queryLog("1");
}
}
- 输出结果
信息: public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) param is [1]
五月 30, 2020 12:17:51 下午 com.github.houbb.auto.log.core.support.interceptor.AutoLogMethodInterceptor info
信息: public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) result is result-1
五月 30, 2020 12:17:51 下午 org.springframework.context.support.GenericApplicationContext doClose
springboot 整合使用
maven 引入
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>auto-log-springboot-starter</artifactId>
<version>最新版本</version>
</dependency>
只需要引入 jar 即可,其他的什么都不用配置。
使用方式和 spring 一致。
测试
@Autowired
private UserService userService;
@Test
public void queryLogTest() {
userService.query("spring-boot");
}
开源地址
Road-Map
- 优化日志中的方法路径名称
考虑补全对应的类信息
- 全局配置
比如全局的慢日志阈值设置等
jvm-sandbox 特性
编译时注解特性
原文地址

java 注解结合 spring aop 自动输出日志新增拦截器与过滤器的更多相关文章
- Spring Boot项目中如何定制拦截器
本文首发于个人网站:Spring Boot项目中如何定制拦截器 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供Han ...
- 基于注解的Spring AOP的配置和使用
摘要: 基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不 ...
- 基于注解的Spring AOP的配置和使用--转载
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(三)创建代理对象
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- Java动态代理-->Spring AOP
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(二)筛选合适的通知器
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(一)入口
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 基于注解的Spring AOP示例
基于注解的Spring AOP示例 目录 在XML配置文件中开启 @AspectJ 支持 声明切面及切入点 声明通知 测试 结语 在XML配置文件中开启 @AspectJ 支持 要使用Spring的A ...
- Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现
转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...
- spring AOP AspectJ 定义切面实现拦截
总结记录一下AOP常用的应用场景及使用方式,如有错误,请留言. 1. 讲AOP之前,先来总结web项目的几种拦截方式 A: 过滤器 使用过滤器可以过滤URL请求,以及请求和响应的信息,但是过 ...
随机推荐
- 什么是 doris,为什么几乎国内大厂都会使用它
转载至我的博客 https://www.infrastack.cn ,公众号:架构成长指南 今天给各位分享一个非常牛的实时分析型数据库Apache Doris,几乎国内的一二线大厂都在使用它做数据分析 ...
- [转帖]Percolator - 分布式事务的理解与分析
https://zhuanlan.zhihu.com/p/261115166 Percolator - 分布式事务的理解与分析 概述 一个web页面能不能被Google搜索到,取决于它是否被Googl ...
- [转帖]jmeter无图形界面执行测试并生成报告
1.进入jmeter的安装目录,找到bin文件夹,进入这个文件执行以下命名 jmeter -n -t test\xxx.jmx -l test\cli0705.jtl -e -o test\resul ...
- [转帖]011 Linux 打包与解压 tar
https://my.oschina.net/u/3113381/blog/5429977 01 压缩.打包命令有哪些? Linux 上有着各种压缩.打包的工具:tar.gzip.zip.7z,而 t ...
- [转帖]【k8s】1、基础概念和架构及组件
文章目录 一.kubernetes概述 1.什么是kubernetes? 2.应用程序部署方式的演变 3.为什么要用kubernetes? 二.kubernetes 特性 三.Kubernetes集群 ...
- vue3获取数据的注意点
场景描述 在使用vue3的时候.我们很多人喜欢一个页面分成几个几个部分来写 这样做的目的是为了区分. 做的彼此的逻辑互相独立,互不干扰 但是有的时候,我们可能会去获取不属于自己区域的函数 这个时候我们 ...
- fasthttp 中如何使用`Transfer-Encoding: chunked` 方式的流式内容输出
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 具体的思路是这样:通过 RequestCtx 的 Conn ...
- Git 简单实用教程
相关链接: 码云(gitee)配置SSH密钥 码云gitee创建仓库并用git上传文件 git 上传错误This oplation equires one of the flowi vrsionsot ...
- 【五】AI Studio 项目详解【VisualDL工具、环境使用说明、脚本任务、图形化任务、(五)在线部署及预测】PARL
相关文章 [一]-环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简介 [五]-Sarsa&Qlear ...
- C/C++ 关于继承与多态笔记
继承的基本语法: 继承的目的就是用于提高代码的可用性,减少代码的重复内容,高效开发. #include <iostream> using namespace std; class Base ...