Skip to content

Commit

Permalink
Stable JVM semconv implementation: the rest (#9896)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateusz Rzeszutek authored Nov 17, 2023
1 parent 683c311 commit 5d007bb
Show file tree
Hide file tree
Showing 21 changed files with 1,360 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics;
import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetricsBuilder;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil;
Expand All @@ -23,24 +24,29 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
ConfigProperties config = AutoConfigureUtil.getConfig(autoConfiguredSdk);

OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
RuntimeMetrics runtimeMetrics = null;
RuntimeMetricsBuilder builder = null;
/*
By default don't use any JFR metrics. May change this once semantic conventions are updated.
If enabled, default to only the metrics not already covered by runtime-telemetry-java8
*/
boolean defaultEnabled = config.getBoolean("otel.instrumentation.common.default-enabled", true);
if (config.getBoolean("otel.instrumentation.runtime-telemetry-java17.enable-all", false)) {
runtimeMetrics = RuntimeMetrics.builder(openTelemetry).enableAllFeatures().build();
builder = RuntimeMetrics.builder(openTelemetry).enableAllFeatures();
} else if (config.getBoolean("otel.instrumentation.runtime-telemetry-java17.enabled", false)) {
runtimeMetrics = RuntimeMetrics.create(openTelemetry);
builder = RuntimeMetrics.builder(openTelemetry);
} else if (config.getBoolean(
"otel.instrumentation.runtime-telemetry.enabled", defaultEnabled)) {
// This only uses metrics gathered by JMX
runtimeMetrics = RuntimeMetrics.builder(openTelemetry).disableAllFeatures().build();
builder = RuntimeMetrics.builder(openTelemetry).disableAllFeatures();
}

if (runtimeMetrics != null) {
RuntimeMetrics finalJfrTelemetry = runtimeMetrics;
if (builder != null) {
if (config.getBoolean(
"otel.instrumentation.runtime-telemetry.emit-experimental-telemetry", false)) {
builder.enableExperimentalJmxTelemetry();
}

RuntimeMetrics finalJfrTelemetry = builder.build();
Thread cleanupTelemetry = new Thread(() -> finalJfrTelemetry.close());
Runtime.getRuntime().addShutdownHook(cleanupTelemetry);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import io.opentelemetry.instrumentation.runtimemetrics.java8.GarbageCollector;
import io.opentelemetry.instrumentation.runtimemetrics.java8.MemoryPools;
import io.opentelemetry.instrumentation.runtimemetrics.java8.Threads;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.ExperimentalBufferPools;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.ExperimentalCpu;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.ExperimentalMemoryPools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -28,6 +31,7 @@ public final class RuntimeMetricsBuilder {
final EnumMap<JfrFeature, Boolean> enabledFeatureMap;

private boolean disableJmx = false;
private boolean enableExperimentalJmxTelemetry = false;

RuntimeMetricsBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry;
Expand Down Expand Up @@ -73,13 +77,20 @@ public RuntimeMetricsBuilder disableFeature(JfrFeature feature) {
return this;
}

/** Disable telemetry collection associated with the {@link JfrFeature}. */
/** Disable all JMX telemetry collection. */
@CanIgnoreReturnValue
public RuntimeMetricsBuilder disableAllJmx() {
disableJmx = true;
return this;
}

/** Disable telemetry collection associated with the {@link JfrFeature}. */
@CanIgnoreReturnValue
public RuntimeMetricsBuilder enableExperimentalJmxTelemetry() {
enableExperimentalJmxTelemetry = true;
return this;
}

/** Build and start an {@link RuntimeMetrics} with the config from this builder. */
public RuntimeMetrics build() {
List<AutoCloseable> observables = buildObservables();
Expand All @@ -98,9 +109,14 @@ private List<AutoCloseable> buildObservables() {
observables.addAll(BufferPools.registerObservers(openTelemetry));
observables.addAll(Classes.registerObservers(openTelemetry));
observables.addAll(Cpu.registerObservers(openTelemetry));
observables.addAll(GarbageCollector.registerObservers(openTelemetry));
observables.addAll(MemoryPools.registerObservers(openTelemetry));
observables.addAll(Threads.registerObservers(openTelemetry));
observables.addAll(GarbageCollector.registerObservers(openTelemetry));
if (enableExperimentalJmxTelemetry) {
observables.addAll(ExperimentalBufferPools.registerObservers(openTelemetry));
observables.addAll(ExperimentalCpu.registerObservers(openTelemetry));
observables.addAll(ExperimentalMemoryPools.registerObservers(openTelemetry));
}
return observables;
} catch (Exception e) {
throw new IllegalStateException("Error building RuntimeMetrics", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import io.opentelemetry.instrumentation.runtimemetrics.java8.GarbageCollector;
import io.opentelemetry.instrumentation.runtimemetrics.java8.MemoryPools;
import io.opentelemetry.instrumentation.runtimemetrics.java8.Threads;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.ExperimentalBufferPools;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.ExperimentalCpu;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.ExperimentalMemoryPools;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
Expand All @@ -35,19 +38,24 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
|| Double.parseDouble(System.getProperty("java.specification.version")) >= 17) {
return;
}

OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
List<AutoCloseable> observables = new ArrayList<>();
observables.addAll(BufferPools.registerObservers(openTelemetry));
observables.addAll(Classes.registerObservers(openTelemetry));
observables.addAll(Cpu.registerObservers(openTelemetry));
observables.addAll(GarbageCollector.registerObservers(openTelemetry));
observables.addAll(MemoryPools.registerObservers(openTelemetry));
observables.addAll(Threads.registerObservers(openTelemetry));
observables.addAll(GarbageCollector.registerObservers(openTelemetry));
Thread cleanupTelemetry =
new Thread(
() -> {
JmxRuntimeMetricsUtil.closeObservers(observables);
});

if (config.getBoolean(
"otel.instrumentation.runtime-telemetry.emit-experimental-telemetry", false)) {
observables.addAll(ExperimentalBufferPools.registerObservers(openTelemetry));
observables.addAll(ExperimentalCpu.registerObservers(openTelemetry));
observables.addAll(ExperimentalMemoryPools.registerObservers(openTelemetry));
}

Thread cleanupTelemetry = new Thread(() -> JmxRuntimeMetricsUtil.closeObservers(observables));
Runtime.getRuntime().addShutdownHook(cleanupTelemetry);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,26 @@ Register observers for the desired runtime metrics:
```java
OpenTelemetry openTelemetry = // OpenTelemetry instance configured elsewhere

BufferPools.registerObservers(openTelemetry);
Classes.registerObservers(openTelemetry);
Cpu.registerObservers(openTelemetry);
MemoryPools.registerObservers(openTelemetry);
Threads.registerObservers(openTelemetry);
GarbageCollector.registerObservers(openTelemetry);
```

## Stable JVM metrics preview

If you want to enable the preview of the stable JVM semantic conventions, you need to set either
the `otel.semconv-stability.opt-in` system property or the `OTEL_SEMCONV_STABILITY_OPT_IN`
environment variable to one of the following values:

- `jvm` - this will make the runtime metrics emit only the new, stable conventions, and stop
emitting the old experimental conventions that the instrumentation emitted previously.
- `jvm/dup` - emit both the old and the stable JVM conventions, allowing for a seamless transition.

Note that the `otel.semconv-stability.opt-in` setting is a comma-separated list, and you can specify
more than one value, e.g. `-Dotel.semconv-stability.opt-in=http,jvm`.

## Garbage Collector Dependent Metrics

The attributes reported on the memory metrics (`process.runtime.jvm.memory.*`) and gc metrics (`process.runtime.jvm.gc.*`) are dependent on the garbage collector used by the application, since each garbage collector organizes memory pools differently and has different strategies for reclaiming memory during garbage collection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import io.opentelemetry.instrumentation.api.internal.SemconvStability;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
Expand Down Expand Up @@ -48,6 +50,11 @@ public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry)
// Visible for testing
static List<AutoCloseable> registerObservers(
OpenTelemetry openTelemetry, List<BufferPoolMXBean> bufferBeans) {

// buffer pool metrics are experimental in the new semconv
if (!SemconvStability.emitOldJvmSemconv()) {
return Collections.emptyList();
}
List<AutoCloseable> observables = new ArrayList<>();
Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry);
observables.add(
Expand Down
Loading

0 comments on commit 5d007bb

Please sign in to comment.