我想集中API性能测量逻辑 - 是否有优雅,高效的解决方案?
假设我们有这个API:
public interface MyApi {
void zero();
Long one(String a);
String two(Long a, Long b);
}
我想使用一个简单的测量包装器测量此API实现的性能:
public class MyApiImpl implements MyApi{
// ...
public Long one(String a) {
Long start = System.nanoTime();
try {
return oneImpl(a);
} finally {
Measure.record(System.nanoTime()-start, "one", a);
}
}
// ...
}
但是我没有在每个API实现中重复这个测量包装器逻辑,而是想集中它,例如,一个有效的注释将是一个优雅的解决方案:
public class MyApiImpl implements MyApi{
// ...
@Measure
public Long one(String a) {
// ...
}
// ...
}
具有Measure
的API位于Linux开发,登台和生产环境中,并且全天候启用。有谁愿意分享好的解决方案?
注意:我特别不是在寻找“解决”这个问题的“打包软件解决方案”,无论是商业还是开源。问题是如何在呼叫站点有效和优雅地解决数据收集问题,即什么是程序化解决方案,例如,有效的注释。
答案 0 :(得分:2)
我使用方面和Dropwizard指标做了类似的事情。首先为Timed注释创建一个方面,
@Aspect
@Component
public class TimedAspect {
private MetricRegistry registry;
@Autowired
public TimedAspect(MetricRegistry registry) {
this.registry = registry;
}
@Around("@annotation(annotation) || @within(annotation)")
public Object generateMetric(
final ProceedingJoinPoint pointcut,
final Timed annotation) throws Throwable {
Timed anno = getAnnotation(pointcut, annotation);
String metricName = ...;
final Timer timer = registry.timer(metricName);
final Timer.Context context = timer.time();
try {
return pointcut.proceed();
} finally {
context.stop();
}
}
...
}
现在,您可以在班级的任何位置使用@Timed
注释
public class MyApiImpl implements MyApi {
// ...
@Timed
public Long one(String a) {
// ...
}
// ...
}
我有一个工作示例here。