Java 如何删除时间测量逻辑
我需要计算一些方法的执行时间。这些是类中的私有方法,因此Spring AOP不合适。现在代码看起来像这样Java 如何删除时间测量逻辑,java,spring,spring-aop,Java,Spring,Spring Aop,我需要计算一些方法的执行时间。这些是类中的私有方法,因此Spring AOP不合适。现在代码看起来像这样 public void method() { StopWatch sw = new StopWatch(); sw.start(); innerMethod1(); sw.stop(); Monitoring.add("eventType1", sw.getLastTaskTimeMillis()
public void method() {
StopWatch sw = new StopWatch();
sw.start();
innerMethod1();
sw.stop();
Monitoring.add("eventType1", sw.getLastTaskTimeMillis());
sw.start();
innerMethod2("abs");
sw.stop();
Monitoring.add("eventType2", sw.getLastTaskTimeMillis());
sw.start();
innerMethod3(5, 29);
sw.stop();
Monitoring.add("eventType3", sw.getLastTaskTimeMillis());
}
但是带有时间度量的插入适合于业务逻辑。有什么解决办法吗?这些数据随后将记录在grafana的数据库中。我正在寻找AspectJ,但启动应用程序时无法传递键
当在不支持或现有LoadTimeWeaver实现不支持的环境中需要类插装时,JDK代理可以是唯一的解决方案。对于这种情况,Spring提供了InstrumentationLoadTimeWeaver,它需要一个特定于Spring的(但非常通用的)VM代理,org.springframework.instrument-{version}.jar(以前名为Spring agent.jar)。
要使用它,必须通过提供以下JVM选项,使用Spring代理启动虚拟机:
-javaagent:/path/to/org.springframework.instrument-{version}.jar
马克·布拉姆尼克 如果我没弄错的话,那就找方法吧
private List<String> innerMethod3(int value, int count) {
//
}
private String innerMethod2(String event) {
//
}
私有列表innerMethod3(int值,int计数){
//
}
私有字符串innerMethod2(字符串事件){
//
}
需要方法
public <T, R, U> U timed(T value, R count, BiFunction<T, R, U> function) {
long start = System.currentTimeMillis();
U result = function.apply(value, count);
Monitoring.add("method", System.currentTimeMillis() - start);
return result;
}
public <T, R> R timed(T value, Function<T, R> function) {
long start = System.currentTimeMillis();
R result = function.apply(value);
Monitoring.add("method", System.currentTimeMillis() - start);
return result;
}
公共U定时(T值、R计数、双功能){
长启动=System.currentTimeMillis();
U结果=函数。应用(值、计数);
Monitoring.add(“方法”,System.currentTimeMillis()-start);
返回结果;
}
公共R定时(T值,函数){
长启动=System.currentTimeMillis();
R结果=函数。应用(值);
Monitoring.add(“方法”,System.currentTimeMillis()-start);
返回结果;
}
和调用方法:
List<String> timed = timed(5, 5, this::innerMethod3);
String string = timed("string", this::innerMethod2);
List timed=timed(5,5,this::innerMethod3);
String String=timed(“String”,this::innerMethod2);
但是,如果method4有4个参数,那么我需要一种新的测量时间的方法和一个新的功能接口可以采取很多方法,但都可以归结为重构 方法1:
class Timed {
public static void timed(String name, Runnable codeBlock) {
long from = System.currentTimeMillis();
codeBlock.run();
long to = System.currentTimeMillis();
System.out.println("Monitored: " + name + " : " + (to - from) + " ms");
}
public static <T> T timed(String name, Supplier<T> codeBlock) {
long from = System.currentTimeMillis();
T result = codeBlock.get();
long to = System.currentTimeMillis();
System.out.println("Monitored: " + name + " : " + (to - from) + " ms");
return result;
}
}
另一种方法
将代码重构为公共方法,并与已有注释支持的方法集成(请参阅)
我不知道监控是什么,但测微计已经包含了与普罗米修斯(以及其他类似的产品,可以存储度量值,后来从格拉法纳使用)的集成,它将测量值的数学模型保存在内存中,不会将每次测量的信息保存在内存中。在自定义实现中,它是一个需要维护的复杂代码
更新1
不,您弄错了,您不需要维护不同版本的timed
——您只需要我在解决方案中提供的两个版本。在问题中介绍的情况下,您甚至不需要第二个版本的timed
您的代码将成为:
public void method() {
Timed.timed("eventType1", () -> {
innerMethod1();
});
Timed.timed("eventType2", () -> {
innerMethod2("abs");
});
Timed.timed("eventType3", () -> {
innerMethod3(5, 29);
});
}
如果您实际从“定时”代码返回某些值,则需要第二个版本:
例如:
假设您有返回字符串的innerMethod4
,那么您将编写以下代码:
String result = Timed.timed("eventType3", () -> {
return innerMethod4(5, 29);
});
谢谢,我一直在考虑第一个选择。不幸的是,几乎所有的方法都有不同的签名。事实证明,每种方法都需要另一种方法来包装它,你确定吗?第一个解决方案在代码块级别工作,代码块可以包括一个或多个方法调用,并且不依赖于方法签名。。。你能提供一个不同方法的例子吗(请随时更新问题并在这里发表评论,以便我可以跟踪)…@Violetta:请查看我答案上的更新,如果有帮助请告诉我……非常感谢。我明白你的意思。这正是我要找的,你添加了一个spring aop标签。您可以在这里或在WWW的其余部分找到几十个springaop计时和日志的示例。如果您担心springaop无法在同一个类中截获内部方法调用,只需使用AspectJ即可。它很容易实现,就像典型的AOP新手的练习任务一样。
String result = Timed.timed("eventType3", () -> {
return innerMethod4(5, 29);
});