auto-log
auto-logЭто система автоматического мониторинга журналов, разработанная для java.
творческая цель
Я часто пишу какие-то инструменты, и иногда очень хлопотно вручную добавлять какие-то логи, а введение 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;
}
Базовая реализация АОП
Класс 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, а потребление времени превышает сконфигурированное значение, будет выведен журнал медленной работы. |
Весенняя интеграция
Полная ссылка на пример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
адрес с открытым исходным кодом
Gitee: git ee.com/houbinbin/ah...
Добро пожаловать в форк/звезду~