content: /*
   * Copyright The OpenTelemetry Authors
   * SPDX-License-Identifier: Apache-2.0
   */
  
  package io.opentelemetry.instrumentation.runtimemetrics.java8.internal;
  
  import io.opentelemetry.api.OpenTelemetry;
  import io.opentelemetry.api.metrics.Meter;
  import java.lang.management.ManagementFactory;
  import java.lang.management.OperatingSystemMXBean;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.function.Supplier;
  import javax.annotation.Nullable;
  
  /**
   * Registers measurements that generate experimental metrics about CPU.
   *
   * <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
   * at any time.
   */
  public final class ExperimentalCpu {
  
    /** Register observers for java runtime experimental CPU metrics. */
    public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry) {
      return registerObservers(
          openTelemetry,
          ManagementFactory.getOperatingSystemMXBean(),
          CpuMethods.systemCpuUtilization());
    }
  
    // Visible for testing
    static List<AutoCloseable> registerObservers(
        OpenTelemetry openTelemetry,
        OperatingSystemMXBean osBean,
        @Nullable Supplier<Double> systemCpuUtilization) {
  
      Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry);
      List<AutoCloseable> observables = new ArrayList<>();
      observables.add(
          meter
              .gaugeBuilder("jvm.system.cpu.load_1m")
              .setDescription(
                  "Average CPU load of the whole system for the last minute as reported by the JVM.")
              .setUnit("{run_queue_item}")
              .buildWithCallback(
                  observableMeasurement -> {
                    double loadAverage = osBean.getSystemLoadAverage();
                    if (loadAverage >= 0) {
                      observableMeasurement.record(loadAverage);
                    }
                  }));
      if (systemCpuUtilization != null) {
        observables.add(
            meter
                .gaugeBuilder("jvm.system.cpu.utilization")
                .setDescription("Recent CPU utilization for the whole system as reported by the JVM.")
                .setUnit("1")
                .buildWithCallback(
                    observableMeasurement -> {
                      Double cpuUsage = systemCpuUtilization.get();
                      if (cpuUsage != null && cpuUsage >= 0) {
                        observableMeasurement.record(cpuUsage);
                      }
                    }));
      }
      return observables;
    }
  
    private ExperimentalCpu() {}
  }
  