Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,56 @@ runtimeOnly("io.opentelemetry.instrumentation:opentelemetry-runtime-telemetry-ja

### Usage

Register observers for the desired runtime metrics:
Register JVM runtime metrics:

```java
OpenTelemetry openTelemetry = // OpenTelemetry instance configured elsewhere

Classes.registerObservers(openTelemetry);
Cpu.registerObservers(openTelemetry);
MemoryPools.registerObservers(openTelemetry);
Threads.registerObservers(openTelemetry);
GarbageCollector.registerObservers(openTelemetry);
RuntimeMetrics runtimeMetrics = RuntimeMetrics.create(openTelemetry);

// When done, close to stop metric collection
runtimeMetrics.close();
```

To select specific metrics, configure [metric views](https://opentelemetry.io/docs/languages/java/sdk/#views)
on the SDK to filter or customize which metrics are exported.

For example, using [declarative configuration](https://github.com/open-telemetry/opentelemetry-java-examples/tree/main/declarative-configuration):

```yaml
meter_provider:
views:
# Drop jvm.memory.committed metric
- selector:
instrument_name: jvm.memory.committed
stream:
aggregation:
drop:
# Only retain jvm.memory.type attribute on jvm.memory.used
- selector:
instrument_name: jvm.memory.used
stream:
attribute_keys:
included:
- jvm.memory.type
```

To retain only `jvm.memory.used` and drop all other JVM runtime metrics:

```yaml
meter_provider:
views:
# Drop all metrics from this instrumentation scope
- selector:
meter_name: io.opentelemetry.runtime-telemetry-java8
stream:
aggregation:
drop:
# Keep jvm.memory.used (views are additive, this creates a second stream)
- selector:
meter_name: io.opentelemetry.runtime-telemetry-java8
instrument_name: jvm.memory.used
stream: {}
```

## Garbage Collector Dependent Metrics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,74 +6,21 @@
package io.opentelemetry.instrumentation.runtimemetrics.java8;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;

/**
* Registers measurements that generate metrics about JVM classes. The metrics generated by this
* class follow <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/runtime/jvm-metrics.md">the
* stable JVM metrics semantic conventions</a>.
* Registers measurements that generate metrics about JVM classes.
*
* <p>Example usage:
*
* <pre>{@code
* Classes.registerObservers(GlobalOpenTelemetry.get());
* }</pre>
*
* <p>Example metrics being exported:
*
* <pre>
* jvm.class.loaded 100
* jvm.class.unloaded 2
* jvm.class.count 98
* </pre>
* @deprecated Use {@link RuntimeMetrics} instead, and configure metric views to select specific
* metrics.
*/
@Deprecated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if your goal is just to move these to internal then maybe it would be easier to move the class, drop final, add deprecated class in original location that extends the moved class

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in cfbec4d

public final class Classes {

// Visible for testing
static final Classes INSTANCE = new Classes();

/** Register observers for java runtime class metrics. */
public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry) {
return INSTANCE.registerObservers(openTelemetry, ManagementFactory.getClassLoadingMXBean());
}

// Visible for testing
List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry, ClassLoadingMXBean classBean) {
Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry);
List<AutoCloseable> observables = new ArrayList<>();

observables.add(
meter
.counterBuilder("jvm.class.loaded")
.setDescription("Number of classes loaded since JVM start.")
.setUnit("{class}")
.buildWithCallback(
observableMeasurement ->
observableMeasurement.record(classBean.getTotalLoadedClassCount())));
observables.add(
meter
.counterBuilder("jvm.class.unloaded")
.setDescription("Number of classes unloaded since JVM start.")
.setUnit("{class}")
.buildWithCallback(
observableMeasurement ->
observableMeasurement.record(classBean.getUnloadedClassCount())));
observables.add(
meter
.upDownCounterBuilder("jvm.class.count")
.setDescription("Number of classes currently loaded.")
.setUnit("{class}")
.buildWithCallback(
observableMeasurement ->
observableMeasurement.record(classBean.getLoadedClassCount())));

return observables;
return io.opentelemetry.instrumentation.runtimemetrics.java8.internal.Classes.registerObservers(
openTelemetry);
}

private Classes() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,100 +6,21 @@
package io.opentelemetry.instrumentation.runtimemetrics.java8;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.CpuMethods;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
import javax.annotation.Nullable;

/**
* Registers measurements that generate metrics about CPU. The metrics generated by this class
* follow <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/runtime/jvm-metrics.md">the
* stable JVM metrics semantic conventions</a>.
* Registers measurements that generate metrics about CPU.
*
* <p>Example usage:
*
* <pre>{@code
* Cpu.registerObservers(GlobalOpenTelemetry.get());
* }</pre>
*
* <p>Example metrics being exported:
*
* <pre>
* jvm.cpu.time 20.42
* jvm.cpu.count 8
* jvm.cpu.recent_utilization 0.1
* </pre>
* @deprecated Use {@link RuntimeMetrics} instead, and configure metric views to select specific
* metrics.
*/
@Deprecated
public final class Cpu {

// Visible for testing
static final Cpu INSTANCE = new Cpu();

private static final double NANOS_PER_S = TimeUnit.SECONDS.toNanos(1);

/** Register observers for java runtime CPU metrics. */
public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry) {
return INSTANCE.registerObservers(
openTelemetry,
Runtime.getRuntime()::availableProcessors,
CpuMethods.processCpuTime(),
CpuMethods.processCpuUtilization());
}

// Visible for testing
List<AutoCloseable> registerObservers(
OpenTelemetry openTelemetry,
IntSupplier availableProcessors,
@Nullable Supplier<Long> processCpuTime,
@Nullable Supplier<Double> processCpuUtilization) {
Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry);
List<AutoCloseable> observables = new ArrayList<>();

if (processCpuTime != null) {
observables.add(
meter
.counterBuilder("jvm.cpu.time")
.ofDoubles()
.setDescription("CPU time used by the process as reported by the JVM.")
.setUnit("s")
.buildWithCallback(
observableMeasurement -> {
Long cpuTimeNanos = processCpuTime.get();
if (cpuTimeNanos != null && cpuTimeNanos >= 0) {
observableMeasurement.record(cpuTimeNanos / NANOS_PER_S);
}
}));
}
observables.add(
meter
.upDownCounterBuilder("jvm.cpu.count")
.setDescription("Number of processors available to the Java virtual machine.")
.setUnit("{cpu}")
.buildWithCallback(
observableMeasurement ->
observableMeasurement.record(availableProcessors.getAsInt())));
if (processCpuUtilization != null) {
observables.add(
meter
.gaugeBuilder("jvm.cpu.recent_utilization")
.setDescription("Recent CPU utilization for the process as reported by the JVM.")
.setUnit("1")
.buildWithCallback(
observableMeasurement -> {
Double cpuUsage = processCpuUtilization.get();
if (cpuUsage != null && cpuUsage >= 0) {
observableMeasurement.record(cpuUsage);
}
}));
}

return observables;
return io.opentelemetry.instrumentation.runtimemetrics.java8.internal.Cpu.registerObservers(
openTelemetry);
}

private Cpu() {}
Expand Down
Loading
Loading