项目:
我使用 Sflow + Ganglia 来监控 Websphere Application Server (WAS) 的 JVM 指标。WAS 使用 AspectJ 方面进行检测。我添加了一个方面来测量所有应用程序方法运行时。
我使用 Hsflowd 作为 JVM 指标收集器。Hsflowd 在内部使用JMX-SflowAgent javaagent 挂钩到 JVM 以使用 MXBean(RuntimeMXBean、GarbageCollectorMXBean、CompilationMXBean 和 ThreadMXBean)收集指标。
问题:
当我在没有 aspectjweaver 挂钩的情况下运行 WAS 时,我可以连续查看 Ganglia Web 中的所有指标(CPU、桌面、内存、进程等)。但是当将 aspectjweaver 添加到 JVM args 并重新启动服务器后,我可以看到 10 分钟的指标,但之后它不会在 Ganglia web 中报告 JVM 指标。
在 Aspectj 编织日志中,我可以看到 AspectJ 正在编织 JMXsflowAgent 代码。即使它被排除在外!call(* com.sflow.JMX.SFlowAgent(..))
。
方面:
package com.foo.main;
import java.io.*;
import java.lang.reflect.Method;
import java.security.Signature;
import java.util.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.osgi.service.application.ApplicationAdminPermission;
@Aspect
public class ResponseTimeAspect {
@Pointcut(
"execution(* com.foo.*(..)) && " +
"!within(com.foo.main.ResponseTimeAspect) && " +
"!within(ThreadLocal+) && " +
"!within(&& !within(*..*Aspect)) && " +
"!within(com.foo.main.AppInformationReader) && " +
"!within(@org.aspectj.lang.annotation.Aspect *) && " +
"!within(com.sflow.jmx.SFlowAgent) && " +
"!(call( * com.sflow.jmx.SFlowAgent(..)))"
)
public void loggingResponseTime() {}
private static ThreadLocal<String> uuidContainer = new ThreadLocal<String>() {
@Override
protected String initialValue(){
return UUID.randomUUID().toString();
}
};
AppInformationReader logWriter = AppInformationReader.getInstance();
@Around("loggingResponseTime()")
public Object tracing(ProceedingJoinPoint thisJoinPoint) throws Throwable {
Long startTime= System.currentTimeMillis();
Long startTotalMemory = Runtime.getRuntime().totalMemory();
Long startFreeMemory = Runtime.getRuntime().freeMemory();
Object ret = thisJoinPoint.proceed();
Long elapsedTime=System.currentTimeMillis() - startTime;
Long endTotalMemory = Runtime.getRuntime().totalMemory();
Long endFreeMemory = Runtime.getRuntime().freeMemory();
String methodSignature=thisJoinPoint.getSignature().toString();
String classname=methodSignature.split("\\.")[thisJoinPoint.getSignature().toString().split("\\.").length-1];
String methodName =thisJoinPoint.getSignature().getDeclaringType().getCanonicalName();
logWriter.writeLog(uuidContainer.get().toString(), startTime, System.currentTimeMillis(), elapsedTime, classname, methodName);
return ret;
}
}
JMX 包位于com.sflow.jmx.SFlowAgent
.