java 注解结合 spring aop 实现自动输出日志
auto-log
auto-log 是一款为 java 设计的自动日志监控框架。
创作目的
经常会写一些工具,有时候手动加一些日志很麻烦,引入 spring 又过于大材小用。
所以希望从从简到繁实现一个工具,便于平时使用。
特性
基于注解+字节码,配置灵活
自动适配常见的日志框架
支持编程式的调用
支持注解式,完美整合 spring
支持整合 spring-boot
支持慢日志阈值指定,耗时,入参,出参,异常信息等常见属性指定
核心原理
注解定义
import java.lang.annotation.*;
/**
* 自动注解
* @author binbin.hou
* @since 0.0.1
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface AutoLog {
/**
* 输出参数
* @return 参数
* @since 0.0.1
*/
boolean param() default true;
/**
* 是否输出结果
* @return 结果
* @since 0.0.1
*/
boolean result() default true;
/**
* 是否输出时间
* @return 耗时
* @since 0.0.1
*/
boolean costTime() default false;
/**
* 是否输出异常信息
* @return 是否
* @since 0.0.6
*/
boolean exception() default true;
/**
* 慢日志阈值
*
* 当值小于 0 时,不进行慢日志统计。
* 当值大于等于0时,当前值只要大于等于这个值,就进行统计。
* @return 阈值
* @since 0.0.4
*/
long slowThresholdMills() default -1;
}
核心 AOP 实现
这里的 LogFactory 类是关键,可以兼容目前大部分的日志框架。
import com.github.houbb.auto.log.annotation.AutoLog;
import com.github.houbb.heaven.response.exception.CommonRuntimeException;
import com.github.houbb.log.integration.core.Log;
import com.github.houbb.log.integration.core.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* 这是一种写法
* 自动日志输出 aop
* @author binbin.hou
* @since 0.0.3
*/
@Aspect
@Component
@EnableAspectJAutoProxy
public class AutoLogAop {
private static final Log LOG = LogFactory.getLog(AutoLogAop.class);
/**
* 执行核心方法
*
* 相当于 MethodInterceptor
* @param point 切点
* @param autoLog 日志参数
* @return 结果
* @throws Throwable 异常信息
* @since 0.0.3
*/
@Around("@annotation(autoLog)")
public Object around(ProceedingJoinPoint point, AutoLog autoLog) throws Throwable {
Method method = getCurrentMethod(point);
String methodName = method.getName();
try {
final long startMills = System.currentTimeMillis();
//1. 是否输入入参
if (autoLog.param()) {
LOG.info("{} param is {}.", methodName, Arrays.toString(point.getArgs()));
}
//2. 执行方法
Object result = point.proceed();
//3. 结果
if (autoLog.result()) {
LOG.info("{} result is {}.", methodName, result);
}
//3.1 耗时
final long slowThreshold = autoLog.slowThresholdMills();
if (autoLog.costTime() || slowThreshold >= 0) {
final long endMills = System.currentTimeMillis();
long costTime = endMills - startMills;
if (autoLog.costTime()) {
LOG.info("{} cost time is {}ms.", methodName, costTime);
}
//3.2 慢日志
if (slowThreshold >= 0 && costTime >= slowThreshold) {
LOG.warn("{} is slow log, {}ms >= {}ms.", methodName, costTime, slowThreshold);
}
}
return result;
} catch (Throwable e) {
if(autoLog.exception()) {
LOG.error("{} meet ex.", methodName, e);
}
throw e;
}
}
/**
* 获取当前方法信息
*
* @param point 切点
* @return 方法
*/
private Method getCurrentMethod(ProceedingJoinPoint point) {
try {
Signature sig = point.getSignature();
MethodSignature msig = (MethodSignature) sig;
Object target = point.getTarget();
return target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new CommonRuntimeException(e);
}
}
}
快速开始
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;
}
}
注解说明
核心注解 @AutoLog 的属性说明如下:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| param | boolean | true | 是否打印入参 |
| result | boolean | true | 是否打印出参 |
| costTime | boolean | false | 是否打印耗时 |
| exception | boolean | true | 是否打印异常 |
| slowThresholdMills | long | -1 | 当这个值大于等于 0 时,且耗时超过配置值,会输出慢日志 |
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
开源地址
欢迎 fork/star~
java 注解结合 spring aop 实现自动输出日志的更多相关文章
- 基于注解的Spring AOP的配置和使用
摘要: 基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不 ...
- 基于注解的Spring AOP的配置和使用--转载
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- Java动态代理-->Spring AOP
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...
- 基于注解的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 Boot 2.X(八):Spring AOP 实现简单的日志切面
AOP 1.什么是 AOP ? AOP 的全称为 Aspect Oriented Programming,译为面向切面编程,是通过预编译方式和运行期动态代理实现核心业务逻辑之外的横切行为的统一维护的一 ...
- spring boot使用slf4j输出日志
spring boot使用slf4j输出日志 https://blog.csdn.net/qq442270636/article/details/79406346 Spring Boot SLF4J日 ...
- 【java自定义注解2】java自定义注解结合Spring AOP
承接上一篇,注解应用于属性,本篇定义了一个用于方法的注解,结合Spring AOP 实现 切面编程. 以下demo演示使用了SpringBoot,与SSM中使用方式大致相同,效果如下: 1.自定义注解 ...
- 基于注解的Spring AOP入门、增强Advice实例
这篇文章简单通过一个例子,介绍几种增强的基本配置,以方便spring框架初学者对aop的代码结构有个清楚的了解认识.首先,spring支持aop编程,支持aspectJ的语法格式来表示切入点,切面,增 ...
- spring AOP知识点总结以及日志的输出
AOP的作用就是在基于OCP在不改变原有系统核心业务代码的基础上动态添加一些扩展功能.通常应用于日志的处理,事务处理,权限处理,缓存处理等等 首先,使用AOP需要添加的依赖有:spring-conte ...
随机推荐
- Linux查看文件内容与处理文件
Linux查看文件内容与处理文件 目录 Linux查看文件内容与处理文件 查看文件内容 1.查看文件类型 2.查看整个文件 3.查看部分文件 处理文件 1.创建空文件 2.过滤文件内容 3.统计文件内 ...
- 03-Tcl数学表达式及expr命令
3 Tcl书写表达式及expr命令 Tcl提供了有效的数学运算和逻辑运算功能.通过expr可以实现对数学表达式的分析和计算. 3.1 数学与逻辑运算符 运算符 说明 - + ~ ! 一元减(取负).一 ...
- Go-单元测试-Test
单元测试 文件名以 _test.go 结尾 函数名以 Test 开头 函数参数固定 t *testing.T 运行单元测试 go test Demo 源文件 package unit import & ...
- [转帖]使用 TiDB 读取 TiFlash
https://docs.pingcap.com/zh/tidb/stable/use-tidb-to-read-tiflash 本文档介绍如何使用 TiDB 读取 TiFlash 副本. TiDB ...
- [转帖]configure: error: cannot guess build type;you must specify one
该问题一般出现在国产平台,从错误描述来看,意思是:无法猜测build类型,你必须指定一个. 解决办法: 1. 在系统/usr路径下搜索 config.guess 和 config.sub 这两个文件. ...
- [转帖]Nacos的版本支持情况
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 由于 Spring ...
- vim配置的学习与总结
摘要 有时候在linux里面操作需要使用粘贴以及其他处理. 很多发行版, 遇到 # 会自动退格, 很难受. 想着能够处理一下vim的默认设置可以好很多. 所以这里简单总结一下. 配置文件 vim的配置 ...
- Linux KVM网络处理过程
Linux KVM网络处理过程 总体解决方法 本次遇到的问题是KVM的网桥处理不小心导致系统无法连接.处理简要总结: 进入机房,给IPMI插上网线, 开机点 Del 进入bios 设置IMPI的地址 ...
- 学习: Linux的 date 命令
date 命令非常好用 多用 date --h 还是非常好的 获取 今天是今年的第多少天 最简单的办法 就是 date +%j 以后需要多学习 多利用 linux的帮助才可以呢. Usage: dat ...
- 京东金融APP-新交互技术“虚拟数字人”赋能世界杯主题营销
作者:平台研发部,智能服务与产品部 距离加文·伍德提出web3.0已经过去8年时间,这8年加文·伍德创建的以太坊大放异彩,同时由web3.0引出的数字人.元宇宙也生根发芽,茁壮成长,带来了非凡的用户体 ...