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请求,以及请求和响应的信息,但是过 ...
随机推荐
- 安卓系统如何使用谷歌框架下的app?
1.问题 安卓系统从理论上无法使用谷歌框架下的应用(比如像GMail,YouTube,Google play等等),会导致一些麻烦(闪退,卡在登陆界面等等) 注意:使用前提是会魔法,否则请绕道 2.解 ...
- 《OnJava》——11内部类
内部类 利用内部类,可以将逻辑上存在关联的类组织在一起,而且可以控制一个类在另一个类中的可见性. 内部类和组合不同,内部类是一种代码隐藏机制:将代码放在其他类的内部. 11.1 创建内部类 创建内部类 ...
- CAP-BASE
- [转帖]nginx反向代理时保持长连接
https://www.cnblogs.com/liufarui/p/11075630.html ·[场景描述] HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上 ...
- [转帖]OutOfMemory JVM参数一览
https://www.cnblogs.com/kuroro/p/11707951.html JVM提供了有用的参数来处理OutOfMemoryError.在本文中,我们要强调那些JVM参数.在对Ou ...
- [转帖]mysql8.0的RPM方式安装
https://www.cnblogs.com/asker009/p/15072354.html 1. 下载 https://dev.mysql.com/downloads/ 使用wget下载yum的 ...
- 【转帖】训练中文LLaMA大规模语言模型
https://zhuanlan.zhihu.com/p/612752963?utm_id=0 https://github.com/CVI-SZU/Linlygithub.com/CVI-SZU/ ...
- Linux 开启防火墙 避免非干系人误操作的处理
公司里面进行系统集成测试. 不想让开发能够更改我的服务器信息, 但是改密码又太麻烦了. 想了想还是用 防火墙好一些. 第一步 开启防火墙 systemctl enable firewalld syst ...
- redis 6源码解析之 sds
redis使用sds(simple dynamic string)实现了字符串的存储.sds实际上就是TLV格式的数据结构.其数据结构主要分为如下5种,主要分为首部和数据部分,首部给出了type和le ...
- 【0基础学爬虫】爬虫基础之HTTP协议的基本原理介绍
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶.逆向相关文章,为实现从易到难全方位覆盖,特设[0基础学爬 ...