annotation java log_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 引入

com.github.houbb

auto-log-core

${最新版本}

入门案例

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 整合使用

注解声明

使用 @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~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值