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 Inventor的tcp连接扩展插件ClientSocketAl2Ext
参考原文:https://www.cnblogs.com/bemfa/p/13390251.html 下载地址:https://wwtl.lanzoum.com/ik0Ky1clu41a B站关联学习 ...
- Oracle实例的启动和关闭
启动模式 1.NoMount 模式(启动实例不加载数据库) 命令:startup nomount 讲解:这种启动模式只会创建实例,并不加载数据库,Oracle仅为实例创建各种内存结构和服务进程,不会打 ...
- 2023年江苏“领航杯”MISC一个很有意思的题目(别把鸡蛋放在同一个篮子里面)
别把鸡蛋放在同一个篮子里面 题目附件:https://wwzl.lanzoue.com/i6HmX16finnc 1.题目信息 解压压缩包打开附件,获得5141个txt文档,每个文档都有内容,发现是b ...
- IDEA:端口号被占用解决办法
idea遇到这样的问题:如下图 解决办法 步骤1:通过端口号找到pid打开dos命令行,输入netstat -ano | find "9009"得到下列内容,看到最后一行就是pid ...
- [转帖]awk的printf格式化输出
https://www.cnblogs.com/chanix/p/12738097.html awk的printf格式化输出20121108 Chenxincat sort_result.txt223 ...
- [转帖]perf学习-linux自带性能分析工具
目前在做性能分析的事情,之前没怎么接触perf,找了几篇文章梳理了一下,按照问题的形式记录在这里. 方便自己查看. 什么是perf? linux性能调优工具,32内核以上自带的工具,软件性能分析. ...
- [转帖]Rocksdb的优劣及应用场景分析
研究Rocksdb已经有七个月的时间了,这期间阅读了它的大部分代码,对底层存储引擎进行了适配,同时也做了大量的测试.在正式研究之前由于对其在本地存储引擎这个江湖地位的膜拜,把它想象的很完美,深入摸 ...
- 【转帖】10个Linux 系统性能监控命令行工具
引言: 系统一旦跑起来,我们就希望它能够稳定运行,不要宕机,不出现速度变慢.因此,对于Linux 系统管理员来说每天监控和调试 Linux 系统的性能问题是一项繁重却又重要的工作.监控和保持系统启动并 ...
- [转帖]Intel、海光、鲲鹏920、飞腾2500 CPU性能对比
https://plantegg.github.io/2021/06/18/%E5%87%A0%E6%AC%BECPU%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94/ Int ...
- 通过写脚本的方式自动获取JVM内的进程堆栈信息等内容
公司转java之后 经常会遇到java进程占用CPU特别多的情况. 每次连上机器进行处理都比较慢了. 索性自己写一个脚本, 把想要查询的信息直接汇总进去. 这样的话 就简单很多了. 脚本也很简单主要如 ...