数据统计埋点需求
背景
随着公司代码的迭代,有一些垃圾代码逻辑冗余在项目中,导致消耗了资源又不好维护。为了保险,需要在线上统计代码使用的频率,剔除无用代码。
描述
方法便可分为如下几种:
- 对于确定没用的代码,可以先注释掉,并替换为
error
日志,保证遇到问题及时发现。 - 对疑似无用代码,可以使用统计方法调用次数,运行一段时间,判断去留。
设计
第一种方法就是,注释代码添加日志,所以我们着重描述第二种情况:
使用 spring aop
进行拦截,注意只能拦截被 ioc
管理的对象
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CountInvokeTimes {
}
@Aspect
@Slf4j
@Component
public class CountInvokedTimesAspect {
private final RedisUtils redisUtil;
public CountInvokedTimesAspect(RedisUtils redisUtil) {
this.redisUtil = redisUtil;
}
@Pointcut("@within(com.tao.annotation.CountInvokeTimes) || @annotation(com.tao.annotation.CountInvokeTimes)")
public void countInvokeTimes() {
}
@Around(value = "countInvokeTimes()")
public Object doAround(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
Class<?>[] argTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
argTypes[i] = args[i].getClass();
}
try {
String methodName = joinPoint.getSignature().getName();
Method method = joinPoint.getTarget().getClass().getMethod(methodName, argTypes);
Class<?> aClass = joinPoint.getTarget().getClass();
String className = aClass.getName();
boolean isClassAnnotationPresent = aClass.isAnnotationPresent(CountInvokeTimes.class);
boolean isMethodAnnotationPresent = method.isAnnotationPresent(CountInvokeTimes.class);
if (isClassAnnotationPresent || isMethodAnnotationPresent) {
// 此处也可以发送mq消息给统计服务
redisUtil.getRedisTemplate().opsForZSet().incrementScore(RedisConstant.METHOD_STATISTICS, className + "." + methodName, 1);
}
} catch (Exception e) {
log.error("CountInvokedTimesAspect error", e);
}
Object object = null;
try {
object = joinPoint.proceed();
} catch (Throwable throwable) {
log.error("CountInvokedTimesAspect error", throwable);
}
return object;
}
}
@RequestMapping("/getMethodStatistics")
public String getMethodStatistics() {
Set<ZSetOperations.TypedTuple<String>> typedTuples = redisUtils.getRedisTemplate().opsForZSet().rangeWithScores(RedisConstant.METHOD_STATISTICS, 0, -1);
return JSON.toJSONString(typedTuples);
}
本文来自博客园,作者:帅气的涛啊,转载请注明原文链接:https://www.cnblogs.com/handsometaoa/p/18038798