聊聊skywalking的CPUProvider

本文主要研究一下skywalking的CPUProvider

CPUProvider

skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/cpu/CPUProvider.java

public enum CPUProvider {
    INSTANCE;
    private CPUMetricsAccessor cpuMetricsAccessor;

    CPUProvider() {
        int processorNum = ProcessorUtil.getNumberOfProcessors();
        try {
            this.cpuMetricsAccessor =
                (CPUMetricsAccessor)CPUProvider.class.getClassLoader().loadClass("org.apache.skywalking.apm.agent.core.jvm.cpu.SunCpuAccessor")
                    .getConstructor(int.class).newInstance(processorNum);
        } catch (Exception e) {
            this.cpuMetricsAccessor = new NoSupportedCPUAccessor(processorNum);
            ILog logger = LogManager.getLogger(CPUProvider.class);
            logger.error(e, "Only support accessing CPU metrics in SUN JVM platform.");
        }
    }

    public CPU getCpuMetric() {
        return cpuMetricsAccessor.getCPUMetrics();
    }
}
复制代码
  • CPUProvider的构造会实例化org.apache.skywalking.apm.agent.core.jvm.cpu.SunCpuAccessor;其getCpuMetric则通过cpuMetricsAccessor.getCPUMetrics()获取CPU信息

CPUMetricsAccessor

skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/cpu/CPUMetricsAccessor.java

public abstract class CPUMetricsAccessor {
    private long lastCPUTimeNs;
    private long lastSampleTimeNs;
    private final int cpuCoreNum;

    public CPUMetricsAccessor(int cpuCoreNum) {
        this.cpuCoreNum = cpuCoreNum;
    }

    protected void init() {
        lastCPUTimeNs = this.getCpuTime();
        lastSampleTimeNs = System.nanoTime();
    }

    protected abstract long getCpuTime();

    public CPU getCPUMetrics() {
        long cpuTime = this.getCpuTime();
        long cpuCost = cpuTime - lastCPUTimeNs;
        long now = System.nanoTime();

        try {
            CPU.Builder cpuBuilder = CPU.newBuilder();
            return cpuBuilder.setUsagePercent(cpuCost * 1.0d / ((now - lastSampleTimeNs) * cpuCoreNum) * 100).build();
        } finally {
            lastCPUTimeNs = cpuTime;
            lastSampleTimeNs = now;
        }
    }
}
复制代码
  • CPUMetricsAccessor是个抽象类,它定义了lastCPUTimeNs、lastSampleTimeNs属性,其getCPUMetrics方法则通过cpuCost * 1.0d / ((now - lastSampleTimeNs) * cpuCoreNum) * 100计算usagePercent;其getCpuTime为抽象方法

SunCpuAccessor

skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/cpu/SunCpuAccessor.java

public class SunCpuAccessor extends CPUMetricsAccessor {
    private final OperatingSystemMXBean osMBean;

    public SunCpuAccessor(int cpuCoreNum) {
        super(cpuCoreNum);
        this.osMBean = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
        this.init();
    }

    @Override
    protected long getCpuTime() {
        return osMBean.getProcessCpuTime();
    }
}
复制代码
  • SunCpuAccessor继承了CPUMetricsAccessor,它通过ManagementFactory.getOperatingSystemMXBean()的getProcessCpuTime来实现getCpuTime方法

小结

CPUProvider的构造会实例化org.apache.skywalking.apm.agent.core.jvm.cpu.SunCpuAccessor;其getCpuMetric则通过cpuMetricsAccessor.getCPUMetrics()获取CPU信息(usagePercent)

doc

猜你喜欢

转载自juejin.im/post/5e5508c06fb9a07cba0ee513