diff --git a/.fossa.yml b/.fossa.yml index acc066c7adf1..38d672ebf0e1 100644 --- a/.fossa.yml +++ b/.fossa.yml @@ -274,6 +274,12 @@ targets: - type: gradle path: ./ target: ':instrumentation:rmi:javaagent' + - type: gradle + path: ./ + target: ':instrumentation:runtime-telemetry:javaagent' + - type: gradle + path: ./ + target: ':instrumentation:runtime-telemetry:library' - type: gradle path: ./ target: ':instrumentation:scala-fork-join-2.8:javaagent' diff --git a/buildscripts/checkstyle.xml b/buildscripts/checkstyle.xml index 1513e1f92d4b..f15568cc72bd 100644 --- a/buildscripts/checkstyle.xml +++ b/buildscripts/checkstyle.xml @@ -88,26 +88,7 @@ value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE, LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, DO_WHILE"/> - - - - - - - - - - - + diff --git a/instrumentation/runtime-telemetry/README.md b/instrumentation/runtime-telemetry/README.md index 51a6611f7c08..202543df8fbc 100644 --- a/instrumentation/runtime-telemetry/README.md +++ b/instrumentation/runtime-telemetry/README.md @@ -1,10 +1,19 @@ # Settings for the Runtime Telemetry instrumentation +| System property | Type | Default | Description | +| ------------------------------------------------------------------------------------- | ------- | ------- | --------------------------------------------------------------------------------------- | +| `otel.instrumentation.runtime-telemetry.emit-experimental-metrics` | Boolean | `false` | Enable the capture of experimental metrics. | +| `otel.instrumentation.runtime-telemetry.experimental.prefer-jfr` | Boolean | `false` | Prefer JFR over JMX for metrics where both collection methods are available (Java 17+). | +| `otel.instrumentation.runtime-telemetry.experimental.package-emitter.enabled` | Boolean | `false` | Enable creating events for JAR libraries used by the application. | +| `otel.instrumentation.runtime-telemetry.experimental.package-emitter.jars-per-second` | Integer | 10 | The number of JAR files processed per second. | + +## Deprecated Properties (to be removed in 3.0) + | System property | Type | Default | Description | -|--------------------------------------------------------------------------|---------|---------|-----------------------------------------------------------------------------------| -| `otel.instrumentation.runtime-telemetry.capture-gc-cause` | Boolean | `false` | Enable the capture of the jvm.gc.cause attribute with the jvm.gc.duration metric. | -| `otel.instrumentation.runtime-telemetry.emit-experimental-telemetry` | Boolean | `false` | Enable the capture of experimental metrics. | -| `otel.instrumentation.runtime-telemetry-java17.enable-all` | Boolean | `false` | Enable the capture of all JFR based metrics. | -| `otel.instrumentation.runtime-telemetry-java17.enabled` | Boolean | `false` | Enable the capture of JFR based metrics. | -| `otel.instrumentation.runtime-telemetry.package-emitter.enabled` | Boolean | `false` | Enable creating events for JAR libraries used by the application. | -| `otel.instrumentation.runtime-telemetry.package-emitter.jars-per-second` | Integer | 10 | The number of JAR files processed per second. | +| ------------------------------------------------------------------------ | ------- | ------- | --------------------------------------------------------------------------------- | +| `otel.instrumentation.runtime-telemetry.capture-gc-cause` | Boolean | `false` | Enable the capture of the jvm.gc.cause attribute. Will always be captured in 3.0. | +| `otel.instrumentation.runtime-telemetry.emit-experimental-telemetry` | Boolean | `false` | Use `emit-experimental-metrics` instead. | +| `otel.instrumentation.runtime-telemetry.package-emitter.enabled` | Boolean | `false` | Use `experimental.package-emitter.enabled` instead. | +| `otel.instrumentation.runtime-telemetry.package-emitter.jars-per-second` | Integer | 10 | Use `experimental.package-emitter.jars-per-second` instead. | +| `otel.instrumentation.runtime-telemetry-java17.enabled` | Boolean | `false` | Deprecated. Use `emit-experimental-metrics` for experimental JFR features. | +| `otel.instrumentation.runtime-telemetry-java17.enable-all` | Boolean | `false` | Deprecated. Use `emit-experimental-metrics` and `experimental.prefer-jfr`. | diff --git a/instrumentation/runtime-telemetry/javaagent/build.gradle.kts b/instrumentation/runtime-telemetry/javaagent/build.gradle.kts new file mode 100644 index 000000000000..493e69c45b3c --- /dev/null +++ b/instrumentation/runtime-telemetry/javaagent/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +dependencies { + implementation(project(":instrumentation:runtime-telemetry:library")) + + compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + compileOnly("io.opentelemetry:opentelemetry-api-incubator") +} + +tasks { + test { + jvmArgs("-Dotel.instrumentation.runtime-telemetry.experimental.package-emitter.enabled=true") + } +} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzer.java b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzer.java similarity index 79% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzer.java rename to instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzer.java index b32f2c44a805..5435445bcbbb 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzer.java +++ b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzer.java @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8; +package io.opentelemetry.javaagent.instrumentation.runtimetelemetry; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarDetails.EAR_EXTENSION; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarDetails.JAR_EXTENSION; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarDetails.WAR_EXTENSION; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarDetails.EAR_EXTENSION; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarDetails.JAR_EXTENSION; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarDetails.WAR_EXTENSION; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.logging.Level.FINEST; import static java.util.logging.Level.INFO; @@ -17,8 +17,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; -import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.internal.DaemonThreadFactory; import io.opentelemetry.sdk.common.internal.RateLimiter; @@ -34,7 +34,6 @@ import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; -import java.util.logging.Logger; /** * {@link JarAnalyzer} is a {@link ClassFileTransformer} which processes the {@link @@ -43,7 +42,8 @@ */ final class JarAnalyzer implements ClassFileTransformer { - private static final Logger logger = Logger.getLogger(JarAnalyzer.class.getName()); + private static final java.util.logging.Logger logger = + java.util.logging.Logger.getLogger(JarAnalyzer.class.getName()); private static final String EVENT_NAME_INFO = "package.info"; static final AttributeKey PACKAGE_NAME = AttributeKey.stringKey("package.name"); @@ -59,16 +59,16 @@ final class JarAnalyzer implements ClassFileTransformer { private final Set seenUris = new HashSet<>(); private final BlockingQueue toProcess = new LinkedBlockingDeque<>(); - private JarAnalyzer(OpenTelemetry openTelemetry, int jarsPerSecond) { - ExtendedLogRecordBuilder logRecordBuilder = - (ExtendedLogRecordBuilder) - openTelemetry - .getLogsBridge() - .loggerBuilder(JmxRuntimeMetricsUtil.getInstrumentationName()) - .setInstrumentationVersion(JmxRuntimeMetricsUtil.getInstrumentationVersion()) - .build() - .logRecordBuilder(); - Worker worker = new Worker(logRecordBuilder, toProcess, jarsPerSecond); + private JarAnalyzer(OpenTelemetry openTelemetry, String instrumentationName, int jarsPerSecond) { + String instrumentationVersion = + EmbeddedInstrumentationProperties.findVersion(instrumentationName); + Logger logger = + openTelemetry + .getLogsBridge() + .loggerBuilder(instrumentationName) + .setInstrumentationVersion(instrumentationVersion) + .build(); + Worker worker = new Worker(logger, toProcess, jarsPerSecond); Thread workerThread = new DaemonThreadFactory(JarAnalyzer.class.getSimpleName() + "_WorkerThread") .newThread(worker); @@ -76,8 +76,10 @@ private JarAnalyzer(OpenTelemetry openTelemetry, int jarsPerSecond) { } /** Create {@link JarAnalyzer} and start the worker thread. */ - public static JarAnalyzer create(OpenTelemetry unused, int jarsPerSecond) { - return new JarAnalyzer(unused, jarsPerSecond); + // TODO can remove instrumentationName parameter in 3.0 + public static JarAnalyzer create( + OpenTelemetry openTelemetry, String instrumentationName, int jarsPerSecond) { + return new JarAnalyzer(openTelemetry, instrumentationName, jarsPerSecond); } /** @@ -156,20 +158,19 @@ private void handle(ProtectionDomain protectionDomain) { private static final class Worker implements Runnable { - private final ExtendedLogRecordBuilder eventLogger; + private final Logger logger; private final BlockingQueue toProcess; private final RateLimiter rateLimiter; - private Worker( - ExtendedLogRecordBuilder eventLogger, BlockingQueue toProcess, int jarsPerSecond) { - this.eventLogger = eventLogger; + private Worker(Logger logger, BlockingQueue toProcess, int jarsPerSecond) { + this.logger = logger; this.toProcess = toProcess; this.rateLimiter = new RateLimiter(jarsPerSecond, jarsPerSecond, Clock.getDefault()); } /** * Continuously poll the {@link #toProcess} for archive {@link URL}s, and process each wit - * {@link #processUrl(ExtendedLogRecordBuilder, URL)}. + * {@link #processUrl(Logger, URL)}. */ @Override public void run() { @@ -190,12 +191,13 @@ public void run() { try { // TODO(jack-berg): add ability to optionally re-process urls periodically to re-emit // events - processUrl(eventLogger, archiveUrl); + processUrl(logger, archiveUrl); } catch (Throwable e) { - logger.log(WARNING, "Unexpected error processing archive URL: " + archiveUrl, e); + JarAnalyzer.logger.log( + WARNING, "Unexpected error processing archive URL: " + archiveUrl, e); } } - logger.warning("JarAnalyzer stopped"); + JarAnalyzer.logger.warning("JarAnalyzer stopped"); } } @@ -203,12 +205,12 @@ public void run() { * Process the {@code archiveUrl}, extracting metadata from it and emitting an event with the * content. */ - static void processUrl(ExtendedLogRecordBuilder eventLogger, URL archiveUrl) { + static void processUrl(Logger logger, URL archiveUrl) { JarDetails jarDetails; try { jarDetails = JarDetails.forUrl(archiveUrl); } catch (IOException e) { - logger.log(WARNING, "Error reading package for archive URL: " + archiveUrl, e); + JarAnalyzer.logger.log(WARNING, "Error reading package for archive URL: " + archiveUrl, e); return; } AttributesBuilder builder = Attributes.builder(); @@ -242,6 +244,10 @@ static void processUrl(ExtendedLogRecordBuilder eventLogger, URL archiveUrl) { builder.put(PACKAGE_CHECKSUM, packageChecksum); builder.put(PACKAGE_CHECKSUM_ALGORITHM, "SHA1"); - eventLogger.setEventName(EVENT_NAME_INFO).setAllAttributes(builder.build()).emit(); + logger + .logRecordBuilder() + .setEventName(EVENT_NAME_INFO) + .setAllAttributes(builder.build()) + .emit(); } } diff --git a/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzerInstaller.java b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzerInstaller.java new file mode 100644 index 000000000000..c6d3f0d93f8e --- /dev/null +++ b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzerInstaller.java @@ -0,0 +1,83 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.runtimetelemetry; + +import com.google.auto.service.AutoService; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; +import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder; +import io.opentelemetry.javaagent.tooling.BeforeAgentListener; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import java.lang.instrument.Instrumentation; +import java.util.logging.Logger; + +/** Installs the {@link JarAnalyzer}. */ +@AutoService(BeforeAgentListener.class) +public class JarAnalyzerInstaller implements BeforeAgentListener { + + private static final Logger logger = Logger.getLogger(JarAnalyzerInstaller.class.getName()); + private static final int DEFAULT_JARS_PER_SECOND = 10; + + @Override + public void beforeAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { + OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); + DeclarativeConfigProperties config = + DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry"); + + // Support both new config (package_emitter/development) and old path + // (package_emitter) + DeclarativeConfigProperties newPackageEmitterConfig = config.get("package_emitter/development"); + DeclarativeConfigProperties oldPackageEmitterConfig = config.get("package_emitter"); + + boolean enabledNew = newPackageEmitterConfig.getBoolean("enabled", false); + boolean enabledOld = oldPackageEmitterConfig.getBoolean("enabled", false); + if (enabledOld) { + logger.warning( + "otel.instrumentation.runtime-telemetry.package-emitter.enabled is deprecated and will" + + " be removed in 3.0. Use" + + " otel.instrumentation.runtime-telemetry.experimental.package-emitter.enabled" + + " instead."); + } + if (!enabledNew && !enabledOld) { + return; + } + Instrumentation inst = InstrumentationHolder.getInstrumentation(); + if (inst == null) { + return; + } + + // Use appropriate instrumentation name based on which config is active + String instrumentationName = + enabledNew + ? "io.opentelemetry.runtime-telemetry" + : "io.opentelemetry.runtime-telemetry-java8"; + + int newJarsPerSecond = newPackageEmitterConfig.getInt("jars_per_second", -1); + int oldJarsPerSecond = oldPackageEmitterConfig.getInt("jars_per_second", -1); + + if (oldJarsPerSecond >= 0) { + logger.warning( + "otel.instrumentation.runtime-telemetry.package-emitter.jars-per-second is deprecated" + + " and will be removed in 3.0. Use" + + " otel.instrumentation.runtime-telemetry.experimental.package-emitter.jars-per-second" + + " instead."); + } + + int jarsPerSecond; + if (newJarsPerSecond >= 0) { + jarsPerSecond = newJarsPerSecond; + } else if (oldJarsPerSecond >= 0) { + jarsPerSecond = oldJarsPerSecond; + } else { + jarsPerSecond = DEFAULT_JARS_PER_SECOND; + } + + JarAnalyzer jarAnalyzer = JarAnalyzer.create(openTelemetry, instrumentationName, jarsPerSecond); + inst.addTransformer(jarAnalyzer); + } +} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarDetails.java b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarDetails.java similarity index 99% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarDetails.java rename to instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarDetails.java index 0e61f186ec65..5b2fd6bc6691 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarDetails.java +++ b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarDetails.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8; +package io.opentelemetry.javaagent.instrumentation.runtimetelemetry; import static java.util.function.Function.identity; import static java.util.stream.Collectors.collectingAndThen; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/RuntimeTelemetryInstaller.java similarity index 57% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java rename to instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/RuntimeTelemetryInstaller.java index 3aac8a9ebab5..0e99957a3144 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java +++ b/instrumentation/runtime-telemetry/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/RuntimeTelemetryInstaller.java @@ -3,31 +3,30 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.runtimemetrics.java17; +package io.opentelemetry.javaagent.instrumentation.runtimetelemetry; import com.google.auto.service.AutoService; import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Internal; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; /** An {@link AgentListener} that enables runtime metrics during agent startup. */ @AutoService(AgentListener.class) -public class Java17RuntimeMetricsInstaller implements AgentListener { +public class RuntimeTelemetryInstaller implements AgentListener { @Override public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { - RuntimeMetrics runtimeMetrics = - RuntimeMetricsConfigUtil.configure( - RuntimeMetrics.builder(GlobalOpenTelemetry.get()), + RuntimeTelemetry runtimeTelemetry = + Internal.configure( GlobalOpenTelemetry.get(), AgentDistributionConfig.get().isInstrumentationDefaultEnabled()); - if (runtimeMetrics != null) { + if (runtimeTelemetry != null) { Runtime.getRuntime() .addShutdownHook( - new Thread(runtimeMetrics::close, "OpenTelemetry RuntimeMetricsShutdownHook")); + new Thread(runtimeTelemetry::close, "OpenTelemetry RuntimeTelemetryShutdownHook")); } } } diff --git a/instrumentation/runtime-telemetry/library/README.md b/instrumentation/runtime-telemetry/library/README.md new file mode 100644 index 000000000000..10800c87afb1 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/README.md @@ -0,0 +1,178 @@ +# JVM Runtime Metrics + +This module provides JVM runtime metrics as documented in the [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/runtime/jvm-metrics.md). + +This is the unified runtime telemetry module that works on all Java versions. On Java 8-16, it uses +JMX for metrics collection. On Java 17+, it can additionally use JFR (Java Flight Recorder) for +metrics that are not available via JMX. + +## Quickstart + +### Add these dependencies to your project + +Replace `OPENTELEMETRY_VERSION` with the [latest +release](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-runtime-telemetry). + +For Maven, add to your `pom.xml` dependencies: + +```xml + + + io.opentelemetry.instrumentation + opentelemetry-runtime-telemetry + OPENTELEMETRY_VERSION + + +``` + +For Gradle, add to your dependencies: + +```groovy +runtimeOnly("io.opentelemetry.instrumentation:opentelemetry-runtime-telemetry:OPENTELEMETRY_VERSION") +``` + +### Usage + +Register JVM runtime metrics: + +```java +OpenTelemetry openTelemetry = // OpenTelemetry instance configured elsewhere + +RuntimeTelemetry runtimeTelemetry = RuntimeTelemetry.create(openTelemetry); + +// When done, close to stop metric collection +runtimeTelemetry.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 + stream: + aggregation: + drop: + # Keep jvm.memory.used (views are additive, this creates a second stream) + - selector: + meter_name: io.opentelemetry.runtime-telemetry + instrument_name: jvm.memory.used + stream: {} +``` + +## Metrics + +### Stable Metrics (enabled by default) + +These metrics are collected via JMX on all Java versions: + +| Metric | Description | +| -------- | ----------- | +| `jvm.class.count` | Number of classes currently loaded | +| `jvm.class.loaded` | Number of classes loaded since JVM start | +| `jvm.class.unloaded` | Number of classes unloaded since JVM start | +| `jvm.cpu.recent_utilization` | Recent CPU utilization for the process | +| `jvm.cpu.time` | CPU time used by the process | +| `jvm.gc.duration` | Duration of JVM garbage collection actions | +| `jvm.memory.committed` | Measure of memory committed | +| `jvm.memory.limit` | Measure of max obtainable memory | +| `jvm.memory.used` | Measure of memory used | +| `jvm.memory.used_after_last_gc` | Measure of memory used, as measured after the most recent garbage collection event on this pool | +| `jvm.thread.count` | Number of executing platform threads | + +### Experimental Metrics + +These metrics are enabled with `emitExperimentalMetrics()`: + +**JMX-based (all Java versions):** + +| Metric | Description | +| -------- | ----------- | +| `jvm.buffer.count` | Number of buffers in the pool | +| `jvm.buffer.memory.limit` | Measure of total memory capacity of buffers | +| `jvm.buffer.memory.used` | Measure of memory used by buffers | +| `jvm.memory.init` | Measure of initial memory requested | +| `jvm.system.cpu.utilization` | System-wide CPU utilization | + +**JFR-based (Java 17+ only):** + +> **Warning**: JFR events might not be available for all JVMs or with a GraalVM native image, +> therefore limiting the produced metrics. The original implementation was done for Hotspot. OpenJ9 +> currently (Nov. 2025) only has the VM-level JFR implementation. So events emitted at the Java +> level (ie. in jdk.jfr) will not be present. Meaning, jdk.SocketRead, jdk.SocketWrite won't work. + +| Metric | Description | +| -------- | ----------- | +| `jvm.cpu.context_switch` | Context switch rate | +| `jvm.cpu.longlock` | Long lock contention | +| `jvm.memory.allocation` | Memory allocation rate | +| `jvm.network.io` | Network I/O bytes | +| `jvm.network.time` | Network I/O time | + +## Garbage Collector Dependent Metrics + +The attributes reported on the memory metrics (`jvm.memory.*`) and gc metrics (`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. + +The following lists attributes reported for a variety of garbage collectors. Notice that attributes are not necessarily constant across `*.used`, `*.committed`, and `*.limit` since not all memory pools report a limit. + +- CMS Garbage Collector + - `jvm.memory.used`: {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Code Cache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.committed`: {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Code Cache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.limit`: {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Code Cache,jvm.memory.type=non_heap} + - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap} + - `jvm.gc.duration`: {jvm.gc.action=end of minor GC,jvm.gc.name=ParNew}, {jvm.gc.action=end of major GC,jvm.gc.name=MarkSweepCompact} +- G1 Garbage Collector + - `jvm.memory.used`: {jvm.memory.pool.name=G1 Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.committed`: {jvm.memory.pool.name=G1 Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=G1 Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap} + - `jvm.gc.duration`: {jvm.gc.action=end of minor GC,jvm.gc.name=G1 Young Generation}, {jvm.gc.action=end of major GC,jvm.gc.name=G1 Old Generation} +- Parallel Garbage Collector + - `jvm.memory.used`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.committed`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap} + - `jvm.gc.duration`: {jvm.gc.action=end of major GC,jvm.gc.name=PS MarkSweep}, {jvm.gc.action=end of minor GC,jvm.gc.name=PS Scavenge} +- Serial Garbage Collector + - `jvm.memory.used`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.committed`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} + - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap} + - `jvm.gc.duration`: {jvm.gc.action=end of minor GC,jvm.gc.name=Copy}, {jvm.gc.action=end of major GC,jvm.gc.name=MarkSweepCompact} +- Shenandoah Garbage Collector + - `jvm.memory.used`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.committed`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap} + - `jvm.gc.duration`: {jvm.gc.action=end of GC cycle,jvm.gc.name=Shenandoah Cycles}, {jvm.gc.action=end of GC pause,jvm.gc.name=Shenandoah Pauses} +- Z Garbage Collector + - `jvm.memory.used`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.committed`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} + - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap} + - `jvm.gc.duration`: {jvm.gc.action=end of GC cycle,jvm.gc.name=ZGC Cycles}, {jvm.gc.action=end of GC pause,jvm.gc.name=ZGC Pauses} diff --git a/instrumentation/runtime-telemetry/library/build.gradle.kts b/instrumentation/runtime-telemetry/library/build.gradle.kts new file mode 100644 index 000000000000..2a390f89da1b --- /dev/null +++ b/instrumentation/runtime-telemetry/library/build.gradle.kts @@ -0,0 +1,170 @@ +plugins { + id("otel.library-instrumentation") +} + +val mrJarVersions = listOf(17) + +dependencies { + implementation(project(":instrumentation-api")) + implementation(project(":instrumentation-api-incubator")) + + testImplementation("io.opentelemetry:opentelemetry-sdk-testing") + testImplementation("io.github.netmikey.logunit:logunit-jul:1.1.3") +} + +sourceSets { + create("testJava17") { + java { + setSrcDirs(listOf("src/testJava17/java")) + } + } +} + +for (version in mrJarVersions) { + sourceSets { + create("java$version") { + java { + setSrcDirs(listOf("src/main/java$version")) + } + } + } + + tasks { + named("compileJava${version}Java") { + sourceCompatibility = "$version" + targetCompatibility = "$version" + options.release.set(version) + } + } + + configurations { + named("java${version}Implementation") { + extendsFrom(configurations["implementation"]) + } + named("java${version}CompileOnly") { + extendsFrom(configurations["compileOnly"]) + } + } + + dependencies { + // Common to reference classes in main sourceset from Java 17 one + add("java${version}Implementation", files(sourceSets.main.get().output.classesDirs)) + } +} + +// Configure testJava17 dependencies after java17 sourceset is created +configurations { + named("testJava17Implementation") { + extendsFrom(configurations["testImplementation"]) + } + named("testJava17RuntimeOnly") { + extendsFrom(configurations["testRuntimeOnly"]) + } +} + +dependencies { + add("testJava17Implementation", sourceSets.test.get().output) + add("testJava17Implementation", sourceSets["java17"].output) + add("testJava17Implementation", sourceSets.main.get().output) +} + +tasks { + // Configure testJava17 compilation for Java 17 + named("compileTestJava17Java") { + dependsOn("compileJava17Java") + sourceCompatibility = "17" + targetCompatibility = "17" + options.release.set(17) + } + + withType(Jar::class) { + val sourcePathProvider = if (name == "jar") { + { ss: SourceSet? -> ss?.output } + } else if (name == "sourcesJar") { + { ss: SourceSet? -> ss?.java } + } else { + { project.objects.fileCollection() } + } + + for (version in mrJarVersions) { + into("META-INF/versions/$version") { + from(sourcePathProvider(sourceSets["java$version"])) + } + } + manifest.attributes( + "Multi-Release" to "true", + ) + } + + // GC-specific tests that require Java 17+ + val testG1 by registering(Test::class) { + dependsOn("compileTestJava17Java") + testClassesDirs = sourceSets["testJava17"].output.classesDirs + classpath = sourceSets["testJava17"].runtimeClasspath + filter { + includeTestsMatching("*G1GcMemoryMetricTest*") + } + include("**/*G1GcMemoryMetricTest.*") + jvmArgs("-XX:+UseG1GC") + } + + val testPS by registering(Test::class) { + dependsOn("compileTestJava17Java") + testClassesDirs = sourceSets["testJava17"].output.classesDirs + classpath = sourceSets["testJava17"].runtimeClasspath + filter { + includeTestsMatching("*PsGcMemoryMetricTest*") + } + include("**/*PsGcMemoryMetricTest.*") + jvmArgs("-XX:+UseParallelGC") + } + + val testSerial by registering(Test::class) { + dependsOn("compileTestJava17Java") + testClassesDirs = sourceSets["testJava17"].output.classesDirs + classpath = sourceSets["testJava17"].runtimeClasspath + filter { + includeTestsMatching("*SerialGcMemoryMetricTest*") + } + include("**/*SerialGcMemoryMetricTest.*") + jvmArgs("-XX:+UseSerialGC") + } + + // Run other Java 17 tests (not GC-specific) + val testJava17 by registering(Test::class) { + dependsOn("compileTestJava17Java") + testClassesDirs = sourceSets["testJava17"].output.classesDirs + classpath = sourceSets["testJava17"].runtimeClasspath + filter { + excludeTestsMatching("*G1GcMemoryMetricTest") + excludeTestsMatching("*SerialGcMemoryMetricTest") + excludeTestsMatching("*PsGcMemoryMetricTest") + } + } + + test { + // Java 8 tests only + } + + val testJavaVersion = + gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion) + ?: JavaVersion.current() + if (!testJavaVersion.isCompatibleWith(JavaVersion.VERSION_17)) { + named("testG1", Test::class).configure { + enabled = false + } + named("testPS", Test::class).configure { + enabled = false + } + named("testSerial", Test::class).configure { + enabled = false + } + named("testJava17", Test::class).configure { + enabled = false + } + } + + check { + dependsOn(testJava17, testG1, testPS, testSerial) + } +} diff --git a/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetry.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetry.java new file mode 100644 index 000000000000..28fd0207b2c5 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetry.java @@ -0,0 +1,82 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry; + +import static java.util.logging.Level.WARNING; + +import io.opentelemetry.api.OpenTelemetry; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Logger; +import javax.annotation.Nullable; + +/** The entry point class for runtime telemetry support using JMX (Java 8+) and JFR (Java 17+). */ +public final class RuntimeTelemetry implements AutoCloseable { + + private static final Logger logger = Logger.getLogger(RuntimeTelemetry.class.getName()); + + private final AtomicBoolean isClosed = new AtomicBoolean(); + private final List observables; + @Nullable private final AutoCloseable jfrTelemetry; + + RuntimeTelemetry(List observables, @Nullable AutoCloseable jfrTelemetry) { + this.observables = Collections.unmodifiableList(observables); + this.jfrTelemetry = jfrTelemetry; + } + + /** + * Create and start {@link RuntimeTelemetry}. + * + *

Listens for select JMX beans (and JFR events on Java 17+), extracts data, and records to + * various metrics. Recording will continue until {@link #close()} is called. + * + * @param openTelemetry the {@link OpenTelemetry} instance used to record telemetry + */ + public static RuntimeTelemetry create(OpenTelemetry openTelemetry) { + return new RuntimeTelemetryBuilder(openTelemetry).build(); + } + + /** + * Create a builder for configuring {@link RuntimeTelemetry}. + * + * @param openTelemetry the {@link OpenTelemetry} instance used to record telemetry + */ + public static RuntimeTelemetryBuilder builder(OpenTelemetry openTelemetry) { + return new RuntimeTelemetryBuilder(openTelemetry); + } + + // Only used by tests + @Nullable + AutoCloseable getJfrTelemetry() { + return jfrTelemetry; + } + + /** Stop recording metrics. */ + @Override + public void close() { + if (!isClosed.compareAndSet(false, true)) { + logger.log(WARNING, "RuntimeTelemetry is already closed"); + return; + } + + if (jfrTelemetry != null) { + try { + jfrTelemetry.close(); + } catch (Exception e) { + logger.log(WARNING, "Error closing JFR telemetry", e); + } + } + + for (AutoCloseable observable : observables) { + try { + observable.close(); + } catch (Exception e) { + // Ignore + } + } + } +} diff --git a/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryBuilder.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryBuilder.java new file mode 100644 index 000000000000..e2640675f9b7 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryBuilder.java @@ -0,0 +1,125 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry; + +import static java.util.Collections.emptyList; + +import com.google.errorprone.annotations.CanIgnoreReturnValue; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.MeterBuilder; +import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Experimental; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Internal; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrConfig; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JmxRuntimeMetricsFactory; +import java.util.List; +import javax.annotation.Nullable; + +/** Builder for {@link RuntimeTelemetry}. */ +public final class RuntimeTelemetryBuilder { + + private static final String DEFAULT_INSTRUMENTATION_NAME = "io.opentelemetry.runtime-telemetry"; + + private final OpenTelemetry openTelemetry; + private final JfrConfig jfrConfig; + + private boolean emitExperimentalMetrics; + private boolean preferJfrMetrics; + private boolean disableJmx; + private boolean captureGcCause; + // For backward compatibility: support separate instrumentation names for JMX and JFR metrics + @Nullable private String jmxInstrumentationName; + @Nullable private String jfrInstrumentationName; + + static { + Experimental.internalSetEmitExperimentalMetrics( + (builder, emit) -> { + builder.emitExperimentalMetrics = emit; + if (emit) { + builder.jfrConfig.enableExperimentalFeatures(); + } + }); + Experimental.internalSetPreferJfrMetrics( + (builder, prefer) -> builder.preferJfrMetrics = prefer); + Internal.internalSetEnableAllJfrFeatures( + (builder, enable) -> { + if (enable) { + builder.jfrConfig.enableAllFeatures(); + } + }); + Internal.internalSetDisableAllJfrFeatures( + (builder, disable) -> { + if (disable) { + builder.jfrConfig.disableAllFeatures(); + } + }); + Internal.internalSetEnableExperimentalJfrFeatures( + (builder, enable) -> { + if (enable) { + builder.jfrConfig.enableExperimentalFeatures(); + } + }); + Internal.internalSetCaptureGcCause((builder, capture) -> builder.captureGcCause = capture); + Internal.internalSetUseLegacyJfrCpuCountMetric( + (builder, useLegacy) -> builder.jfrConfig.setUseLegacyJfrCpuCountMetric(useLegacy)); + Internal.internalSetJmxInstrumentationName( + (builder, name) -> builder.jmxInstrumentationName = name); + Internal.internalSetJfrInstrumentationName( + (builder, name) -> builder.jfrInstrumentationName = name); + Internal.internalSetEnableJfrFeature( + (builder, featureName) -> builder.jfrConfig.enableFeature(featureName)); + Internal.internalSetDisableJfrFeature( + (builder, featureName) -> builder.jfrConfig.disableFeature(featureName)); + Internal.internalSetDisableJmx((builder, disable) -> builder.disableJmx = disable); + } + + RuntimeTelemetryBuilder(OpenTelemetry openTelemetry) { + this.openTelemetry = openTelemetry; + this.jfrConfig = JfrConfig.create(); + } + + // Visible for testing + JfrConfig getJfrConfig() { + return jfrConfig; + } + + /** Disable all JMX telemetry collection. Visible for testing. */ + @CanIgnoreReturnValue + RuntimeTelemetryBuilder disableAllJmx() { + disableJmx = true; + return this; + } + + /** Build and start a {@link RuntimeTelemetry} with the config from this builder. */ + public RuntimeTelemetry build() { + // Use configured names, or fall back to default if not set + String jmxName = + jmxInstrumentationName != null ? jmxInstrumentationName : DEFAULT_INSTRUMENTATION_NAME; + String jfrName = + jfrInstrumentationName != null ? jfrInstrumentationName : DEFAULT_INSTRUMENTATION_NAME; + + Meter jmxMeter = getMeter(openTelemetry, jmxName); + Meter jfrMeter = getMeter(openTelemetry, jfrName); + + List observables = + disableJmx + ? emptyList() + : JmxRuntimeMetricsFactory.buildObservables( + emitExperimentalMetrics, captureGcCause, preferJfrMetrics, jmxMeter); + AutoCloseable jfrTelemetry = jfrConfig.buildJfrTelemetry(preferJfrMetrics, jfrMeter); + return new RuntimeTelemetry(observables, jfrTelemetry); + } + + private static Meter getMeter(OpenTelemetry openTelemetry, String instrumentationName) { + MeterBuilder meterBuilder = openTelemetry.meterBuilder(instrumentationName); + String version = EmbeddedInstrumentationProperties.findVersion(instrumentationName); + if (version != null) { + meterBuilder.setInstrumentationVersion(version); + } + return meterBuilder.build(); + } +} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/BufferPools.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/BufferPools.java similarity index 86% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/BufferPools.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/BufferPools.java index 375b97625def..360d994284a6 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/BufferPools.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/BufferPools.java @@ -3,11 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.api.common.AttributeKey.stringKey; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; @@ -31,18 +30,15 @@ public final class BufferPools { stringKey("jvm.buffer.pool.name"); /** Register observers for java runtime buffer pool metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { + public static List registerObservers(Meter meter) { List bufferBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); - return registerObservers(openTelemetry, bufferBeans); + return registerObservers(meter, bufferBeans); } // Visible for testing - static List registerObservers( - OpenTelemetry openTelemetry, List bufferBeans) { - + static List registerObservers(Meter meter, List bufferBeans) { List observables = new ArrayList<>(); - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); observables.add( meter .upDownCounterBuilder("jvm.buffer.memory.used") diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Classes.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Classes.java similarity index 81% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Classes.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Classes.java index afe74d074a0d..dd7711d39eef 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Classes.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Classes.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.Meter; import java.lang.management.ClassLoadingMXBean; import java.lang.management.ManagementFactory; @@ -27,13 +26,12 @@ public class Classes { static final Classes INSTANCE = new Classes(); /** Register observers for java runtime class metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { - return INSTANCE.registerObservers(openTelemetry, ManagementFactory.getClassLoadingMXBean()); + public static List registerObservers(Meter meter) { + return INSTANCE.registerObservers(meter, ManagementFactory.getClassLoadingMXBean()); } // Visible for testing - List registerObservers(OpenTelemetry openTelemetry, ClassLoadingMXBean classBean) { - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); + List registerObservers(Meter meter, ClassLoadingMXBean classBean) { List observables = new ArrayList<>(); observables.add( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Cpu.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Cpu.java similarity index 90% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Cpu.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Cpu.java index 5014ef765736..3b713a056a4e 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Cpu.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Cpu.java @@ -3,11 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static java.util.concurrent.TimeUnit.SECONDS; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.Meter; import java.util.ArrayList; import java.util.List; @@ -32,9 +31,9 @@ public class Cpu { private static final double NANOS_PER_S = SECONDS.toNanos(1); /** Register observers for java runtime CPU metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { + public static List registerObservers(Meter meter) { return INSTANCE.registerObservers( - openTelemetry, + meter, Runtime.getRuntime()::availableProcessors, CpuMethods.processCpuTime(), CpuMethods.processCpuUtilization()); @@ -42,11 +41,10 @@ public static List registerObservers(OpenTelemetry openTelemetry) // Visible for testing List registerObservers( - OpenTelemetry openTelemetry, + Meter meter, IntSupplier availableProcessors, @Nullable Supplier processCpuTime, @Nullable Supplier processCpuUtilization) { - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); List observables = new ArrayList<>(); if (processCpuTime != null) { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/CpuMethods.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/CpuMethods.java similarity index 98% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/CpuMethods.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/CpuMethods.java index 479170865901..e2d56fbfa59d 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/CpuMethods.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/CpuMethods.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; diff --git a/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Experimental.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Experimental.java new file mode 100644 index 000000000000..351794fdb9d9 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Experimental.java @@ -0,0 +1,68 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry.internal; + +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetryBuilder; +import java.util.function.BiConsumer; +import javax.annotation.Nullable; + +/** + * This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. + */ +public final class Experimental { + + @Nullable + private static volatile BiConsumer setEmitExperimentalMetrics; + + @Nullable + private static volatile BiConsumer setPreferJfrMetrics; + + /** + * Sets whether experimental metrics should be emitted. Experimental metrics are those not marked + * as stable in the semantic + * conventions. + * + * @param builder the runtime telemetry builder + * @param emitExperimentalMetrics {@code true} to emit experimental metrics + */ + public static void setEmitExperimentalMetrics( + RuntimeTelemetryBuilder builder, boolean emitExperimentalMetrics) { + if (setEmitExperimentalMetrics != null) { + setEmitExperimentalMetrics.accept(builder, emitExperimentalMetrics); + } + } + + public static void internalSetEmitExperimentalMetrics( + BiConsumer setEmitExperimentalMetrics) { + Experimental.setEmitExperimentalMetrics = setEmitExperimentalMetrics; + } + + /** + * Sets whether to prefer JFR over JMX for metrics where both collection methods are available. + * When set to {@code true}, metrics available from both sources will be collected using JFR. When + * set to {@code false} (default), metrics available from both sources will be collected using + * JMX. Metrics available from only one source are unaffected by this setting. + * + * @param builder the runtime telemetry builder + * @param preferJfrMetrics {@code true} to prefer JFR over JMX where both are available + */ + public static void setPreferJfrMetrics( + RuntimeTelemetryBuilder builder, boolean preferJfrMetrics) { + if (setPreferJfrMetrics != null) { + setPreferJfrMetrics.accept(builder, preferJfrMetrics); + } + } + + public static void internalSetPreferJfrMetrics( + BiConsumer setPreferJfrMetrics) { + Experimental.setPreferJfrMetrics = setPreferJfrMetrics; + } + + private Experimental() {} +} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/FileDescriptor.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/FileDescriptor.java similarity index 83% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/FileDescriptor.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/FileDescriptor.java index 4e2a07214f65..cc58040fa217 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/FileDescriptor.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/FileDescriptor.java @@ -3,10 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import com.sun.management.UnixOperatingSystemMXBean; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.Meter; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; @@ -30,14 +29,12 @@ private static Class loadClass(String className) { } /** Register observers for java runtime file descriptor metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { - return registerObservers(openTelemetry, ManagementFactory.getOperatingSystemMXBean()); + public static List registerObservers(Meter meter) { + return registerObservers(meter, ManagementFactory.getOperatingSystemMXBean()); } // Visible for testing - static List registerObservers( - OpenTelemetry openTelemetry, OperatingSystemMXBean osBean) { - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); + static List registerObservers(Meter meter, OperatingSystemMXBean osBean) { List observables = new ArrayList<>(); if (unixOperatingSystemMxBeanClass != null diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/GarbageCollector.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollector.java similarity index 94% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/GarbageCollector.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollector.java index f94300009deb..5cb5393f6646 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/GarbageCollector.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollector.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.semconv.JvmAttributes.JVM_GC_ACTION; import static io.opentelemetry.semconv.JvmAttributes.JVM_GC_NAME; @@ -13,7 +13,6 @@ import static java.util.concurrent.TimeUnit.SECONDS; import com.sun.management.GarbageCollectionNotificationInfo; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; @@ -58,8 +57,7 @@ public class GarbageCollector { .equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION); /** Register observers for java runtime memory metrics. */ - public static List registerObservers( - OpenTelemetry openTelemetry, boolean captureGcCause) { + public static List registerObservers(Meter meter, boolean captureGcCause) { if (!isNotificationClassPresent()) { logger.fine( "The com.sun.management.GarbageCollectionNotificationInfo class is not available;" @@ -68,7 +66,7 @@ public static List registerObservers( } return registerObservers( - openTelemetry, + meter, ManagementFactory.getGarbageCollectorMXBeans(), GarbageCollector::extractNotificationInfo, captureGcCause); @@ -76,11 +74,10 @@ public static List registerObservers( // Visible for testing public static List registerObservers( - OpenTelemetry openTelemetry, + Meter meter, List gcBeans, Function notificationInfoExtractor, boolean captureGcCause) { - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); DoubleHistogram gcDuration = meter diff --git a/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Internal.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Internal.java new file mode 100644 index 000000000000..e3c87f4a7862 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Internal.java @@ -0,0 +1,376 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry.internal; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetryBuilder; +import java.util.function.BiConsumer; +import java.util.logging.Logger; +import javax.annotation.Nullable; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + * + *

This class provides configuration methods for use by the Java agent, including backward + * compatibility support for previous configuration options. The backward compatibility methods may + * be simplified or removed in a future major version (3.0). + */ +public final class Internal { + + private static final Logger logger = Logger.getLogger(Internal.class.getName()); + + @Nullable + private static volatile BiConsumer setEnableAllJfrFeatures; + + @Nullable + private static volatile BiConsumer setDisableAllJfrFeatures; + + @Nullable + private static volatile BiConsumer + setEnableExperimentalJfrFeatures; + + @Nullable private static volatile BiConsumer setCaptureGcCause; + + @Nullable + private static volatile BiConsumer + setUseLegacyJfrCpuCountMetric; + + @Nullable + private static volatile BiConsumer setJmxInstrumentationName; + + @Nullable + private static volatile BiConsumer setJfrInstrumentationName; + + @Nullable private static volatile BiConsumer setEnableJfrFeature; + + @Nullable + private static volatile BiConsumer setDisableJfrFeature; + + @Nullable private static volatile BiConsumer setDisableJmx; + + /** + * Sets whether all JFR features should be enabled. This is used for backward compatibility with + * the {@code runtime_telemetry_java17.enable_all} configuration option. + * + *

On Java 17+, this enables all JFR features including those that overlap with JMX metrics. + */ + public static void setEnableAllJfrFeatures( + RuntimeTelemetryBuilder builder, boolean enableAllJfr) { + if (setEnableAllJfrFeatures != null) { + setEnableAllJfrFeatures.accept(builder, enableAllJfr); + } + } + + public static void internalSetEnableAllJfrFeatures( + BiConsumer callback) { + Internal.setEnableAllJfrFeatures = callback; + } + + /** + * Sets whether all JFR features should be disabled. This is used for backward compatibility when + * running on Java 17+ but only the base {@code runtime_telemetry.enabled} option is set (without + * {@code runtime_telemetry_java17.enabled}). + */ + public static void setDisableAllJfrFeatures( + RuntimeTelemetryBuilder builder, boolean disableAllJfr) { + if (setDisableAllJfrFeatures != null) { + setDisableAllJfrFeatures.accept(builder, disableAllJfr); + } + } + + public static void internalSetDisableAllJfrFeatures( + BiConsumer callback) { + Internal.setDisableAllJfrFeatures = callback; + } + + /** + * Sets whether experimental JFR features should be enabled. This is used for backward + * compatibility with the {@code runtime_telemetry_java17.enabled} configuration option, which + * enabled experimental JFR features (context switches, locks, allocations, network I/O) but not + * experimental JMX features. + */ + public static void setEnableExperimentalJfrFeatures( + RuntimeTelemetryBuilder builder, boolean enable) { + if (setEnableExperimentalJfrFeatures != null) { + setEnableExperimentalJfrFeatures.accept(builder, enable); + } + } + + public static void internalSetEnableExperimentalJfrFeatures( + BiConsumer callback) { + Internal.setEnableExperimentalJfrFeatures = callback; + } + + /** + * Sets whether the GC cause attribute should be captured on GC duration metrics. The default is + * {@code true}. This is configurable for backward compatibility with the previous behavior where + * {@code capture_gc_cause} defaulted to {@code false}. + * + * @param builder the runtime telemetry builder + * @param captureGcCause {@code true} to capture the GC cause attribute (default) + */ + public static void setCaptureGcCause(RuntimeTelemetryBuilder builder, boolean captureGcCause) { + if (setCaptureGcCause != null) { + setCaptureGcCause.accept(builder, captureGcCause); + } + } + + public static void internalSetCaptureGcCause( + BiConsumer callback) { + Internal.setCaptureGcCause = callback; + } + + /** + * Sets whether to use the legacy metric name {@code jvm.cpu.limit} instead of the standard {@code + * jvm.cpu.count} for the JFR CPU count feature. This is for backward compatibility with the + * previous runtime-telemetry-java17 module. + * + * @param builder the runtime telemetry builder + * @param useLegacy {@code true} to use the legacy metric name + */ + public static void setUseLegacyJfrCpuCountMetric( + RuntimeTelemetryBuilder builder, boolean useLegacy) { + if (setUseLegacyJfrCpuCountMetric != null) { + setUseLegacyJfrCpuCountMetric.accept(builder, useLegacy); + } + } + + public static void internalSetUseLegacyJfrCpuCountMetric( + BiConsumer callback) { + Internal.setUseLegacyJfrCpuCountMetric = callback; + } + + /** + * Sets the instrumentation name to use for JMX metrics. This is used for backward compatibility + * to preserve the original instrumentation names when using old configuration options. + * + * @param builder the runtime telemetry builder + * @param name the instrumentation name for JMX metrics + */ + public static void setJmxInstrumentationName(RuntimeTelemetryBuilder builder, String name) { + if (setJmxInstrumentationName != null) { + setJmxInstrumentationName.accept(builder, name); + } + } + + public static void internalSetJmxInstrumentationName( + BiConsumer callback) { + Internal.setJmxInstrumentationName = callback; + } + + /** + * Sets the instrumentation name to use for JFR metrics. This is used for backward compatibility + * to preserve the original instrumentation names when using old configuration options. + * + * @param builder the runtime telemetry builder + * @param name the instrumentation name for JFR metrics + */ + public static void setJfrInstrumentationName(RuntimeTelemetryBuilder builder, String name) { + if (setJfrInstrumentationName != null) { + setJfrInstrumentationName.accept(builder, name); + } + } + + public static void internalSetJfrInstrumentationName( + BiConsumer callback) { + Internal.setJfrInstrumentationName = callback; + } + + /** + * Enables a specific JFR feature by name. This is used for backward compatibility with the + * runtime-telemetry-java17 module's per-feature control. + * + * @param builder the runtime telemetry builder + * @param featureName the JFR feature name (e.g., "CPU_COUNT_METRICS") + */ + public static void setEnableJfrFeature(RuntimeTelemetryBuilder builder, String featureName) { + if (setEnableJfrFeature != null) { + setEnableJfrFeature.accept(builder, featureName); + } + } + + public static void internalSetEnableJfrFeature( + BiConsumer callback) { + Internal.setEnableJfrFeature = callback; + } + + /** + * Disables a specific JFR feature by name. This is used for backward compatibility with the + * runtime-telemetry-java17 module's per-feature control. + * + * @param builder the runtime telemetry builder + * @param featureName the JFR feature name (e.g., "CPU_COUNT_METRICS") + */ + public static void setDisableJfrFeature(RuntimeTelemetryBuilder builder, String featureName) { + if (setDisableJfrFeature != null) { + setDisableJfrFeature.accept(builder, featureName); + } + } + + public static void internalSetDisableJfrFeature( + BiConsumer callback) { + Internal.setDisableJfrFeature = callback; + } + + /** + * Disables all JMX-based metrics. This is used for backward compatibility with the + * runtime-telemetry-java17 module's disableAllJmx() method. + * + * @param builder the runtime telemetry builder + * @param disable {@code true} to disable JMX metrics + */ + public static void setDisableJmx(RuntimeTelemetryBuilder builder, boolean disable) { + if (setDisableJmx != null) { + setDisableJmx.accept(builder, disable); + } + } + + public static void internalSetDisableJmx(BiConsumer callback) { + Internal.setDisableJmx = callback; + } + + /** + * Configures and builds a {@link RuntimeTelemetry} instance based on the provided configuration. + * + * @param openTelemetry the OpenTelemetry instance + * @param defaultEnabled whether instrumentation is enabled by default + * @return the configured RuntimeTelemetry, or null if runtime telemetry is disabled + */ + @Nullable + public static RuntimeTelemetry configure(OpenTelemetry openTelemetry, boolean defaultEnabled) { + DeclarativeConfigProperties config = + DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry"); + DeclarativeConfigProperties java17Config = + DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry_java17"); + + // Determine which configuration is being used + boolean baseEnabled = config.getBoolean("enabled", defaultEnabled); + boolean java17Enabled = java17Config.getBoolean("enabled", false); + boolean java17EnableAll = java17Config.getBoolean("enable_all", false); + + if (!baseEnabled && !java17Enabled && !java17EnableAll) { + return null; // Nothing is enabled + } + + RuntimeTelemetryBuilder builder = RuntimeTelemetry.builder(openTelemetry); + + // Old deprecated java17 configs: FREEZE their behavior, don't apply new unified options + if (java17EnableAll) { + configureJava17EnableAll(builder, config); + return builder.build(); + } + if (java17Enabled) { + configureJava17Enabled(builder); + return builder.build(); + } + + // New unified config: handles both old java8 settings and new unified options + if (baseEnabled) { + configureUnified(builder, config); + return builder.build(); + } + + throw new AssertionError("Unreachable: at least one enabled flag must be true"); + } + + private static void configureJava17EnableAll( + RuntimeTelemetryBuilder builder, DeclarativeConfigProperties config) { + logger.warning( + "otel.instrumentation.runtime-telemetry-java17.enable-all is deprecated and will be" + + " removed in 3.0. Use otel.instrumentation.runtime-telemetry.emit-experimental-metrics" + + " and otel.instrumentation.runtime-telemetry.experimental.prefer-jfr instead."); + // For backward compatibility: route JMX metrics to java8 scope, JFR metrics to java17 scope + Internal.setJmxInstrumentationName(builder, "io.opentelemetry.runtime-telemetry-java8"); + Internal.setJfrInstrumentationName(builder, "io.opentelemetry.runtime-telemetry-java17"); + Internal.setEnableAllJfrFeatures(builder, true); + Internal.setUseLegacyJfrCpuCountMetric(builder, true); + + // Check if base config also has emit_experimental_telemetry enabled (for JMX experimental) + boolean emitExperimentalTelemetry = + config.getBoolean("emit_experimental_telemetry/development", false); + boolean emitExperimentalMetrics = + config.getBoolean("emit_experimental_metrics/development", false); + if (emitExperimentalTelemetry || emitExperimentalMetrics) { + if (emitExperimentalTelemetry) { + logger.warning( + "otel.instrumentation.runtime-telemetry.emit-experimental-telemetry is deprecated and" + + " will be removed in 3.0. Use" + + " otel.instrumentation.runtime-telemetry.emit-experimental-metrics instead."); + } + Experimental.setEmitExperimentalMetrics(builder, true); + } + } + + private static void configureJava17Enabled(RuntimeTelemetryBuilder builder) { + logger.warning( + "otel.instrumentation.runtime-telemetry-java17.enabled is deprecated and will be" + + " removed in 3.0. Use otel.instrumentation.runtime-telemetry.emit-experimental-metrics" + + " for experimental JFR features."); + // Enable default JFR features: context switches, CPU count, locks, allocations, network I/O + Internal.setEnableJfrFeature(builder, "CONTEXT_SWITCH_METRICS"); + Internal.setEnableJfrFeature(builder, "CPU_COUNT_METRICS"); + Internal.setEnableJfrFeature(builder, "LOCK_METRICS"); + Internal.setEnableJfrFeature(builder, "MEMORY_ALLOCATION_METRICS"); + Internal.setEnableJfrFeature(builder, "NETWORK_IO_METRICS"); + Internal.setUseLegacyJfrCpuCountMetric(builder, true); + // For backward compatibility: OLD java17 module used java8's JMX factory, so JMX -> java8 scope + Internal.setJmxInstrumentationName(builder, "io.opentelemetry.runtime-telemetry-java8"); + Internal.setJfrInstrumentationName(builder, "io.opentelemetry.runtime-telemetry-java17"); + } + + private static void configureUnified( + RuntimeTelemetryBuilder builder, DeclarativeConfigProperties config) { + // Check if user is using new unified config options + boolean emitExperimentalMetrics = + config.getBoolean("emit_experimental_metrics/development", false); + boolean preferJfr = config.getBoolean("prefer_jfr/development", false); + boolean newConfig = emitExperimentalMetrics || preferJfr; + + if (newConfig) { + // New unified config: Use new instrumentation name for both JMX and JFR + Internal.setJmxInstrumentationName(builder, "io.opentelemetry.runtime-telemetry"); + Internal.setJfrInstrumentationName(builder, "io.opentelemetry.runtime-telemetry"); + } else { + // Old java8 config: JMX-only, disable JFR for backward compatibility + Internal.setDisableAllJfrFeatures(builder, true); + Internal.setJmxInstrumentationName(builder, "io.opentelemetry.runtime-telemetry-java8"); + Internal.setJfrInstrumentationName(builder, "io.opentelemetry.runtime-telemetry-java8"); + } + + // Apply emit_experimental_metrics (supports both old and new names) + boolean emitExperimentalTelemetry = + config.getBoolean("emit_experimental_telemetry/development", false); + if (emitExperimentalTelemetry) { + logger.warning( + "otel.instrumentation.runtime-telemetry.emit-experimental-telemetry is deprecated and" + + " will be removed in 3.0. Use" + + " otel.instrumentation.runtime-telemetry.emit-experimental-metrics instead."); + } + if (emitExperimentalMetrics || emitExperimentalTelemetry) { + Experimental.setEmitExperimentalMetrics(builder, true); + } + + // Apply prefer_jfr + if (preferJfr) { + Experimental.setPreferJfrMetrics(builder, true); + } + + // Apply capture_gc_cause + boolean captureGcCause = config.getBoolean("capture_gc_cause", false); + if (captureGcCause) { + logger.warning( + "otel.instrumentation.runtime-telemetry.capture-gc-cause is deprecated and will be" + + " removed in 3.0. GC cause will always be captured."); + } + Internal.setCaptureGcCause(builder, captureGcCause); + } + + private Internal() {} +} diff --git a/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrConfig.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrConfig.java new file mode 100644 index 000000000000..5eede69aa060 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrConfig.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry.internal; + +import io.opentelemetry.api.metrics.Meter; +import javax.annotation.Nullable; + +/** + * Configuration holder for JFR telemetry. On Java 8, this is a no-op implementation since JFR is + * not available. On Java 17+, this is replaced by an implementation that manages JFR features. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class JfrConfig { + + public static JfrConfig create() { + return new JfrConfig(); + } + + public JfrConfig enableAllFeatures() { + return this; + } + + public JfrConfig disableAllFeatures() { + return this; + } + + public JfrConfig enableExperimentalFeatures() { + return this; + } + + public JfrConfig enableFeature(String featureName) { + return this; + } + + public JfrConfig disableFeature(String featureName) { + return this; + } + + public JfrConfig setUseLegacyJfrCpuCountMetric(boolean useLegacy) { + return this; + } + + @Nullable + public AutoCloseable buildJfrTelemetry(boolean preferJfrMetrics, Meter meter) { + return null; + } + + private JfrConfig() {} +} diff --git a/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/JmxRuntimeMetricsFactory.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/JmxRuntimeMetricsFactory.java new file mode 100644 index 000000000000..f45823aabf6b --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/JmxRuntimeMetricsFactory.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry.internal; + +import io.opentelemetry.api.metrics.Meter; +import java.util.ArrayList; +import java.util.List; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class JmxRuntimeMetricsFactory { + public static List buildObservables( + boolean emitExperimentalTelemetry, + boolean captureGcCause, + boolean preferJfrMetrics, + Meter meter) { + // Set up metrics gathered by JMX + // When preferJfrMetrics is true, skip JMX metrics that have JFR equivalents + List observables = new ArrayList<>(); + if (!preferJfrMetrics) { + observables.addAll(Classes.registerObservers(meter)); + observables.addAll(Cpu.registerObservers(meter)); + observables.addAll(GarbageCollector.registerObservers(meter, captureGcCause)); + observables.addAll(MemoryPools.registerObservers(meter)); + observables.addAll(Threads.registerObservers(meter)); + } + if (emitExperimentalTelemetry) { + if (!preferJfrMetrics) { + observables.addAll(BufferPools.registerObservers(meter)); + observables.addAll(SystemCpu.registerObservers(meter)); + observables.addAll(MemoryInit.registerObservers(meter)); + } + // FileDescriptor has no JFR equivalent, always register + observables.addAll(FileDescriptor.registerObservers(meter)); + } + return observables; + } + + private JmxRuntimeMetricsFactory() {} +} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryInit.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryInit.java similarity index 84% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryInit.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryInit.java index 39264495b173..9a9fff5958f2 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryInit.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryInit.java @@ -3,13 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.semconv.JvmAttributes.JVM_MEMORY_POOL_NAME; import static io.opentelemetry.semconv.JvmAttributes.JVM_MEMORY_TYPE; import static java.util.Collections.singletonList; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -31,15 +30,12 @@ public final class MemoryInit { /** Register observers for java runtime experimental memory metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { - return registerObservers(openTelemetry, ManagementFactory.getMemoryPoolMXBeans()); + public static List registerObservers(Meter meter) { + return registerObservers(meter, ManagementFactory.getMemoryPoolMXBeans()); } // Visible for testing - static List registerObservers( - OpenTelemetry openTelemetry, List poolBeans) { - - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); + static List registerObservers(Meter meter, List poolBeans) { return singletonList( meter .upDownCounterBuilder("jvm.memory.init") diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryPools.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryPools.java similarity index 91% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryPools.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryPools.java index 8c1f6e5101b0..3ec5ef8d325f 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryPools.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryPools.java @@ -3,12 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.semconv.JvmAttributes.JVM_MEMORY_POOL_NAME; import static io.opentelemetry.semconv.JvmAttributes.JVM_MEMORY_TYPE; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; @@ -35,14 +34,13 @@ public class MemoryPools { /** Register observers for java runtime memory metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { - return registerObservers(openTelemetry, ManagementFactory.getMemoryPoolMXBeans()); + public static List registerObservers(Meter meter) { + return registerObservers(meter, ManagementFactory.getMemoryPoolMXBeans()); } // Visible for testing public static List registerObservers( - OpenTelemetry openTelemetry, List poolBeans) { - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); + Meter meter, List poolBeans) { List observables = new ArrayList<>(); observables.add( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/SystemCpu.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/SystemCpu.java similarity index 79% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/SystemCpu.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/SystemCpu.java index 735ed1798c21..50bcda59410d 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/SystemCpu.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/SystemCpu.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.Meter; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; @@ -23,20 +22,15 @@ public final class SystemCpu { /** Register observers for java runtime experimental CPU metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { + public static List registerObservers(Meter meter) { return registerObservers( - openTelemetry, - ManagementFactory.getOperatingSystemMXBean(), - CpuMethods.systemCpuUtilization()); + meter, ManagementFactory.getOperatingSystemMXBean(), CpuMethods.systemCpuUtilization()); } // Visible for testing static List registerObservers( - OpenTelemetry openTelemetry, - OperatingSystemMXBean osBean, - @Nullable Supplier systemCpuUtilization) { + Meter meter, OperatingSystemMXBean osBean, @Nullable Supplier systemCpuUtilization) { - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); List observables = new ArrayList<>(); observables.add( meter diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Threads.java b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Threads.java similarity index 86% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Threads.java rename to instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Threads.java index 4fc4e1aebf00..5edbb5c8574f 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/Threads.java +++ b/instrumentation/runtime-telemetry/library/src/main/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/Threads.java @@ -3,13 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.semconv.JvmAttributes.JVM_THREAD_DAEMON; import static io.opentelemetry.semconv.JvmAttributes.JVM_THREAD_STATE; import static java.util.Objects.requireNonNull; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -44,36 +43,34 @@ public class Threads { static final Threads INSTANCE = new Threads(); /** Register observers for java runtime class metrics. */ - public static List registerObservers(OpenTelemetry openTelemetry) { - return INSTANCE.registerObservers(openTelemetry, useThreads()); + public static List registerObservers(Meter meter) { + return INSTANCE.registerObservers(meter, useThreads()); } - private List registerObservers(OpenTelemetry openTelemetry, boolean useThread) { + private List registerObservers(Meter meter, boolean useThread) { if (useThread) { - return registerObservers(openTelemetry, Threads::getThreads); + return registerObservers(meter, Threads::getThreads); } - return registerObservers(openTelemetry, ManagementFactory.getThreadMXBean()); + return registerObservers(meter, ManagementFactory.getThreadMXBean()); } // Visible for testing - List registerObservers(OpenTelemetry openTelemetry, ThreadMXBean threadBean) { + List registerObservers(Meter meter, ThreadMXBean threadBean) { return registerObservers( - openTelemetry, + meter, isJava9OrNewer() ? Threads::java9AndNewerCallback : Threads::java8Callback, threadBean); } // Visible for testing - List registerObservers( - OpenTelemetry openTelemetry, Supplier threadSupplier) { - return registerObservers(openTelemetry, Threads::java8ThreadCallback, threadSupplier); + List registerObservers(Meter meter, Supplier threadSupplier) { + return registerObservers(meter, Threads::java8ThreadCallback, threadSupplier); } private static List registerObservers( - OpenTelemetry openTelemetry, + Meter meter, Function> callbackProvider, T threadInfo) { - Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry); List observables = new ArrayList<>(); observables.add( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/Constants.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/Constants.java similarity index 98% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/Constants.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/Constants.java index d4f3e79d38e8..cfd35f63f3e5 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/Constants.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/Constants.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/DurationUtil.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/DurationUtil.java similarity index 90% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/DurationUtil.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/DurationUtil.java index 27d5110f9df9..23437d6a88ba 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/DurationUtil.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/DurationUtil.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static java.util.concurrent.TimeUnit.SECONDS; diff --git a/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/HandlerRegistry.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/HandlerRegistry.java new file mode 100644 index 000000000000..156b18d3b2b2 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/HandlerRegistry.java @@ -0,0 +1,93 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry.internal; + +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.buffer.DirectBufferStatisticsHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.classes.ClassesLoadedHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.container.ContainerConfigurationHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.cpu.ContextSwitchRateHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.cpu.LongLockHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.cpu.OverallCpuLoadHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.garbagecollection.G1GarbageCollectionHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.garbagecollection.OldGarbageCollectionHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.garbagecollection.YoungGarbageCollectionHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.memory.CodeCacheConfigurationHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.memory.G1HeapSummaryHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.memory.MetaspaceSummaryHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.memory.ObjectAllocationInNewTlabHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.memory.ObjectAllocationOutsideTlabHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.memory.ParallelHeapSummaryHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.network.NetworkReadHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.network.NetworkWriteHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.threads.ThreadCountHandler; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; + +final class HandlerRegistry { + + private HandlerRegistry() {} + + static List getHandlers( + Meter meter, Predicate featurePredicate, boolean useLegacyCpuCountMetric) { + + List handlers = new ArrayList(); + for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) { + String name = bean.getName(); + switch (name) { + case "G1 Young Generation" -> { + handlers.add(new G1HeapSummaryHandler(meter)); + handlers.add(new G1GarbageCollectionHandler(meter)); + } + + case "Copy" -> handlers.add(new YoungGarbageCollectionHandler(meter, name)); + + case "PS Scavenge" -> { + handlers.add(new YoungGarbageCollectionHandler(meter, name)); + handlers.add(new ParallelHeapSummaryHandler(meter)); + } + + case "G1 Old Generation", "PS MarkSweep", "MarkSweepCompact" -> + handlers.add(new OldGarbageCollectionHandler(meter, name)); + + default -> {} + } + } + + List basicHandlers = + List.of( + new ObjectAllocationInNewTlabHandler(meter), + new ObjectAllocationOutsideTlabHandler(meter), + new NetworkReadHandler(meter), + new NetworkWriteHandler(meter), + new ContextSwitchRateHandler(meter), + new OverallCpuLoadHandler(meter), + new ContainerConfigurationHandler(meter, useLegacyCpuCountMetric), + new LongLockHandler(meter), + new ThreadCountHandler(meter), + new ClassesLoadedHandler(meter), + new MetaspaceSummaryHandler(meter), + new CodeCacheConfigurationHandler(meter), + new DirectBufferStatisticsHandler(meter)); + handlers.addAll(basicHandlers); + + // Filter and close disabled handlers + Iterator iter = handlers.iterator(); + while (iter.hasNext()) { + RecordedEventHandler handler = iter.next(); + if (!featurePredicate.test(handler.getFeature())) { + handler.close(); + iter.remove(); + } + } + + return handlers; + } +} diff --git a/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrConfig.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrConfig.java new file mode 100644 index 000000000000..a2583c791f13 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrConfig.java @@ -0,0 +1,219 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry.internal; + +import com.google.errorprone.annotations.CanIgnoreReturnValue; +import io.opentelemetry.api.metrics.Meter; +import java.io.Closeable; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.function.Predicate; +import javax.annotation.Nullable; +import jdk.jfr.EventSettings; +import jdk.jfr.FlightRecorder; +import jdk.jfr.consumer.RecordingStream; + +/** + * Configuration holder for JFR telemetry. On Java 17+, this implementation manages JFR features and + * creates JFR telemetry. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class JfrConfig { + + // Visible for testing + public final EnumMap enabledFeatureMap; + + private boolean useLegacyCpuCountMetric = false; + + /** Create a new JfrConfig with default feature settings. */ + public static JfrConfig create() { + return new JfrConfig(); + } + + protected JfrConfig() { + enabledFeatureMap = new EnumMap<>(JfrFeature.class); + // By default, enable JFR features that don't overlap with JMX and are not experimental + for (JfrFeature feature : JfrFeature.values()) { + enabledFeatureMap.put(feature, !feature.overlapsWithJmx() && !feature.isExperimental()); + } + } + + /** Enable all JFR features. */ + @CanIgnoreReturnValue + public JfrConfig enableAllFeatures() { + Arrays.stream(JfrFeature.values()).forEach(feature -> enabledFeatureMap.put(feature, true)); + return this; + } + + /** Disable all JFR features. */ + @CanIgnoreReturnValue + public JfrConfig disableAllFeatures() { + Arrays.stream(JfrFeature.values()).forEach(feature -> enabledFeatureMap.put(feature, false)); + return this; + } + + /** Enable experimental JFR features. */ + @CanIgnoreReturnValue + public JfrConfig enableExperimentalFeatures() { + Arrays.stream(JfrFeature.values()) + .filter(JfrFeature::isExperimental) + .forEach(feature -> enabledFeatureMap.put(feature, true)); + return this; + } + + /** Enable a specific JFR feature. */ + @CanIgnoreReturnValue + public JfrConfig enableFeature(JfrFeature feature) { + enabledFeatureMap.put(feature, true); + return this; + } + + /** Enable a specific JFR feature by name. */ + @CanIgnoreReturnValue + public JfrConfig enableFeature(String featureName) { + enableFeature(JfrFeature.valueOf(featureName)); + return this; + } + + /** Disable a specific JFR feature. */ + @CanIgnoreReturnValue + public JfrConfig disableFeature(JfrFeature feature) { + enabledFeatureMap.put(feature, false); + return this; + } + + /** Disable a specific JFR feature by name. */ + @CanIgnoreReturnValue + public JfrConfig disableFeature(String featureName) { + disableFeature(JfrFeature.valueOf(featureName)); + return this; + } + + /** + * Sets whether to use the legacy metric name {@code jvm.cpu.limit} instead of the standard {@code + * jvm.cpu.count}. This is for backward compatibility with previous versions. + */ + @CanIgnoreReturnValue + public JfrConfig setUseLegacyJfrCpuCountMetric(boolean useLegacy) { + this.useLegacyCpuCountMetric = useLegacy; + return this; + } + + /** + * Build JFR telemetry based on the current configuration. + * + * @param preferJfrMetrics if true, enable JFR features that overlap with JMX + * @param meter the Meter to use for metrics + * @return the JFR telemetry closeable, or null if JFR is not available or all features are + * disabled + */ + @Nullable + public AutoCloseable buildJfrTelemetry(boolean preferJfrMetrics, Meter meter) { + // If preferJfrMetrics is set, enable JFR features that overlap with JMX + if (preferJfrMetrics) { + for (JfrFeature feature : JfrFeature.values()) { + if (feature.overlapsWithJmx()) { + enabledFeatureMap.put(feature, true); + } + } + } + + if (enabledFeatureMap.values().stream().noneMatch(isEnabled -> isEnabled)) { + return null; + } + return JfrRuntimeMetrics.build(meter, enabledFeatureMap::get, useLegacyCpuCountMetric); + } + + /** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ + public static class JfrRuntimeMetrics implements Closeable { + private final List recordedEventHandlers; + private final RecordingStream recordingStream; + private final CountDownLatch startUpLatch = new CountDownLatch(1); + private volatile boolean closed = false; + + private JfrRuntimeMetrics( + Meter meter, Predicate featurePredicate, boolean useLegacyCpuCountMetric) { + this.recordedEventHandlers = + HandlerRegistry.getHandlers(meter, featurePredicate, useLegacyCpuCountMetric); + recordingStream = new RecordingStream(); + recordedEventHandlers.forEach( + handler -> { + EventSettings eventSettings = recordingStream.enable(handler.getEventName()); + handler.getPollingDuration().ifPresent(eventSettings::withPeriod); + handler.getThreshold().ifPresent(eventSettings::withThreshold); + recordingStream.onEvent(handler.getEventName(), handler); + }); + recordingStream.onMetadata(event -> startUpLatch.countDown()); + Thread daemonRunner = + new Thread(this::startRecordingStream, "OpenTelemetry JFR-Metrics-Runner"); + daemonRunner.setDaemon(true); + daemonRunner.setContextClassLoader(null); + daemonRunner.start(); + } + + private void startRecordingStream() { + if (closed) { + return; + } + + try { + recordingStream.start(); + } catch (IllegalStateException exception) { + // Can happen when close is called at the same time as start + if (!closed) { + throw exception; + } + } + } + + @Nullable + static JfrRuntimeMetrics build( + Meter meter, Predicate featurePredicate, boolean useLegacyCpuCountMetric) { + if (!isJfrAvailable()) { + return null; + } + return new JfrRuntimeMetrics(meter, featurePredicate, useLegacyCpuCountMetric); + } + + @Override + public void close() { + closed = true; + recordingStream.close(); + recordedEventHandlers.forEach(RecordedEventHandler::close); + } + + // Visible for testing + public List getRecordedEventHandlers() { + return recordedEventHandlers; + } + + // Visible for testing + public RecordingStream getRecordingStream() { + return recordingStream; + } + + // Visible for testing + public CountDownLatch getStartUpLatch() { + return startUpLatch; + } + + private static boolean isJfrAvailable() { + try { + return FlightRecorder.isAvailable(); + } catch (Throwable e) { + // NoClassDefFoundError, UnsatisfiedLinkError (native images), or other issues + return false; + } + } + } +} diff --git a/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrFeature.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrFeature.java new file mode 100644 index 000000000000..598462e9bc94 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/JfrFeature.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry.internal; + +/** + * Enumeration of JFR features, used internally to control which JFR events are registered. + * + *

Features that overlap with stable JMX-based instrumentation are disabled by default to avoid + * duplicate metrics. Experimental features (those not marked stable in the semantic conventions) + * are also disabled by default and require {@code emit_experimental_metrics=true} to enable. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public enum JfrFeature { + BUFFER_METRICS(/* overlapsWithJmx= */ true, /* experimental= */ true), + CLASS_LOAD_METRICS(/* overlapsWithJmx= */ true, /* experimental= */ false), + CONTEXT_SWITCH_METRICS(/* overlapsWithJmx= */ false, /* experimental= */ true), + CPU_COUNT_METRICS(/* overlapsWithJmx= */ true, /* experimental= */ false), + CPU_UTILIZATION_METRICS(/* overlapsWithJmx= */ true, /* experimental= */ false), + GC_DURATION_METRICS(/* overlapsWithJmx= */ true, /* experimental= */ false), + LOCK_METRICS(/* overlapsWithJmx= */ false, /* experimental= */ true), + MEMORY_ALLOCATION_METRICS(/* overlapsWithJmx= */ false, /* experimental= */ true), + MEMORY_POOL_METRICS(/* overlapsWithJmx= */ true, /* experimental= */ false), + NETWORK_IO_METRICS(/* overlapsWithJmx= */ false, /* experimental= */ true), + THREAD_METRICS(/* overlapsWithJmx= */ true, /* experimental= */ false), + ; + + private final boolean overlapsWithJmx; + private final boolean experimental; + + JfrFeature(boolean overlapsWithJmx, boolean experimental) { + this.overlapsWithJmx = overlapsWithJmx; + this.experimental = experimental; + } + + /** Returns true if this JFR feature overlaps with JMX-based metrics. */ + public boolean overlapsWithJmx() { + return overlapsWithJmx; + } + + /** Returns true if this JFR feature produces experimental (non-stable) metrics. */ + public boolean isExperimental() { + return experimental; + } +} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RecordedEventHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/RecordedEventHandler.java similarity index 93% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RecordedEventHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/RecordedEventHandler.java index 16df1a9405a5..920fc0eafb4e 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RecordedEventHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/RecordedEventHandler.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; import java.time.Duration; import java.util.List; import java.util.Optional; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/buffer/DirectBufferStatisticsHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/buffer/DirectBufferStatisticsHandler.java similarity index 90% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/buffer/DirectBufferStatisticsHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/buffer/DirectBufferStatisticsHandler.java index 2f9ed50b2c26..12e2d46770a7 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/buffer/DirectBufferStatisticsHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/buffer/DirectBufferStatisticsHandler.java @@ -3,14 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.buffer; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.buffer; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.ArrayList; import java.util.List; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/classes/ClassesLoadedHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/classes/ClassesLoadedHandler.java similarity index 89% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/classes/ClassesLoadedHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/classes/ClassesLoadedHandler.java index 98bee7942725..47e5ec8a8256 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/classes/ClassesLoadedHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/classes/ClassesLoadedHandler.java @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.classes; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.classes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.ArrayList; import java.util.List; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/container/ContainerConfigurationHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/container/ContainerConfigurationHandler.java similarity index 51% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/container/ContainerConfigurationHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/container/ContainerConfigurationHandler.java index 09220d3c6beb..7e29caa8a4fc 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/container/ContainerConfigurationHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/container/ContainerConfigurationHandler.java @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.container; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.container; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.util.ArrayList; import java.util.List; import jdk.jfr.consumer.RecordedEvent; @@ -18,7 +18,10 @@ * any time. */ public final class ContainerConfigurationHandler implements RecordedEventHandler { - private static final String METRIC_NAME = "jvm.cpu.limit"; + private static final String METRIC_NAME = "jvm.cpu.count"; + // Legacy metric name for backward compatibility with runtime-telemetry-java17 module + private static final String LEGACY_METRIC_NAME = "jvm.cpu.limit"; + private static final String EVENT_NAME = "jdk.ContainerConfiguration"; private static final String EFFECTIVE_CPU_COUNT = "effectiveCpuCount"; @@ -26,12 +29,15 @@ public final class ContainerConfigurationHandler implements RecordedEventHandler private volatile long value = 0L; - public ContainerConfigurationHandler(Meter meter) { - observables.add( - meter - .upDownCounterBuilder(METRIC_NAME) - .setUnit(Constants.ONE) - .buildWithCallback(codm -> codm.record(value))); + public ContainerConfigurationHandler(Meter meter, boolean useLegacyMetric) { + var builder = + useLegacyMetric + ? meter.upDownCounterBuilder(LEGACY_METRIC_NAME).setUnit(Constants.ONE) + : meter + .upDownCounterBuilder(METRIC_NAME) + .setUnit("{cpu}") + .setDescription("Number of processors available to the Java virtual machine."); + observables.add(builder.buildWithCallback(codm -> codm.record(value))); } @Override diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/ContextSwitchRateHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/ContextSwitchRateHandler.java similarity index 81% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/ContextSwitchRateHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/ContextSwitchRateHandler.java index 39a3dc6efa7c..fea1769fecb1 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/ContextSwitchRateHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/ContextSwitchRateHandler.java @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.cpu; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.cpu; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.ArrayList; import java.util.List; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/LongLockHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/LongLockHandler.java similarity index 80% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/LongLockHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/LongLockHandler.java index b3dfad486887..cc1d66691a92 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/LongLockHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/LongLockHandler.java @@ -3,15 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.cpu; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.cpu; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.DurationUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.DurationUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.Optional; import jdk.jfr.consumer.RecordedEvent; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/OverallCpuLoadHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/OverallCpuLoadHandler.java similarity index 88% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/OverallCpuLoadHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/OverallCpuLoadHandler.java index 260b26857c9e..59ffbfc6829b 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/cpu/OverallCpuLoadHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/cpu/OverallCpuLoadHandler.java @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.cpu; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.cpu; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.ArrayList; import java.util.List; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/G1GarbageCollectionHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/G1GarbageCollectionHandler.java similarity index 78% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/G1GarbageCollectionHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/G1GarbageCollectionHandler.java index 2ac74dd9b8f9..089fededcd32 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/G1GarbageCollectionHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/G1GarbageCollectionHandler.java @@ -3,15 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.garbagecollection; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.garbagecollection; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.DurationUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.DurationUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.Optional; import jdk.jfr.consumer.RecordedEvent; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/OldGarbageCollectionHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/OldGarbageCollectionHandler.java similarity index 78% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/OldGarbageCollectionHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/OldGarbageCollectionHandler.java index 7fbaeeadefed..840c3fb2aa7b 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/OldGarbageCollectionHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/OldGarbageCollectionHandler.java @@ -3,15 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.garbagecollection; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.garbagecollection; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.DurationUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.DurationUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.Optional; import jdk.jfr.consumer.RecordedEvent; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/YoungGarbageCollectionHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/YoungGarbageCollectionHandler.java similarity index 79% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/YoungGarbageCollectionHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/YoungGarbageCollectionHandler.java index 53fa2f22da81..8fc75c8079d3 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/garbagecollection/YoungGarbageCollectionHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/garbagecollection/YoungGarbageCollectionHandler.java @@ -3,15 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.garbagecollection; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.garbagecollection; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.DurationUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.DurationUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.Optional; import jdk.jfr.consumer.RecordedEvent; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/CodeCacheConfigurationHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/CodeCacheConfigurationHandler.java similarity index 84% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/CodeCacheConfigurationHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/CodeCacheConfigurationHandler.java index 1b11c80ea4d1..1515722a22a7 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/CodeCacheConfigurationHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/CodeCacheConfigurationHandler.java @@ -3,13 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.memory; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.ArrayList; import java.util.List; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/G1HeapSummaryHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/G1HeapSummaryHandler.java similarity index 93% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/G1HeapSummaryHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/G1HeapSummaryHandler.java index 05c8a49fb5cc..a292e0bdfe31 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/G1HeapSummaryHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/G1HeapSummaryHandler.java @@ -3,13 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.memory; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/MetaspaceSummaryHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/MetaspaceSummaryHandler.java similarity index 91% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/MetaspaceSummaryHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/MetaspaceSummaryHandler.java index fcbe93cafbab..06f44688e917 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/MetaspaceSummaryHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/MetaspaceSummaryHandler.java @@ -3,13 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.memory; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -128,8 +128,8 @@ private static void doIfAvailable( return; } Object value = event.getValue(field); - if (value instanceof RecordedObject) { - closure.accept((RecordedObject) value); + if (value instanceof RecordedObject recordedObject) { + closure.accept(recordedObject); } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ObjectAllocationInNewTlabHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ObjectAllocationInNewTlabHandler.java similarity index 82% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ObjectAllocationInNewTlabHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ObjectAllocationInNewTlabHandler.java index c04de5bf944c..5d960d3270cc 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ObjectAllocationInNewTlabHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ObjectAllocationInNewTlabHandler.java @@ -3,14 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.memory; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import jdk.jfr.consumer.RecordedEvent; /** diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ObjectAllocationOutsideTlabHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ObjectAllocationOutsideTlabHandler.java similarity index 82% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ObjectAllocationOutsideTlabHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ObjectAllocationOutsideTlabHandler.java index 30dfc78c0126..a26098eaf623 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ObjectAllocationOutsideTlabHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ObjectAllocationOutsideTlabHandler.java @@ -3,14 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.memory; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import jdk.jfr.consumer.RecordedEvent; /** diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ParallelHeapSummaryHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ParallelHeapSummaryHandler.java similarity index 94% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ParallelHeapSummaryHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ParallelHeapSummaryHandler.java index 3ec8e57c845d..1ec213b187f0 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/memory/ParallelHeapSummaryHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/memory/ParallelHeapSummaryHandler.java @@ -3,13 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.memory; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; @@ -145,8 +145,8 @@ private static void doIfAvailable( return; } Object value = event.getValue(field); - if (value instanceof RecordedObject) { - closure.accept((RecordedObject) value); + if (value instanceof RecordedObject recordedObject) { + closure.accept(recordedObject); } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/network/NetworkReadHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/network/NetworkReadHandler.java similarity index 81% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/network/NetworkReadHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/network/NetworkReadHandler.java index e84ca15a2315..4ce834b41bf1 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/network/NetworkReadHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/network/NetworkReadHandler.java @@ -3,16 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.network; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.network; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.DurationUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.DurationUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import jdk.jfr.consumer.RecordedEvent; /** diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/network/NetworkWriteHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/network/NetworkWriteHandler.java similarity index 85% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/network/NetworkWriteHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/network/NetworkWriteHandler.java index 8d0124ff4bcf..9ccdc1031d0f 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/network/NetworkWriteHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/network/NetworkWriteHandler.java @@ -3,16 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.network; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.network; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.DurationUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.DurationUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import jdk.jfr.consumer.RecordedEvent; // jdk.SocketWrite { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/threads/ThreadCountHandler.java b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/threads/ThreadCountHandler.java similarity index 85% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/threads/ThreadCountHandler.java rename to instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/threads/ThreadCountHandler.java index ef741482cc3f..b936ec957fa7 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/threads/ThreadCountHandler.java +++ b/instrumentation/runtime-telemetry/library/src/main/java17/io/opentelemetry/instrumentation/runtimetelemetry/internal/threads/ThreadCountHandler.java @@ -3,13 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal.threads; +package io.opentelemetry.instrumentation.runtimetelemetry.internal.threads; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.runtimemetrics.java17.JfrFeature; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.RecordedEventHandler; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -23,7 +23,7 @@ public final class ThreadCountHandler implements RecordedEventHandler { private static final String METRIC_NAME = "jvm.thread.count"; private static final String EVENT_NAME = "jdk.JavaThreadStatistics"; - private static final String METRIC_DESCRIPTION = "Number of executing threads"; + private static final String METRIC_DESCRIPTION = "Number of executing platform threads."; private static final Attributes ATTR_DAEMON_TRUE = Attributes.of(Constants.ATTR_DAEMON, true); private static final Attributes ATTR_DAEMON_FALSE = Attributes.of(Constants.ATTR_DAEMON, false); diff --git a/instrumentation/runtime-telemetry/library/src/main/resources/META-INF/native-image/reflect-config.json b/instrumentation/runtime-telemetry/library/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 000000000000..1e250d63300c --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,10 @@ +[ + { + "name": "com.sun.management.OperatingSystemMXBean", + "allPublicMethods": true + }, + { + "name": "com.ibm.lang.management.OperatingSystemMXBean", + "allPublicMethods": true + } +] diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/BufferPoolsTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/BufferPoolsTest.java similarity index 89% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/BufferPoolsTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/BufferPoolsTest.java index 5cbf8c87fa1f..f2d5b87cd915 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/BufferPoolsTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/BufferPoolsTest.java @@ -3,10 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.Collections.singletonList; import static org.mockito.ArgumentMatchers.any; @@ -52,16 +51,15 @@ void registerObservers() { when(bufferPoolBean.getTotalCapacity()).thenReturn(11L); when(bufferPoolBean.getCount()).thenReturn(12L); - BufferPools.registerObservers(testing.getOpenTelemetry(), beans); + BufferPools.registerObservers(testing.getOpenTelemetry().getMeter("test"), beans); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.buffer.memory.used", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Measure of memory used by buffers.") .hasUnit("By") .hasLongSumSatisfying( @@ -74,13 +72,12 @@ void registerObservers() { stringKey("jvm.buffer.pool.name"), "buffer_pool_1"))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.buffer.memory.limit", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Measure of total memory capacity of buffers.") .hasUnit("By") .hasLongSumSatisfying( @@ -93,13 +90,12 @@ void registerObservers() { stringKey("jvm.buffer.pool.name"), "buffer_pool_1"))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.buffer.count", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Number of buffers in the pool.") .hasUnit("{buffer}") .hasLongSumSatisfying( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/ClassesTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/ClassesTest.java similarity index 85% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/ClassesTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/ClassesTest.java index 5399e84efa47..34069b83250d 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/ClassesTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/ClassesTest.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.mockito.Mockito.when; @@ -33,16 +32,15 @@ void registerObservers() { when(classBean.getUnloadedClassCount()).thenReturn(2L); when(classBean.getLoadedClassCount()).thenReturn(1); - Classes.INSTANCE.registerObservers(testing.getOpenTelemetry(), classBean); + Classes.INSTANCE.registerObservers(testing.getOpenTelemetry().getMeter("test"), classBean); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.class.loaded", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Number of classes loaded since JVM start.") .hasUnit("{class}") .hasLongSumSatisfying( @@ -52,13 +50,12 @@ void registerObservers() { point -> point.hasValue(3).hasAttributes(Attributes.empty()))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.class.unloaded", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Number of classes unloaded since JVM start.") .hasUnit("{class}") .hasLongSumSatisfying( @@ -68,13 +65,12 @@ void registerObservers() { point -> point.hasValue(2).hasAttributes(Attributes.empty()))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.class.count", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Number of classes currently loaded.") .hasUnit("{class}") .hasLongSumSatisfying( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/CpuTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/CpuTest.java similarity index 81% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/CpuTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/CpuTest.java index 982abad9eaa6..e35a748ce8aa 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/CpuTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/CpuTest.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; @@ -28,16 +27,18 @@ void registerObservers() { Supplier processCpuUtilization = () -> 0.05; Cpu.INSTANCE.registerObservers( - testing.getOpenTelemetry(), availableProcessors, processCpuTime, processCpuUtilization); + testing.getOpenTelemetry().getMeter("test"), + availableProcessors, + processCpuTime, + processCpuUtilization); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.cpu.time", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("CPU time used by the process as reported by the JVM.") .hasUnit("s") .hasDoubleSumSatisfying( @@ -46,13 +47,12 @@ void registerObservers() { .isMonotonic() .hasPointsSatisfying(point -> point.hasValue(42))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.cpu.count", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription( "Number of processors available to the Java virtual machine.") .hasUnit("{cpu}") @@ -62,13 +62,12 @@ void registerObservers() { .isNotMonotonic() .hasPointsSatisfying(point -> point.hasValue(8))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.cpu.recent_utilization", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription( "Recent CPU utilization for the process as reported by the JVM.") .hasUnit("1") diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/FileDescriptorTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/FileDescriptorTest.java similarity index 54% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/FileDescriptorTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/FileDescriptorTest.java index e1711e7bd4e1..b36b287d1d46 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/FileDescriptorTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/FileDescriptorTest.java @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.mockito.Mockito.when; @@ -41,28 +41,34 @@ void setUp() { @Test void registerObservers() { // we have to test for positive and negative values in the same test as the metric is only - // registered for positive values. Also, the JVM might return Long.MAX_VALUE when there is no - // limit. + // registered for positive values. when(osBean.getOpenFileDescriptorCount()).thenReturn(-1L, 42L); - when(osBean.getMaxFileDescriptorCount()).thenReturn(Long.MAX_VALUE, -1L, 100L); - FileDescriptor.registerObservers(testing.getOpenTelemetry(), osBean); + when(osBean.getMaxFileDescriptorCount()).thenReturn(-1L, 100L); + FileDescriptor.registerObservers(testing.getOpenTelemetry().getMeter("test"), osBean); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", - metric -> - metric - .hasName("jvm.file_descriptor.count") - .hasInstrumentationScope(EXPECTED_SCOPE) - .hasDescription("Number of open file descriptors as reported by the JVM.") - .hasUnit("{file_descriptor}") - .hasLongSumSatisfying(sum -> sum.hasPointsSatisfying(point -> point.hasValue(42))), - metric -> - metric - .hasName("jvm.file_descriptor.limit") - .hasInstrumentationScope(EXPECTED_SCOPE) - .hasDescription("Measure of max open file descriptors as reported by the JVM.") - .hasUnit("{file_descriptor}") - .hasLongSumSatisfying( - sum -> sum.hasPointsSatisfying(point -> point.hasValue(100)))); + "test", + "jvm.file_descriptor.count", + metrics -> + metrics.anySatisfy( + metricData -> + assertThat(metricData) + .hasDescription("Number of open file descriptors as reported by the JVM.") + .hasUnit("{file_descriptor}") + .hasLongSumSatisfying( + sum -> sum.hasPointsSatisfying(point -> point.hasValue(42))))); + + testing.waitAndAssertMetrics( + "test", + "jvm.file_descriptor.limit", + metrics -> + metrics.anySatisfy( + metricData -> + assertThat(metricData) + .hasDescription( + "Measure of max open file descriptors as reported by the JVM.") + .hasUnit("{file_descriptor}") + .hasLongSumSatisfying( + sum -> sum.hasPointsSatisfying(point -> point.hasValue(100))))); } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/GarbageCollectorTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollectorTest.java similarity index 95% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/GarbageCollectorTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollectorTest.java index f6fe2a7a115d..25e73fbcb235 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/GarbageCollectorTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollectorTest.java @@ -3,10 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.JvmAttributes.JVM_GC_ACTION; @@ -56,7 +55,7 @@ class GarbageCollectorTest { @ValueSource(booleans = {true, false}) void registerObservers(boolean captureGcCause) { GarbageCollector.registerObservers( - testing.getOpenTelemetry(), + testing.getOpenTelemetry().getMeter("test"), singletonList(gcBean), GarbageCollectorTest::getGcNotificationInfo, captureGcCause); @@ -75,13 +74,12 @@ void registerObservers(boolean captureGcCause) { createTestNotification("G1 Old Generation", "end of major GC", "System.gc()", 11), null); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.gc.duration", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Duration of JVM garbage collection actions.") .hasUnit("s") .hasHistogramSatisfying( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryInitTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryInitTest.java similarity index 90% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryInitTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryInitTest.java index fa4e985c18db..645ccf4d6413 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryInitTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryInitTest.java @@ -3,10 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.Arrays.asList; import static org.mockito.Mockito.when; @@ -56,16 +55,15 @@ void setup() { void registerObservers() { when(heapPoolUsage.getInit()).thenReturn(11L); when(nonHeapUsage.getInit()).thenReturn(15L); - MemoryInit.registerObservers(testing.getOpenTelemetry(), beans); + MemoryInit.registerObservers(testing.getOpenTelemetry().getMeter("test"), beans); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.memory.init", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Measure of initial memory requested.") .hasUnit("By") .hasLongSumSatisfying( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryPoolsTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryPoolsTest.java similarity index 93% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryPoolsTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryPoolsTest.java index 97c58aa5e44f..e1935a1c5c71 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/MemoryPoolsTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/MemoryPoolsTest.java @@ -3,10 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; @@ -78,16 +77,15 @@ void registerObservers() { when(nonHeapUsage.getMax()).thenReturn(17L); when(heapCollectionUsage.getUsed()).thenReturn(18L); when(nonHeapCollectionUsage.getUsed()).thenReturn(19L); - MemoryPools.registerObservers(testing.getOpenTelemetry(), beans); + MemoryPools.registerObservers(testing.getOpenTelemetry().getMeter("test"), beans); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.memory.used", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Measure of memory used.") .hasUnit("By") .hasLongSumSatisfying( @@ -107,13 +105,12 @@ void registerObservers() { .hasAttribute( stringKey("jvm.memory.type"), "non_heap"))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.memory.committed", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Measure of memory committed.") .hasUnit("By") .hasLongSumSatisfying( @@ -133,13 +130,12 @@ void registerObservers() { .hasAttribute( stringKey("jvm.memory.type"), "non_heap"))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.memory.limit", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Measure of max obtainable memory.") .hasUnit("By") .hasLongSumSatisfying( @@ -159,13 +155,12 @@ void registerObservers() { .hasAttribute( stringKey("jvm.memory.type"), "non_heap"))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.memory.used_after_last_gc", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription( "Measure of memory used, as measured after the most recent garbage collection event on this pool.") .hasUnit("By") diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/SystemCpuTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/SystemCpuTest.java similarity index 81% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/SystemCpuTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/SystemCpuTest.java index 19e27ee37493..0ee84a7e12ff 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/SystemCpuTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/SystemCpuTest.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.mockito.Mockito.when; @@ -32,29 +31,28 @@ void registerObservers() { when(osBean.getSystemLoadAverage()).thenReturn(2.2); Supplier systemCpuUtilization = () -> 0.11; - SystemCpu.registerObservers(testing.getOpenTelemetry(), osBean, systemCpuUtilization); + SystemCpu.registerObservers( + testing.getOpenTelemetry().getMeter("test"), osBean, systemCpuUtilization); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.system.cpu.load_1m", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription( "Average CPU load of the whole system for the last minute as reported by the JVM.") .hasUnit("{run_queue_item}") .hasDoubleGaugeSatisfying( gauge -> gauge.hasPointsSatisfying(point -> point.hasValue(2.2))))); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.system.cpu.utilization", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription( "Recent CPU utilization for the whole system as reported by the JVM.") .hasUnit("1") diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/ThreadsTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/ThreadsTest.java similarity index 91% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/ThreadsTest.java rename to instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/ThreadsTest.java index 860eb28aa42b..bc9ba0738ff4 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/ThreadsTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/ThreadsTest.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; -import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.JvmAttributes.JVM_THREAD_DAEMON; @@ -49,17 +48,16 @@ void registerObservers_Java8Jmx() { when(threadBean.getDaemonThreadCount()).thenReturn(2); Threads.INSTANCE - .registerObservers(testing.getOpenTelemetry(), threadBean) + .registerObservers(testing.getOpenTelemetry().getMeter("test"), threadBean) .forEach(cleanup::deferCleanup); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.thread.count", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Number of executing platform threads.") .hasUnit("{thread}") .hasLongSumSatisfying( @@ -86,17 +84,16 @@ void registerObservers_Java8Thread() { Thread[] threads = new Thread[] {threadInfo1, threadInfo2}; Threads.INSTANCE - .registerObservers(testing.getOpenTelemetry(), () -> threads) + .registerObservers(testing.getOpenTelemetry().getMeter("test"), () -> threads) .forEach(cleanup::deferCleanup); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.thread.count", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Number of executing platform threads.") .hasUnit("{thread}") .hasLongSumSatisfying( @@ -131,17 +128,16 @@ void registerObservers_Java9AndNewer() { .thenReturn(new ThreadInfo[] {threadInfo1, null, threadInfo2}); Threads.INSTANCE - .registerObservers(testing.getOpenTelemetry(), threadBean) + .registerObservers(testing.getOpenTelemetry().getMeter("test"), threadBean) .forEach(cleanup::deferCleanup); testing.waitAndAssertMetrics( - "io.opentelemetry.runtime-telemetry-java8", + "test", "jvm.thread.count", metrics -> metrics.anySatisfy( metricData -> assertThat(metricData) - .hasInstrumentationScope(EXPECTED_SCOPE) .hasDescription("Number of executing platform threads.") .hasUnit("{thread}") .hasLongSumSatisfying( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/BufferMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/BufferMetricTest.java similarity index 87% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/BufferMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/BufferMetricTest.java index 25d999c4f118..2ae95715ed2d 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/BufferMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/BufferMetricTest.java @@ -3,15 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.BYTES; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.UNIT_BUFFERS; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.BYTES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.UNIT_BUFFERS; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import java.nio.ByteBuffer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -21,7 +22,10 @@ class BufferMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.BUFFER_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.BUFFER_METRICS); + }); /** * This is a basic test that allocates some buffers and tests to make sure the resulting JFR event diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/CodeCacheMemoryInitMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/CodeCacheMemoryInitMetricTest.java similarity index 58% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/CodeCacheMemoryInitMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/CodeCacheMemoryInitMetricTest.java index 49ccd293a9ce..5beb498e0185 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/CodeCacheMemoryInitMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/CodeCacheMemoryInitMetricTest.java @@ -3,14 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_CODE_CACHE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.BYTES; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY_INIT; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY_INIT; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_CODE_CACHE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.BYTES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY_INIT; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY_INIT; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -19,7 +20,10 @@ class CodeCacheMemoryInitMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.MEMORY_POOL_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.MEMORY_POOL_METRICS); + }); @Test void shouldHaveMemoryInitMetrics() { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/G1GcMemoryMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/G1GcMemoryMetricTest.java similarity index 60% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/G1GcMemoryMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/G1GcMemoryMetricTest.java index f341d8920b93..6d50f87c0fe3 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/G1GcMemoryMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/G1GcMemoryMetricTest.java @@ -3,27 +3,28 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_G1_EDEN_SPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_G1_SURVIVOR_SPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_GC_ACTION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_GC_NAME; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.BYTES; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.END_OF_MAJOR_GC; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.END_OF_MINOR_GC; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_COMMITTED; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_GC_DURATION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY_AFTER; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_COMMITTED; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_GC_DURATION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY_AFTER; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.SECONDS; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_G1_EDEN_SPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_G1_SURVIVOR_SPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_GC_ACTION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_GC_NAME; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.BYTES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.END_OF_MAJOR_GC; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.END_OF_MINOR_GC; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_COMMITTED; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_GC_DURATION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY_AFTER; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_COMMITTED; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_GC_DURATION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY_AFTER; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.SECONDS; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import io.opentelemetry.sdk.metrics.data.MetricData; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -33,11 +34,11 @@ class G1GcMemoryMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> - builder - .disableAllFeatures() - .enableFeature(JfrFeature.GC_DURATION_METRICS) - .enableFeature(JfrFeature.MEMORY_POOL_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.GC_DURATION_METRICS); + jfrConfig.enableFeature(JfrFeature.MEMORY_POOL_METRICS); + }); @Test void shouldHaveMemoryMetrics() { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/GenerateDocs.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/GenerateDocs.java similarity index 83% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/GenerateDocs.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/GenerateDocs.java index c9fb2b704cda..1ff6ccae9a58 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/GenerateDocs.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/GenerateDocs.java @@ -3,12 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; import static java.util.logging.Level.WARNING; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toSet; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrConfig; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -38,7 +40,7 @@ private GenerateDocs() {} public static void main(String[] args) throws Exception { // Suppress info level logs - Logger.getLogger(RuntimeMetrics.class.getName()).setLevel(WARNING); + Logger.getLogger(RuntimeTelemetry.class.getName()).setLevel(WARNING); String jfrReadmePath = System.getProperty(JFR_README_PATH_KEY); if (jfrReadmePath == null) { @@ -52,6 +54,15 @@ public static void main(String[] args) throws Exception { logger.info("Done"); } + private static RuntimeTelemetry buildTelemetryForFeature( + OpenTelemetrySdk sdk, JfrFeature feature) { + RuntimeTelemetryBuilder builder = RuntimeTelemetry.builder(sdk); + JfrConfig jfrConfig = builder.getJfrConfig(); + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(feature); + return builder.build(); + } + private static String generateMarkdownTable() throws InterruptedException { // Create new JfrTelemetry for each JfrFeature Map map = new HashMap<>(); @@ -63,10 +74,7 @@ private static String generateMarkdownTable() throws InterruptedException { .build(); map.put( feature, - new JfrTelemetryWithFeature( - RuntimeMetrics.builder(sdk).disableAllFeatures().enableFeature(feature).build(), - sdk, - reader)); + new JfrTelemetryWithFeature(buildTelemetryForFeature(sdk, feature), sdk, reader)); } // Exercise JVM to produce various JFR events @@ -94,7 +102,7 @@ private static String generateMarkdownTable() throws InterruptedException { .append("| ") .append(feature.name()) .append(" | ") - .append(feature.isDefaultEnabled()) + .append(!feature.overlapsWithJmx() && !feature.isExperimental()) .append(" | ") .append(metricCol) .append(" |") @@ -107,12 +115,12 @@ private static String generateMarkdownTable() throws InterruptedException { } private static class JfrTelemetryWithFeature { - private final RuntimeMetrics jfrTelemetry; + private final RuntimeTelemetry jfrTelemetry; private final OpenTelemetrySdk sdk; private final InMemoryMetricReader reader; private JfrTelemetryWithFeature( - RuntimeMetrics jfrTelemetry, OpenTelemetrySdk sdk, InMemoryMetricReader reader) { + RuntimeTelemetry jfrTelemetry, OpenTelemetrySdk sdk, InMemoryMetricReader reader) { this.jfrTelemetry = jfrTelemetry; this.sdk = sdk; this.reader = reader; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrClassesLoadedCountTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrClassesLoadedCountTest.java similarity index 85% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrClassesLoadedCountTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrClassesLoadedCountTest.java index 4e5eb144be30..f1727e0855e5 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrClassesLoadedCountTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrClassesLoadedCountTest.java @@ -3,11 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.UNIT_CLASSES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.UNIT_CLASSES; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -16,7 +17,10 @@ class JfrClassesLoadedCountTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.CLASS_LOAD_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.CLASS_LOAD_METRICS); + }); @Test void shouldHaveJfrLoadedClassesCountEvents() throws Exception { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrCpuLockTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrCpuLockTest.java similarity index 80% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrCpuLockTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrCpuLockTest.java index ce16fc528457..c9ba68f028e9 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrCpuLockTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrCpuLockTest.java @@ -3,11 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.SECONDS; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.SECONDS; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import java.time.Duration; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.Test; @@ -18,7 +19,10 @@ class JfrCpuLockTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.LOCK_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.LOCK_METRICS); + }); @Test void shouldHaveLockEvents() throws Exception { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrExtension.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrExtension.java similarity index 80% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrExtension.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrExtension.java index dc63325c2d4b..ccfd696785ac 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrExtension.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrExtension.java @@ -3,12 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static org.awaitility.Awaitility.await; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrConfig; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -24,14 +25,14 @@ public class JfrExtension implements BeforeEachCallback, AfterEachCallback { - private final Consumer builderConsumer; + private final Consumer jfrConfigConsumer; private SdkMeterProvider meterProvider; private InMemoryMetricReader metricReader; - private RuntimeMetrics runtimeMetrics; + private RuntimeTelemetry runtimeMetrics; - public JfrExtension(Consumer builderConsumer) { - this.builderConsumer = builderConsumer; + public JfrExtension(Consumer jfrConfigConsumer) { + this.jfrConfigConsumer = jfrConfigConsumer; } @Override @@ -46,10 +47,11 @@ public void beforeEach(ExtensionContext context) throws InterruptedException { metricReader = InMemoryMetricReader.create(); meterProvider = SdkMeterProvider.builder().registerMetricReader(metricReader).build(); OpenTelemetrySdk sdk = OpenTelemetrySdk.builder().setMeterProvider(meterProvider).build(); - RuntimeMetricsBuilder builder = RuntimeMetrics.builder(sdk); - builderConsumer.accept(builder); + RuntimeTelemetryBuilder builder = RuntimeTelemetry.builder(sdk); + jfrConfigConsumer.accept(builder.getJfrConfig()); runtimeMetrics = builder.build(); - RuntimeMetrics.JfrRuntimeMetrics jfrRuntimeMetrics = runtimeMetrics.getJfrRuntimeMetrics(); + JfrConfig.JfrRuntimeMetrics jfrRuntimeMetrics = + (JfrConfig.JfrRuntimeMetrics) runtimeMetrics.getJfrTelemetry(); if (jfrRuntimeMetrics != null) { jfrRuntimeMetrics.getStartUpLatch().await(30, SECONDS); } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrOverallCpuLoadHandlerTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrOverallCpuLoadHandlerTest.java similarity index 71% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrOverallCpuLoadHandlerTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrOverallCpuLoadHandlerTest.java index 38c8585a50d0..d1406e42ccba 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrOverallCpuLoadHandlerTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrOverallCpuLoadHandlerTest.java @@ -3,10 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.UNIT_UTILIZATION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.UNIT_UTILIZATION; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -15,8 +16,10 @@ class JfrOverallCpuLoadHandlerTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> - builder.disableAllFeatures().enableFeature(JfrFeature.CPU_UTILIZATION_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.CPU_UTILIZATION_METRICS); + }); @Test void shouldHaveCpuLoadEvents() { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrThreadCountTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrThreadCountTest.java similarity index 77% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrThreadCountTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrThreadCountTest.java index 52831b9a798f..d15fe6d1a749 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrThreadCountTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/JfrThreadCountTest.java @@ -3,13 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_DAEMON; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.UNIT_THREADS; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_DAEMON; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.UNIT_THREADS; import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import io.opentelemetry.sdk.metrics.data.LongPointData; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -19,7 +20,10 @@ class JfrThreadCountTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.THREAD_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.THREAD_METRICS); + }); @Test void shouldHaveJfrThreadCountEvents() throws Exception { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryCommittedMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryCommittedMetricTest.java similarity index 54% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryCommittedMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryCommittedMetricTest.java index 768fca11771a..d744cb26a973 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryCommittedMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryCommittedMetricTest.java @@ -3,15 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_COMPRESSED_CLASS_SPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_METASPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.BYTES; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_COMMITTED; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_COMMITTED; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_COMPRESSED_CLASS_SPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_METASPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.BYTES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_COMMITTED; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_COMMITTED; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -20,7 +21,10 @@ class MetaspaceMemoryCommittedMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.MEMORY_POOL_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.MEMORY_POOL_METRICS); + }); @Test void shouldHaveMemoryCommittedMetrics() { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryLimitMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryLimitMetricTest.java similarity index 55% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryLimitMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryLimitMetricTest.java index 4ef4f41f6b3d..928c9ca6fa64 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryLimitMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryLimitMetricTest.java @@ -3,14 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_COMPRESSED_CLASS_SPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.BYTES; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY_LIMIT; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY_LIMIT; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_COMPRESSED_CLASS_SPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.BYTES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY_LIMIT; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY_LIMIT; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -19,7 +20,10 @@ class MetaspaceMemoryLimitMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.MEMORY_POOL_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.MEMORY_POOL_METRICS); + }); @Test void shouldHaveMemoryLimitMetrics() { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryUsageMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryUsageMetricTest.java similarity index 56% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryUsageMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryUsageMetricTest.java index 004115d11c33..6f638d6b45e6 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/MetaspaceMemoryUsageMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/MetaspaceMemoryUsageMetricTest.java @@ -3,15 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_COMPRESSED_CLASS_SPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_METASPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.BYTES; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_COMPRESSED_CLASS_SPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_METASPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.BYTES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -20,7 +21,10 @@ class MetaspaceMemoryUsageMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.MEMORY_POOL_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.MEMORY_POOL_METRICS); + }); /** This is a basic test for jvm.memory.used. */ @Test diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/PsGcMemoryMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/PsGcMemoryMetricTest.java similarity index 55% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/PsGcMemoryMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/PsGcMemoryMetricTest.java index eaba1c4ff9c4..1d1b70a574da 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/PsGcMemoryMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/PsGcMemoryMetricTest.java @@ -3,30 +3,31 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_GC_ACTION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_GC_NAME; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_PS_EDEN_SPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_PS_OLD_GEN; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_PS_SURVIVOR_SPACE; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.BYTES; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.END_OF_MAJOR_GC; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.END_OF_MINOR_GC; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_COMMITTED; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_GC_DURATION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY_AFTER; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_MEMORY_LIMIT; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_COMMITTED; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_GC_DURATION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY_AFTER; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_MEMORY_LIMIT; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.SECONDS; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_GC_ACTION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_GC_NAME; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_PS_EDEN_SPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_PS_OLD_GEN; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_PS_SURVIVOR_SPACE; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.BYTES; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.END_OF_MAJOR_GC; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.END_OF_MINOR_GC; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_COMMITTED; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_GC_DURATION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY_AFTER; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_MEMORY_LIMIT; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_COMMITTED; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_GC_DURATION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY_AFTER; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_MEMORY_LIMIT; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.SECONDS; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import io.opentelemetry.sdk.metrics.data.MetricData; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -36,11 +37,11 @@ class PsGcMemoryMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> - builder - .disableAllFeatures() - .enableFeature(JfrFeature.GC_DURATION_METRICS) - .enableFeature(JfrFeature.MEMORY_POOL_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.GC_DURATION_METRICS); + jfrConfig.enableFeature(JfrFeature.MEMORY_POOL_METRICS); + }); @Test void shouldHaveMemoryMetrics() { diff --git a/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryBuilderTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryBuilderTest.java new file mode 100644 index 000000000000..be16d5f58765 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryBuilderTest.java @@ -0,0 +1,98 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrConfig; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import java.util.Arrays; +import java.util.HashMap; +import jdk.jfr.FlightRecorder; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class RuntimeTelemetryBuilderTest { + + @BeforeAll + static void setup() { + try { + Class.forName("jdk.jfr.FlightRecorder"); + } catch (ClassNotFoundException exception) { + Assumptions.abort("JFR not present"); + } + Assumptions.assumeTrue(FlightRecorder.isAvailable(), "JFR not available"); + } + + @Test + void defaultFeatures() { + // By default, features that don't overlap with JMX AND are not experimental are enabled + var defaultFeatures = new HashMap(); + Arrays.stream(JfrFeature.values()) + .forEach( + jfrFeature -> + defaultFeatures.put( + jfrFeature, !jfrFeature.overlapsWithJmx() && !jfrFeature.isExperimental())); + + assertThat(newBuilder().getJfrConfig().enabledFeatureMap).isEqualTo(defaultFeatures); + } + + @Test + void enableAllFeatures() { + assertThat(newBuilder().getJfrConfig().enableAllFeatures().enabledFeatureMap) + .allSatisfy((unused, enabled) -> assertThat(enabled).isTrue()); + } + + @Test + void disableAllFeatures() { + assertThat(newBuilder().getJfrConfig().disableAllFeatures().enabledFeatureMap) + .allSatisfy((unused, enabled) -> assertThat(enabled).isFalse()); + } + + @Test + void enableDisableFeature() { + var builder = RuntimeTelemetry.builder(OpenTelemetry.noop()); + + // BUFFER_METRICS overlaps with JMX and is experimental, so it's disabled by default + assertThat(builder.getJfrConfig().enabledFeatureMap.get(JfrFeature.BUFFER_METRICS)).isFalse(); + + builder.getJfrConfig().enableFeature(JfrFeature.BUFFER_METRICS); + assertThat(builder.getJfrConfig().enabledFeatureMap.get(JfrFeature.BUFFER_METRICS)).isTrue(); + builder.getJfrConfig().disableFeature(JfrFeature.BUFFER_METRICS); + assertThat(builder.getJfrConfig().enabledFeatureMap.get(JfrFeature.BUFFER_METRICS)).isFalse(); + } + + @Test + void build_DefaultNoJfr() { + // By default, no JFR features are enabled because all features either overlap + // with JMX or are experimental + var openTelemetry = OpenTelemetry.noop(); + try (var runtimeTelemetry = RuntimeTelemetry.builder(openTelemetry).build()) { + assertThat(runtimeTelemetry.getJfrTelemetry()).isNull(); + } + } + + @Test + void build_WithFeatureEnabled() { + var openTelemetry = OpenTelemetry.noop(); + var builder = RuntimeTelemetry.builder(openTelemetry); + builder.getJfrConfig().enableFeature(JfrFeature.LOCK_METRICS); + try (var runtimeTelemetry = builder.build()) { + var jfrRuntimeMetrics = (JfrConfig.JfrRuntimeMetrics) runtimeTelemetry.getJfrTelemetry(); + assertThat(jfrRuntimeMetrics).isNotNull(); + assertThat(jfrRuntimeMetrics.getRecordedEventHandlers()) + .hasSizeGreaterThan(0) + .allSatisfy( + handler -> assertThat(handler.getFeature()).isEqualTo(JfrFeature.LOCK_METRICS)); + } + } + + private static RuntimeTelemetryBuilder newBuilder() { + return RuntimeTelemetry.builder(OpenTelemetry.noop()); + } +} diff --git a/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryTest.java new file mode 100644 index 000000000000..142e23bcf175 --- /dev/null +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/RuntimeTelemetryTest.java @@ -0,0 +1,123 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.runtimetelemetry; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrConfig; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import java.util.concurrent.atomic.AtomicBoolean; +import jdk.jfr.FlightRecorder; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +class RuntimeTelemetryTest { + + @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(RuntimeTelemetry.class); + + private InMemoryMetricReader reader; + private OpenTelemetrySdk sdk; + + @BeforeEach + void setup() { + try { + Class.forName("jdk.jfr.FlightRecorder"); + } catch (ClassNotFoundException exception) { + Assumptions.abort("JFR not present"); + } + Assumptions.assumeTrue(FlightRecorder.isAvailable(), "JFR not available"); + + reader = InMemoryMetricReader.createDelta(); + sdk = + OpenTelemetrySdk.builder() + .setMeterProvider(SdkMeterProvider.builder().registerMetricReader(reader).build()) + .build(); + } + + @AfterEach + void tearDown() { + if (sdk != null) { + sdk.getSdkMeterProvider().close(); + } + } + + @Test + void create_Default() { + try (RuntimeTelemetry unused = RuntimeTelemetry.create(sdk)) { + assertThat(reader.collectAllMetrics()) + .isNotEmpty() + .allSatisfy( + metric -> { + assertThat(metric.getInstrumentationScopeInfo().getName()) + .isEqualTo("io.opentelemetry.runtime-telemetry"); + }); + } + } + + @Test + void builder_DefaultNoJfr() { + // By default, no JFR features are enabled because all features either overlap + // with JMX or are experimental + try (var runtimeTelemetry = RuntimeTelemetry.builder(sdk).build()) { + assertThat(runtimeTelemetry.getJfrTelemetry()).isNull(); + } + } + + @Test + void builder_WithFeatureEnabled() { + RuntimeTelemetryBuilder builder = RuntimeTelemetry.builder(sdk); + builder.getJfrConfig().enableFeature(JfrFeature.LOCK_METRICS); + try (var runtimeTelemetry = builder.build()) { + JfrConfig.JfrRuntimeMetrics jfrRuntimeMetrics = + (JfrConfig.JfrRuntimeMetrics) runtimeTelemetry.getJfrTelemetry(); + assertThat(jfrRuntimeMetrics).isNotNull(); + assertThat(jfrRuntimeMetrics.getRecordedEventHandlers()) + .hasSizeGreaterThan(0) + .allSatisfy( + handler -> { + assertThat(handler.getFeature()).isEqualTo(JfrFeature.LOCK_METRICS); + }); + } + } + + @Test + void close() throws InterruptedException { + RuntimeTelemetryBuilder builder = RuntimeTelemetry.builder(sdk); + // Enable a feature to test close behavior with JFR + builder.getJfrConfig().enableFeature(JfrFeature.LOCK_METRICS); + try (RuntimeTelemetry jfrTelemetry = builder.build()) { + JfrConfig.JfrRuntimeMetrics jfrRuntimeMetrics = + (JfrConfig.JfrRuntimeMetrics) jfrTelemetry.getJfrTelemetry(); + + // Track whether RecordingStream has been closed + AtomicBoolean recordingStreamClosed = new AtomicBoolean(false); + jfrRuntimeMetrics.getRecordingStream().onClose(() -> recordingStreamClosed.set(true)); + + assertThat(reader.collectAllMetrics()).isNotEmpty(); + + jfrTelemetry.close(); + logs.assertDoesNotContain("RuntimeTelemetry is already closed"); + assertThat(recordingStreamClosed.get()).isTrue(); + + // clear all metrics that might have arrived after close + Thread.sleep(100); // give time for any inflight metric export to be received + reader.collectAllMetrics(); + + Thread.sleep(100); + assertThat(reader.collectAllMetrics()).isEmpty(); + + jfrTelemetry.close(); + logs.assertContains("RuntimeTelemetry is already closed"); + } + } +} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/SerialGcMemoryMetricTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/SerialGcMemoryMetricTest.java similarity index 61% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/SerialGcMemoryMetricTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/SerialGcMemoryMetricTest.java index b8e51bc1b99c..9536d41025cc 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/SerialGcMemoryMetricTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/SerialGcMemoryMetricTest.java @@ -3,18 +3,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17; +package io.opentelemetry.instrumentation.runtimetelemetry; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_GC_ACTION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.ATTR_GC_NAME; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.END_OF_MAJOR_GC; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.END_OF_MINOR_GC; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_DESCRIPTION_GC_DURATION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.METRIC_NAME_GC_DURATION; -import static io.opentelemetry.instrumentation.runtimemetrics.java17.internal.Constants.SECONDS; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_GC_ACTION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.ATTR_GC_NAME; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.END_OF_MAJOR_GC; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.END_OF_MINOR_GC; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_DESCRIPTION_GC_DURATION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.METRIC_NAME_GC_DURATION; +import static io.opentelemetry.instrumentation.runtimetelemetry.internal.Constants.SECONDS; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -23,7 +24,10 @@ class SerialGcMemoryMetricTest { @RegisterExtension JfrExtension jfrExtension = new JfrExtension( - builder -> builder.disableAllFeatures().enableFeature(JfrFeature.GC_DURATION_METRICS)); + jfrConfig -> { + jfrConfig.disableAllFeatures(); + jfrConfig.enableFeature(JfrFeature.GC_DURATION_METRICS); + }); @Test void shouldHaveMemoryMetrics() { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/DurationUtilTest.java b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/DurationUtilTest.java similarity index 85% rename from instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/DurationUtilTest.java rename to instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/DurationUtilTest.java index 401894c5b2f7..891730090f55 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/DurationUtilTest.java +++ b/instrumentation/runtime-telemetry/library/src/testJava17/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/DurationUtilTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal; +package io.opentelemetry.instrumentation.runtimetelemetry.internal; import static org.assertj.core.api.Assertions.assertThat; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/build.gradle.kts b/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/build.gradle.kts index 5b9763cf1e8e..934ea07f8684 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/build.gradle.kts +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/build.gradle.kts @@ -2,13 +2,15 @@ plugins { id("otel.javaagent-instrumentation") } +// This module's main code has been consolidated into :instrumentation:runtime-telemetry:javaagent +// Tests are kept to verify backward compatibility + otelJava { minJavaVersionSupported.set(JavaVersion.VERSION_17) } dependencies { - implementation(project(":instrumentation:runtime-telemetry:runtime-telemetry-java17:library")) - compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + testInstrumentation(project(":instrumentation:runtime-telemetry:javaagent")) } tasks { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/README.md b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/README.md index 382475411c6c..3f6e112d80bd 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/README.md +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/README.md @@ -1,5 +1,9 @@ # Runtime Telemetry Java 17 +> **Deprecated:** This module is deprecated. Use +> [`opentelemetry-runtime-telemetry`](../library/README.md) instead, which provides a unified API +> for all Java versions including JFR support on Java 17+. + The main entry point is the `RuntimeMetrics` class in the package `io.opentelemetry.instrumentation.runtimemetrics.java17`: ```java diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/build.gradle.kts b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/build.gradle.kts index a261bb7e75d8..0ad3b31295b3 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/build.gradle.kts +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/build.gradle.kts @@ -7,61 +7,11 @@ otelJava { } dependencies { - implementation(project(":instrumentation:runtime-telemetry:runtime-telemetry-java8:library")) + implementation(project(":instrumentation:runtime-telemetry:library")) testImplementation("io.github.netmikey.logunit:logunit-jul:1.1.3") } -tasks.register("generateDocs", JavaExec::class) { - group = "build" - description = "Generate table for README.md" - classpath = sourceSets.test.get().runtimeClasspath - mainClass.set("io.opentelemetry.instrumentation.runtimemetrics.java17.GenerateDocs") - systemProperties.set("jfr.readme.path", project.projectDir.toString() + "/README.md") -} - tasks { - val testG1 by registering(Test::class) { - testClassesDirs = sourceSets.test.get().output.classesDirs - classpath = sourceSets.test.get().runtimeClasspath - filter { - includeTestsMatching("*G1GcMemoryMetricTest*") - } - include("**/*G1GcMemoryMetricTest.*") - jvmArgs("-XX:+UseG1GC") - } - - val testPS by registering(Test::class) { - testClassesDirs = sourceSets.test.get().output.classesDirs - classpath = sourceSets.test.get().runtimeClasspath - filter { - includeTestsMatching("*PsGcMemoryMetricTest*") - } - include("**/*PsGcMemoryMetricTest.*") - jvmArgs("-XX:+UseParallelGC") - } - - val testSerial by registering(Test::class) { - testClassesDirs = sourceSets.test.get().output.classesDirs - classpath = sourceSets.test.get().runtimeClasspath - filter { - includeTestsMatching("*SerialGcMemoryMetricTest*") - } - include("**/*SerialGcMemoryMetricTest.*") - jvmArgs("-XX:+UseSerialGC") - } - - test { - filter { - excludeTestsMatching("*G1GcMemoryMetricTest") - excludeTestsMatching("*SerialGcMemoryMetricTest") - excludeTestsMatching("*PsGcMemoryMetricTest") - } - } - - check { - dependsOn(testG1, testPS, testSerial) - } - compileJava { // We compile this module for java 8 because it is used as a dependency in spring-boot-autoconfigure. // If this module is compiled for java 17 then gradle can figure out based on the metadata that diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/HandlerRegistry.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/HandlerRegistry.java deleted file mode 100644 index 6de364065082..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/HandlerRegistry.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.runtimemetrics.java17; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.MeterBuilder; -import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.buffer.DirectBufferStatisticsHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.classes.ClassesLoadedHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.container.ContainerConfigurationHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.cpu.ContextSwitchRateHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.cpu.LongLockHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.cpu.OverallCpuLoadHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.garbagecollection.G1GarbageCollectionHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.garbagecollection.OldGarbageCollectionHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.garbagecollection.YoungGarbageCollectionHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory.CodeCacheConfigurationHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory.G1HeapSummaryHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory.MetaspaceSummaryHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory.ObjectAllocationInNewTlabHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory.ObjectAllocationOutsideTlabHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.memory.ParallelHeapSummaryHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.network.NetworkReadHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.network.NetworkWriteHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.threads.ThreadCountHandler; -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.ManagementFactory; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.function.Predicate; -import javax.annotation.Nullable; - -final class HandlerRegistry { - private static final String SCOPE_NAME = "io.opentelemetry.runtime-telemetry-java17"; - - @Nullable - private static final String SCOPE_VERSION = - EmbeddedInstrumentationProperties.findVersion(SCOPE_NAME); - - private HandlerRegistry() {} - - static List getHandlers( - OpenTelemetry openTelemetry, Predicate featurePredicate) { - - MeterBuilder meterBuilder = openTelemetry.meterBuilder(SCOPE_NAME); - if (SCOPE_VERSION != null) { - meterBuilder.setInstrumentationVersion(SCOPE_VERSION); - } - Meter meter = meterBuilder.build(); - - List handlers = new ArrayList(); - for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) { - String name = bean.getName(); - switch (name) { - case "G1 Young Generation": - handlers.add(new G1HeapSummaryHandler(meter)); - handlers.add(new G1GarbageCollectionHandler(meter)); - break; - - case "Copy": - handlers.add(new YoungGarbageCollectionHandler(meter, name)); - break; - - case "PS Scavenge": - handlers.add(new YoungGarbageCollectionHandler(meter, name)); - handlers.add(new ParallelHeapSummaryHandler(meter)); - break; - - case "G1 Old Generation": - case "PS MarkSweep": - case "MarkSweepCompact": - handlers.add(new OldGarbageCollectionHandler(meter, name)); - break; - - default: - // If none of the above GCs are detected, no action. - } - } - - List basicHandlers = - List.of( - new ObjectAllocationInNewTlabHandler(meter), - new ObjectAllocationOutsideTlabHandler(meter), - new NetworkReadHandler(meter), - new NetworkWriteHandler(meter), - new ContextSwitchRateHandler(meter), - new OverallCpuLoadHandler(meter), - new ContainerConfigurationHandler(meter), - new LongLockHandler(meter), - new ThreadCountHandler(meter), - new ClassesLoadedHandler(meter), - new MetaspaceSummaryHandler(meter), - new CodeCacheConfigurationHandler(meter), - new DirectBufferStatisticsHandler(meter)); - handlers.addAll(basicHandlers); - - // Filter and close disabled handlers - Iterator iter = handlers.iterator(); - while (iter.hasNext()) { - RecordedEventHandler handler = iter.next(); - if (!featurePredicate.test(handler.getFeature())) { - handler.close(); - iter.remove(); - } - } - - return handlers; - } -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrFeature.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrFeature.java index aacaaf8fa654..f91bc60a93e9 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrFeature.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/JfrFeature.java @@ -5,13 +5,23 @@ package io.opentelemetry.instrumentation.runtimemetrics.java17; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; + /** * Enumeration of JFR features, which can be toggled on or off via {@link RuntimeMetricsBuilder}. * *

Features are disabled by default if they are already available through {@code * io.opentelemetry.instrumentation:opentelemetry-runtime-telemetry-java8} JMX based * instrumentation. + * + * @deprecated Use {@link RuntimeTelemetry#builder(io.opentelemetry.api.OpenTelemetry)} in the + * {@code runtime-telemetry} module instead. To enable experimental features, use {@link + * io.opentelemetry.instrumentation.runtimetelemetry.internal.Experimental#setEmitExperimentalMetrics(io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetryBuilder, + * boolean)}. To enable JFR collection for metrics that overlap with JMX, use {@link + * io.opentelemetry.instrumentation.runtimetelemetry.internal.Experimental#setPreferJfrMetrics(io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetryBuilder, + * boolean)}. To disable specific metrics, configure metric views. */ +@Deprecated public enum JfrFeature { BUFFER_METRICS(/* defaultEnabled= */ false), CLASS_LOAD_METRICS(/* defaultEnabled= */ false), diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetrics.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetrics.java index 413cd8ddd6bb..56c3a56e72f6 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetrics.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetrics.java @@ -5,40 +5,23 @@ package io.opentelemetry.instrumentation.runtimemetrics.java17; -import static java.util.logging.Level.WARNING; - import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RecordedEventHandler; -import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil; -import java.io.Closeable; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Predicate; -import java.util.logging.Logger; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; +import java.lang.reflect.Method; import javax.annotation.Nullable; -import jdk.jfr.EventSettings; -import jdk.jfr.FlightRecorder; -import jdk.jfr.consumer.RecordingStream; -/** The entry point class for runtime metrics support using JFR and JMX. */ +/** + * The entry point class for runtime metrics support using JFR and JMX. + * + * @deprecated Use {@link RuntimeTelemetry} in the {@code runtime-telemetry} module instead. + */ +@Deprecated public final class RuntimeMetrics implements AutoCloseable { - private static final Logger logger = Logger.getLogger(RuntimeMetrics.class.getName()); - - private final AtomicBoolean isClosed = new AtomicBoolean(); - private final OpenTelemetry openTelemetry; - private final List observables; - - @Nullable private final JfrRuntimeMetrics jfrRuntimeMetrics; + private final RuntimeTelemetry delegate; - RuntimeMetrics( - OpenTelemetry openTelemetry, - List observables, - @Nullable JfrRuntimeMetrics jfrRuntimeMetrics) { - this.openTelemetry = openTelemetry; - this.observables = List.copyOf(observables); - this.jfrRuntimeMetrics = jfrRuntimeMetrics; + RuntimeMetrics(RuntimeTelemetry delegate) { + this.delegate = delegate; } /** @@ -62,106 +45,21 @@ public static RuntimeMetricsBuilder builder(OpenTelemetry openTelemetry) { return new RuntimeMetricsBuilder(openTelemetry); } - // Visible for testing - OpenTelemetry getOpenTelemetry() { - return openTelemetry; - } - - // Visible for testing - JfrRuntimeMetrics getJfrRuntimeMetrics() { - return jfrRuntimeMetrics; + // Only used by tests + @Nullable + Object getJfrRuntimeMetrics() { + try { + Method method = RuntimeTelemetry.class.getDeclaredMethod("getJfrTelemetry"); + method.setAccessible(true); + return method.invoke(delegate); + } catch (Exception e) { + throw new IllegalStateException("Failed to access JFR telemetry via reflection", e); + } } /** Stop recording JFR events. */ @Override public void close() { - if (!isClosed.compareAndSet(false, true)) { - logger.log(WARNING, "RuntimeMetrics is already closed"); - return; - } - if (jfrRuntimeMetrics != null) { - jfrRuntimeMetrics.close(); - } - - JmxRuntimeMetricsUtil.closeObservers(observables); - } - - static class JfrRuntimeMetrics implements Closeable { - private final List recordedEventHandlers; - private final RecordingStream recordingStream; - private final CountDownLatch startUpLatch = new CountDownLatch(1); - private volatile boolean closed = false; - - private JfrRuntimeMetrics(OpenTelemetry openTelemetry, Predicate featurePredicate) { - this.recordedEventHandlers = HandlerRegistry.getHandlers(openTelemetry, featurePredicate); - recordingStream = new RecordingStream(); - recordedEventHandlers.forEach( - handler -> { - EventSettings eventSettings = recordingStream.enable(handler.getEventName()); - handler.getPollingDuration().ifPresent(eventSettings::withPeriod); - handler.getThreshold().ifPresent(eventSettings::withThreshold); - recordingStream.onEvent(handler.getEventName(), handler); - }); - recordingStream.onMetadata(event -> startUpLatch.countDown()); - Thread daemonRunner = - new Thread(this::startRecordingStream, "OpenTelemetry JFR-Metrics-Runner"); - daemonRunner.setDaemon(true); - daemonRunner.setContextClassLoader(null); - daemonRunner.start(); - } - - private void startRecordingStream() { - if (closed) { - return; - } - - try { - recordingStream.start(); - } catch (IllegalStateException exception) { - // Can happen when close is called at the same time as start - if (!closed) { - throw exception; - } - } - } - - static JfrRuntimeMetrics build( - OpenTelemetry openTelemetry, Predicate featurePredicate) { - if (!isJfrAvailable()) { - return null; - } - return new JfrRuntimeMetrics(openTelemetry, featurePredicate); - } - - @Override - public void close() { - closed = true; - recordingStream.close(); - recordedEventHandlers.forEach(RecordedEventHandler::close); - } - - // Visible for testing - List getRecordedEventHandlers() { - return recordedEventHandlers; - } - - // Visible for testing - RecordingStream getRecordingStream() { - return recordingStream; - } - - // Visible for testing - CountDownLatch getStartUpLatch() { - return startUpLatch; - } - - private static boolean isJfrAvailable() { - try { - return FlightRecorder.isAvailable(); - } catch (Throwable e) { - // NoClassDefFoundError, UnsatisfiedLinkError (native images), or other issues - return false; - } - } + delegate.close(); } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilder.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilder.java index 5fab59c1fbe0..1bd31f3de318 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilder.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilder.java @@ -7,53 +7,111 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsFactory; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetryBuilder; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Experimental; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Internal; +import java.lang.reflect.Method; import java.util.Arrays; -import java.util.EnumMap; -import java.util.List; -import javax.annotation.Nullable; -/** Builder for {@link RuntimeMetrics}. */ +/** + * Builder for {@link RuntimeMetrics}. + * + * @deprecated Use {@link RuntimeTelemetryBuilder} in the {@code runtime-telemetry} module instead. + */ +@Deprecated public final class RuntimeMetricsBuilder { - private final OpenTelemetry openTelemetry; - // Visible for testing - final EnumMap enabledFeatureMap; - - private boolean disableJmx = false; - private boolean emitExperimentalTelemetry = false; - private boolean captureGcCause = false; + private final RuntimeTelemetryBuilder delegate; RuntimeMetricsBuilder(OpenTelemetry openTelemetry) { - this.openTelemetry = openTelemetry; - enabledFeatureMap = new EnumMap<>(JfrFeature.class); + this.delegate = RuntimeTelemetry.builder(openTelemetry); + // Set instrumentation name for backward compatibility + // JMX metrics use java8 scope (matching old behavior where java8 module handled JMX) + Internal.setJmxInstrumentationName(delegate, "io.opentelemetry.runtime-telemetry-java8"); + Internal.setJfrInstrumentationName(delegate, "io.opentelemetry.runtime-telemetry-java17"); + // Use legacy metric for backward compatibility (jvm.cpu.limit instead of jvm.cpu.count) + Internal.setUseLegacyJfrCpuCountMetric(delegate, true); + // Explicitly set to preserve backward compatibility if unified default changes + Internal.setCaptureGcCause(delegate, false); + + // Disable all JFR features first, then selectively enable based on java17 defaults. + // This ensures backward compatibility even if the unified module adds new default-enabled + // features in the future. + Internal.setDisableAllJfrFeatures(delegate, true); + + // Enable features with java17 defaults for (JfrFeature feature : JfrFeature.values()) { - enabledFeatureMap.put(feature, feature.isDefaultEnabled()); + if (feature.isDefaultEnabled()) { + Internal.setEnableJfrFeature(delegate, feature.name()); + } + } + } + + // Only used by tests + Object getJfrConfig() { + try { + Method method = RuntimeTelemetryBuilder.class.getDeclaredMethod("getJfrConfig"); + method.setAccessible(true); + return method.invoke(delegate); + } catch (Exception e) { + throw new IllegalStateException("Failed to access JfrConfig via reflection", e); } } - /** Enable telemetry collection for all {@link JfrFeature}s. */ + /** + * Enable telemetry collection for all {@link JfrFeature}s. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. To enable experimental features, use {@link + * Experimental#setEmitExperimentalMetrics(RuntimeTelemetryBuilder, boolean)}. To enable JFR + * collection for metrics that overlap with JMX, use {@link + * Experimental#setPreferJfrMetrics(RuntimeTelemetryBuilder, boolean)}. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder enableAllFeatures() { Arrays.stream(JfrFeature.values()).forEach(this::enableFeature); return this; } - /** Enable telemetry collection associated with the {@link JfrFeature}. */ + /** + * Enable telemetry collection associated with the {@link JfrFeature}. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. To enable experimental features, use {@link + * Experimental#setEmitExperimentalMetrics(RuntimeTelemetryBuilder, boolean)}. To enable JFR + * collection for metrics that overlap with JMX, use {@link + * Experimental#setPreferJfrMetrics(RuntimeTelemetryBuilder, boolean)}. To disable specific + * metrics, configure metric views. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder enableFeature(JfrFeature feature) { - enabledFeatureMap.put(feature, true); + Internal.setEnableJfrFeature(delegate, feature.name()); return this; } - /** Disable telemetry collection for all {@link JfrFeature}s. */ + /** + * Disable telemetry collection for all {@link JfrFeature}s. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. To disable specific metrics, configure metric views. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder disableAllFeatures() { Arrays.stream(JfrFeature.values()).forEach(this::disableFeature); return this; } - /** Disable telemetry collection for all metrics. */ + /** + * Disable telemetry collection for all metrics. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. To disable specific metrics, configure metric views. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder disableAllMetrics() { disableAllFeatures(); @@ -61,50 +119,67 @@ public RuntimeMetricsBuilder disableAllMetrics() { return this; } - /** Disable telemetry collection associated with the {@link JfrFeature}. */ + /** + * Disable telemetry collection associated with the {@link JfrFeature}. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. To disable specific metrics, configure metric views. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder disableFeature(JfrFeature feature) { - enabledFeatureMap.put(feature, false); + Internal.setDisableJfrFeature(delegate, feature.name()); return this; } - /** Disable all JMX telemetry collection. */ + /** + * Disable all JMX telemetry collection. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. To disable specific metrics, configure metric views. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder disableAllJmx() { - disableJmx = true; + Internal.setDisableJmx(delegate, true); return this; } - /** Enable experimental JMX telemetry collection. */ + /** + * Enable experimental JMX telemetry collection. + * + * @deprecated Use {@link Experimental#setEmitExperimentalMetrics(RuntimeTelemetryBuilder, + * boolean)} instead. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder emitExperimentalTelemetry() { - emitExperimentalTelemetry = true; + Experimental.setEmitExperimentalMetrics(delegate, true); return this; } - /** Enable the capture of the jvm.gc.cause attribute with the jvm.gc.duration metric. */ + /** + * Enable the capture of the jvm.gc.cause attribute with the jvm.gc.duration metric. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. The unified {@link RuntimeTelemetryBuilder} enables GC + * cause capture by default. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder captureGcCause() { - captureGcCause = true; + Internal.setCaptureGcCause(delegate, true); return this; } - /** Build and start an {@link RuntimeMetrics} with the config from this builder. */ + /** + * Build and start an {@link RuntimeMetrics} with the config from this builder. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. + */ + @Deprecated public RuntimeMetrics build() { - List observables = - disableJmx - ? List.of() - : JmxRuntimeMetricsFactory.buildObservables( - openTelemetry, emitExperimentalTelemetry, captureGcCause); - RuntimeMetrics.JfrRuntimeMetrics jfrRuntimeMetrics = buildJfrMetrics(); - return new RuntimeMetrics(openTelemetry, observables, jfrRuntimeMetrics); - } - - @Nullable - private RuntimeMetrics.JfrRuntimeMetrics buildJfrMetrics() { - if (enabledFeatureMap.values().stream().noneMatch(isEnabled -> isEnabled)) { - return null; - } - return RuntimeMetrics.JfrRuntimeMetrics.build(openTelemetry, enabledFeatureMap::get); + return new RuntimeMetrics(delegate.build()); } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java deleted file mode 100644 index 171561f4f4c6..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.runtimemetrics.java17.internal; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics; -import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetricsBuilder; -import javax.annotation.Nullable; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public final class RuntimeMetricsConfigUtil { - private RuntimeMetricsConfigUtil() {} - - @Nullable - public static RuntimeMetrics configure( - RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) { - /* - 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 - */ - if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry_java17") - .getBoolean("enable_all", false)) { - builder.enableAllFeatures(); - } else if (DeclarativeConfigUtil.getInstrumentationConfig( - openTelemetry, "runtime_telemetry_java17") - .getBoolean("enabled", false)) { - // default configuration - } else if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry") - .getBoolean("enabled", defaultEnabled)) { - // This only uses metrics gathered by JMX - builder.disableAllFeatures(); - } else { - // nothing is enabled - return null; - } - - if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry") - .getBoolean("emit_experimental_telemetry/development", false)) { - builder.emitExperimentalTelemetry(); - } - - if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry") - .getBoolean("capture_gc_cause", false)) { - builder.captureGcCause(); - } - - return builder.build(); - } -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilderTest.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilderTest.java index 78f88af3f4f5..72b8accd3137 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilderTest.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsBuilderTest.java @@ -8,13 +8,16 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrConfig; import java.util.Arrays; +import java.util.EnumMap; import java.util.HashMap; import jdk.jfr.FlightRecorder; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +@SuppressWarnings("deprecation") // Testing deprecated API for backward compatibility class RuntimeMetricsBuilderTest { @BeforeAll @@ -33,21 +36,23 @@ void defaultFeatures() { Arrays.stream(JfrFeature.values()) .forEach(jfrFeature -> defaultFeatures.put(jfrFeature, jfrFeature.isDefaultEnabled())); - assertThat(new RuntimeMetricsBuilder(OpenTelemetry.noop()).enabledFeatureMap) + assertThat(getEnabledFeatureMap(new RuntimeMetricsBuilder(OpenTelemetry.noop()))) .isEqualTo(defaultFeatures); } @Test void enableAllFeatures() { assertThat( - new RuntimeMetricsBuilder(OpenTelemetry.noop()).enableAllFeatures().enabledFeatureMap) + getEnabledFeatureMap( + new RuntimeMetricsBuilder(OpenTelemetry.noop()).enableAllFeatures())) .allSatisfy((unused, enabled) -> assertThat(enabled).isTrue()); } @Test void disableAllFeatures() { assertThat( - new RuntimeMetricsBuilder(OpenTelemetry.noop()).disableAllFeatures().enabledFeatureMap) + getEnabledFeatureMap( + new RuntimeMetricsBuilder(OpenTelemetry.noop()).disableAllFeatures())) .allSatisfy((unused, enabled) -> assertThat(enabled).isFalse()); } @@ -55,22 +60,50 @@ void disableAllFeatures() { void enableDisableFeature() { var builder = new RuntimeMetricsBuilder(OpenTelemetry.noop()); - assertThat(builder.enabledFeatureMap.get(JfrFeature.BUFFER_METRICS)).isFalse(); + assertThat(getEnabledFeatureMap(builder).get(JfrFeature.BUFFER_METRICS)).isFalse(); builder.enableFeature(JfrFeature.BUFFER_METRICS); - assertThat(builder.enabledFeatureMap.get(JfrFeature.BUFFER_METRICS)).isTrue(); + assertThat(getEnabledFeatureMap(builder).get(JfrFeature.BUFFER_METRICS)).isTrue(); builder.disableFeature(JfrFeature.BUFFER_METRICS); - assertThat(builder.enabledFeatureMap.get(JfrFeature.BUFFER_METRICS)).isFalse(); + assertThat(getEnabledFeatureMap(builder).get(JfrFeature.BUFFER_METRICS)).isFalse(); } @Test void build() { var openTelemetry = OpenTelemetry.noop(); try (var jfrTelemetry = new RuntimeMetricsBuilder(openTelemetry).build()) { - assertThat(jfrTelemetry.getOpenTelemetry()).isSameAs(openTelemetry); - assertThat(jfrTelemetry.getJfrRuntimeMetrics().getRecordedEventHandlers()) + assertThat(getJfrRuntimeMetrics(jfrTelemetry).getRecordedEventHandlers()) .hasSizeGreaterThan(0) - .allSatisfy(handler -> assertThat(handler.getFeature().isDefaultEnabled()).isTrue()); + .allSatisfy(handler -> assertThat(isDefaultEnabled(handler.getFeature())).isTrue()); } } + + // Helper to access the unified module's state + private static JfrConfig.JfrRuntimeMetrics getJfrRuntimeMetrics(RuntimeMetrics runtimeMetrics) { + return (JfrConfig.JfrRuntimeMetrics) runtimeMetrics.getJfrRuntimeMetrics(); + } + + // Helper to access the unified module's state + private static EnumMap getEnabledFeatureMap(RuntimeMetricsBuilder builder) { + JfrConfig jfrConfig = (JfrConfig) builder.getJfrConfig(); + EnumMap result = new EnumMap<>(JfrFeature.class); + for (JfrFeature feature : JfrFeature.values()) { + result.put( + feature, + jfrConfig.enabledFeatureMap.get( + io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature.valueOf( + feature.name()))); + } + return result; + } + + // Java17 legacy defaults: all non-overlapping features + // plus CPU_COUNT_METRICS (which is emitted as cpu.count.limit) + private static boolean isDefaultEnabled( + io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature feature) { + return !feature.overlapsWithJmx() + || feature + == io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature + .CPU_COUNT_METRICS; + } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsTest.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsTest.java index 15b178abf814..44d4f6186430 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsTest.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java17/RuntimeMetricsTest.java @@ -8,6 +8,8 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrConfig; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; @@ -19,9 +21,10 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +@SuppressWarnings("deprecation") // Testing deprecated API for backward compatibility class RuntimeMetricsTest { - @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(RuntimeMetrics.class); + @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(RuntimeTelemetry.class); private InMemoryMetricReader reader; private OpenTelemetrySdk sdk; @@ -72,10 +75,9 @@ void create_AllDisabled() { @Test void builder() { try (var jfrTelemetry = RuntimeMetrics.builder(sdk).build()) { - assertThat(jfrTelemetry.getOpenTelemetry()).isSameAs(sdk); - assertThat(jfrTelemetry.getJfrRuntimeMetrics().getRecordedEventHandlers()) + assertThat(getJfrRuntimeMetrics(jfrTelemetry).getRecordedEventHandlers()) .hasSizeGreaterThan(0) - .allSatisfy(handler -> assertThat(handler.getFeature().isDefaultEnabled()).isTrue()); + .allSatisfy(handler -> assertThat(isDefaultEnabled(handler.getFeature())).isTrue()); } } @@ -84,15 +86,14 @@ void close() throws InterruptedException { try (RuntimeMetrics jfrTelemetry = RuntimeMetrics.builder(sdk).build()) { // Track whether RecordingStream has been closed AtomicBoolean recordingStreamClosed = new AtomicBoolean(false); - jfrTelemetry - .getJfrRuntimeMetrics() + getJfrRuntimeMetrics(jfrTelemetry) .getRecordingStream() .onClose(() -> recordingStreamClosed.set(true)); assertThat(reader.collectAllMetrics()).isNotEmpty(); jfrTelemetry.close(); - logs.assertDoesNotContain("RuntimeMetrics is already closed"); + logs.assertDoesNotContain("RuntimeTelemetry is already closed"); assertThat(recordingStreamClosed.get()).isTrue(); // clear all metrics that might have arrived after close @@ -103,7 +104,22 @@ void close() throws InterruptedException { assertThat(reader.collectAllMetrics()).isEmpty(); jfrTelemetry.close(); - logs.assertContains("RuntimeMetrics is already closed"); + logs.assertContains("RuntimeTelemetry is already closed"); } } + + // Helper to access the unified module's state + private static JfrConfig.JfrRuntimeMetrics getJfrRuntimeMetrics(RuntimeMetrics runtimeMetrics) { + return (JfrConfig.JfrRuntimeMetrics) runtimeMetrics.getJfrRuntimeMetrics(); + } + + // Java17 legacy defaults: all non-overlapping features + // plus CPU_COUNT_METRICS (which is emitted as cpu.count.limit) + private static boolean isDefaultEnabled( + io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature feature) { + return !feature.overlapsWithJmx() + || feature + == io.opentelemetry.instrumentation.runtimetelemetry.internal.JfrFeature + .CPU_COUNT_METRICS; + } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/build.gradle.kts b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/build.gradle.kts index aa1653528255..cc30320b30c3 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/build.gradle.kts +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/build.gradle.kts @@ -2,11 +2,11 @@ plugins { id("otel.javaagent-instrumentation") } -dependencies { - implementation(project(":instrumentation:runtime-telemetry:runtime-telemetry-java8:library")) +// This module's main code has been consolidated into :instrumentation:runtime-telemetry:javaagent +// Tests are kept to verify backward compatibility with legacy property names - compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") - compileOnly("io.opentelemetry:opentelemetry-api-incubator") +dependencies { + testInstrumentation(project(":instrumentation:runtime-telemetry:javaagent")) } tasks { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzerInstaller.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzerInstaller.java deleted file mode 100644 index 118d67dee88a..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzerInstaller.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8; - -import com.google.auto.service.AutoService; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; -import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder; -import io.opentelemetry.javaagent.tooling.BeforeAgentListener; -import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import java.lang.instrument.Instrumentation; - -/** Installs the {@link JarAnalyzer}. */ -@AutoService(BeforeAgentListener.class) -public class JarAnalyzerInstaller implements BeforeAgentListener { - - @Override - public void beforeAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { - OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); - DeclarativeConfigProperties config = - DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry"); - if (!config.get("package_emitter").getBoolean("enabled", false)) { - return; - } - Instrumentation inst = InstrumentationHolder.getInstrumentation(); - if (inst == null) { - return; - } - JarAnalyzer jarAnalyzer = - JarAnalyzer.create( - openTelemetry, config.get("package_emitter").getInt("jars_per_second", 10)); - inst.addTransformer(jarAnalyzer); - } -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java deleted file mode 100644 index a2d185be53b7..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8; - -import com.google.auto.service.AutoService; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics; -import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil; -import io.opentelemetry.javaagent.extension.AgentListener; -import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; -import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; - -/** An {@link AgentListener} that enables runtime metrics during agent startup. */ -@AutoService(AgentListener.class) -public class Java8RuntimeMetricsInstaller implements AgentListener { - - @Override - public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { - if (Double.parseDouble(System.getProperty("java.specification.version")) >= 17) { - return; - } - - RuntimeMetrics runtimeMetrics = - RuntimeMetricsConfigUtil.configure( - RuntimeMetrics.builder(GlobalOpenTelemetry.get()), - GlobalOpenTelemetry.get(), - AgentDistributionConfig.get().isInstrumentationDefaultEnabled()); - if (runtimeMetrics != null) { - Runtime.getRuntime() - .addShutdownHook( - new Thread(runtimeMetrics::close, "OpenTelemetry RuntimeMetricsShutdownHook")); - } - } -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/README.md b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/README.md index 7ddde09e1fa6..a36864795d41 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/README.md +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/README.md @@ -1,5 +1,9 @@ # JVM Runtime Metrics +> **Deprecated:** This module is deprecated. Use +> [`opentelemetry-runtime-telemetry`](../library/README.md) instead, which provides a unified API +> for all Java versions. + This module provides JVM runtime metrics as documented in the [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/runtime/jvm-metrics.md). ## Quickstart @@ -83,43 +87,7 @@ meter_provider: ## Garbage Collector Dependent Metrics -The attributes reported on the memory metrics (`jvm.memory.*`) and gc metrics (`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. - -The following lists attributes reported for a variety of garbage collectors. Notice that attributes are not necessarily constant across `*.used`, `*.committed`, and `*.limit` since not all memory pools report a limit. - -- CMS Garbage Collector - - `jvm.memory.used`: {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Code Cache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.committed`: {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Code Cache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.limit`: {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Code Cache,jvm.memory.type=non_heap} - - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=Par Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Par Survivor Space,jvm.memory.type=heap} - - `jvm.gc.duration`: {jvm.gc.action=end of minor GC,jvm.gc.name=ParNew}, {jvm.gc.action=end of major GC,jvm.gc.name=MarkSweepCompact} -- G1 Garbage Collector - - `jvm.memory.used`: {jvm.memory.pool.name=G1 Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.committed`: {jvm.memory.pool.name=G1 Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=G1 Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=G1 Old Gen,jvm.memory.type=heap} - - `jvm.gc.duration`: {jvm.gc.action=end of minor GC,jvm.gc.name=G1 Young Generation}, {jvm.gc.action=end of major GC,jvm.gc.name=G1 Old Generation} -- Parallel Garbage Collector - - `jvm.memory.used`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.committed`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=PS Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Old Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=PS Eden Space,jvm.memory.type=heap} - - `jvm.gc.duration`: {jvm.gc.action=end of major GC,jvm.gc.name=PS MarkSweep}, {jvm.gc.action=end of minor GC,jvm.gc.name=PS Scavenge} -- Serial Garbage Collector - - `jvm.memory.used`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.committed`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap} - - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=Tenured Gen,jvm.memory.type=heap}, {jvm.memory.pool.name=Eden Space,jvm.memory.type=heap}, {jvm.memory.pool.name=Survivor Space,jvm.memory.type=heap} - - `jvm.gc.duration`: {jvm.gc.action=end of minor GC,jvm.gc.name=Copy}, {jvm.gc.action=end of major GC,jvm.gc.name=MarkSweepCompact} -- Shenandoah Garbage Collector - - `jvm.memory.used`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.committed`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=Shenandoah,jvm.memory.type=heap} - - `jvm.gc.duration`: {jvm.gc.action=end of GC cycle,jvm.gc.name=Shenandoah Cycles}, {jvm.gc.action=end of GC pause,jvm.gc.name=Shenandoah Pauses} -- Z Garbage Collector - - `jvm.memory.used`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.committed`: {jvm.memory.pool.name=Metaspace,jvm.memory.type=non_heap}, {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.limit`: {jvm.memory.pool.name=CodeCache,jvm.memory.type=non_heap}, {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap}, {jvm.memory.pool.name=Compressed Class Space,jvm.memory.type=non_heap} - - `jvm.memory.used_after_last_gc`: {jvm.memory.pool.name=ZHeap,jvm.memory.type=heap} - - `jvm.gc.duration`: {jvm.gc.action=end of GC cycle,jvm.gc.name=ZGC Cycles}, {jvm.gc.action=end of GC pause,jvm.gc.name=ZGC Pauses} +The attributes reported on memory metrics (`jvm.memory.*`) and GC metrics (`jvm.gc.*`) depend on +the garbage collector used by the application. See the +[runtime-telemetry library README](../../library/README.md#garbage-collector-dependent-metrics) +for details on attributes for various garbage collectors. diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/build.gradle.kts b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/build.gradle.kts index 24be66977afe..41f190e4376d 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/build.gradle.kts +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/build.gradle.kts @@ -3,5 +3,5 @@ plugins { } dependencies { - implementation(project(":instrumentation-api")) + implementation(project(":instrumentation:runtime-telemetry:library")) } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetrics.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetrics.java index 1542325c24c3..9f918a08f8f4 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetrics.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetrics.java @@ -5,25 +5,21 @@ package io.opentelemetry.instrumentation.runtimemetrics.java8; -import static java.util.logging.Level.WARNING; - import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Logger; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; -/** The entry point class for runtime metrics support using JMX. */ +/** + * The entry point class for runtime metrics support using JMX. + * + * @deprecated Use {@link RuntimeTelemetry} in the {@code runtime-telemetry} module instead. + */ +@Deprecated public final class RuntimeMetrics implements AutoCloseable { - private static final Logger logger = Logger.getLogger(RuntimeMetrics.class.getName()); + private final RuntimeTelemetry delegate; - private final AtomicBoolean isClosed = new AtomicBoolean(); - private final List observables; - - RuntimeMetrics(List observables) { - this.observables = Collections.unmodifiableList(observables); + RuntimeMetrics(RuntimeTelemetry delegate) { + this.delegate = delegate; } /** @@ -33,7 +29,10 @@ public final class RuntimeMetrics implements AutoCloseable { * continue until {@link #close()} is called. * * @param openTelemetry the {@link OpenTelemetry} instance used to record telemetry + * @deprecated Use {@link RuntimeTelemetry#create(OpenTelemetry)} in the {@code runtime-telemetry} + * module instead. */ + @Deprecated public static RuntimeMetrics create(OpenTelemetry openTelemetry) { return new RuntimeMetricsBuilder(openTelemetry).build(); } @@ -42,7 +41,10 @@ public static RuntimeMetrics create(OpenTelemetry openTelemetry) { * Create a builder for configuring {@link RuntimeMetrics}. * * @param openTelemetry the {@link OpenTelemetry} instance used to record telemetry + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. */ + @Deprecated public static RuntimeMetricsBuilder builder(OpenTelemetry openTelemetry) { return new RuntimeMetricsBuilder(openTelemetry); } @@ -50,11 +52,6 @@ public static RuntimeMetricsBuilder builder(OpenTelemetry openTelemetry) { /** Stop recording JMX metrics. */ @Override public void close() { - if (!isClosed.compareAndSet(false, true)) { - logger.log(WARNING, "RuntimeMetrics is already closed"); - return; - } - - JmxRuntimeMetricsUtil.closeObservers(observables); + delegate.close(); } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetricsBuilder.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetricsBuilder.java index 97b617d5713c..8a5bddebab1c 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetricsBuilder.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/RuntimeMetricsBuilder.java @@ -7,40 +7,63 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsFactory; -import java.util.List; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry; +import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetryBuilder; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Experimental; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Internal; -/** Builder for {@link RuntimeMetrics}. */ +/** + * Builder for {@link RuntimeMetrics}. + * + * @deprecated Use {@link RuntimeTelemetryBuilder} in the {@code runtime-telemetry} module instead. + */ +@Deprecated public final class RuntimeMetricsBuilder { - private final OpenTelemetry openTelemetry; + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.runtime-telemetry-java8"; - private boolean emitExperimentalTelemetry = false; - private boolean captureGcCause = false; + private final RuntimeTelemetryBuilder delegate; RuntimeMetricsBuilder(OpenTelemetry openTelemetry) { - this.openTelemetry = openTelemetry; + this.delegate = RuntimeTelemetry.builder(openTelemetry); + // Set instrumentation name for backward compatibility + Internal.setJmxInstrumentationName(delegate, INSTRUMENTATION_NAME); + // Disable all JFR features - java8 module was JMX-only. This also ensures backward + // compatibility if the unified module adds new default-enabled JFR features in the future. + Internal.setDisableAllJfrFeatures(delegate, true); + // Explicitly set to preserve backward compatibility if unified default changes + Internal.setCaptureGcCause(delegate, false); } - /** Enable all JMX telemetry collection. */ + /** + * Enable experimental JMX telemetry collection. When running on Java 17+, this will also enable + * experimental JFR metrics. To drop unwanted JFR metrics, configure metric views. + * + * @deprecated Use {@link Experimental#setEmitExperimentalMetrics(RuntimeTelemetryBuilder, + * boolean)} instead. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder emitExperimentalTelemetry() { - emitExperimentalTelemetry = true; + Experimental.setEmitExperimentalMetrics(delegate, true); return this; } - /** Enable the capture of the jvm.gc.cause attribute with the jvm.gc.duration metric. */ + /** + * Enable the capture of the jvm.gc.cause attribute with the jvm.gc.duration metric. + * + * @deprecated Use {@link RuntimeTelemetry#builder(OpenTelemetry)} in the {@code + * runtime-telemetry} module instead. + */ + @Deprecated @CanIgnoreReturnValue public RuntimeMetricsBuilder captureGcCause() { - captureGcCause = true; + Internal.setCaptureGcCause(delegate, true); return this; } /** Build and start an {@link RuntimeMetrics} with the config from this builder. */ public RuntimeMetrics build() { - List observables = - JmxRuntimeMetricsFactory.buildObservables( - openTelemetry, emitExperimentalTelemetry, captureGcCause); - return new RuntimeMetrics(observables); + return new RuntimeMetrics(delegate.build()); } } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/JmxRuntimeMetricsFactory.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/JmxRuntimeMetricsFactory.java deleted file mode 100644 index 8042bc2ea7c5..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/JmxRuntimeMetricsFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.runtimemetrics.java8.internal; - -import io.opentelemetry.api.OpenTelemetry; -import java.util.ArrayList; -import java.util.List; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public class JmxRuntimeMetricsFactory { - @SuppressWarnings("CatchingUnchecked") - public static List buildObservables( - OpenTelemetry openTelemetry, boolean emitExperimentalTelemetry, boolean captureGcCause) { - // Set up metrics gathered by JMX - List observables = new ArrayList<>(); - observables.addAll(Classes.registerObservers(openTelemetry)); - observables.addAll(Cpu.registerObservers(openTelemetry)); - observables.addAll(GarbageCollector.registerObservers(openTelemetry, captureGcCause)); - observables.addAll(MemoryPools.registerObservers(openTelemetry)); - observables.addAll(Threads.registerObservers(openTelemetry)); - if (emitExperimentalTelemetry) { - observables.addAll(BufferPools.registerObservers(openTelemetry)); - observables.addAll(SystemCpu.registerObservers(openTelemetry)); - observables.addAll(MemoryInit.registerObservers(openTelemetry)); - observables.addAll(FileDescriptor.registerObservers(openTelemetry)); - } - return observables; - } - - private JmxRuntimeMetricsFactory() {} -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/JmxRuntimeMetricsUtil.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/JmxRuntimeMetricsUtil.java deleted file mode 100644 index 334d405ad26f..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/JmxRuntimeMetricsUtil.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 io.opentelemetry.api.metrics.MeterBuilder; -import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; -import java.util.List; -import javax.annotation.Nullable; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public class JmxRuntimeMetricsUtil { - - private static final String INSTRUMENTATION_NAME = "io.opentelemetry.runtime-telemetry-java8"; - - @Nullable - private static final String INSTRUMENTATION_VERSION = - EmbeddedInstrumentationProperties.findVersion(INSTRUMENTATION_NAME); - - public static Meter getMeter(OpenTelemetry openTelemetry) { - MeterBuilder meterBuilder = openTelemetry.meterBuilder(INSTRUMENTATION_NAME); - if (INSTRUMENTATION_VERSION != null) { - meterBuilder.setInstrumentationVersion(INSTRUMENTATION_VERSION); - } - return meterBuilder.build(); - } - - public static String getInstrumentationName() { - return INSTRUMENTATION_NAME; - } - - @Nullable - public static String getInstrumentationVersion() { - return INSTRUMENTATION_VERSION; - } - - public static void closeObservers(List observables) { - observables.forEach( - observable -> { - try { - observable.close(); - } catch (Exception e) { - // Ignore - } - }); - } - - private JmxRuntimeMetricsUtil() {} -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java deleted file mode 100644 index a62bcfab9eb1..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.incubator.config.DeclarativeConfigProperties; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; -import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics; -import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetricsBuilder; -import javax.annotation.Nullable; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public final class RuntimeMetricsConfigUtil { - private RuntimeMetricsConfigUtil() {} - - @Nullable - public static RuntimeMetrics configure( - RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) { - DeclarativeConfigProperties config = - DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry"); - if (!config.getBoolean("enabled", defaultEnabled)) { - // nothing is enabled - return null; - } - - if (config.getBoolean("emit_experimental_telemetry/development", false)) { - builder.emitExperimentalTelemetry(); - } - - if (config.getBoolean("capture_gc_cause", false)) { - builder.captureGcCause(); - } - - return builder.build(); - } -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/ScopeUtil.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/ScopeUtil.java deleted file mode 100644 index 3769d2a4ce11..000000000000 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/test/java/io/opentelemetry/instrumentation/runtimemetrics/java8/ScopeUtil.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.runtimemetrics.java8; - -import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.common.InstrumentationScopeInfoBuilder; -import javax.annotation.Nullable; - -public final class ScopeUtil { - - private static final String INSTRUMENTATION_NAME = "io.opentelemetry.runtime-telemetry-java8"; - - @Nullable - private static final String INSTRUMENTATION_VERSION = - EmbeddedInstrumentationProperties.findVersion(INSTRUMENTATION_NAME); - - public static final InstrumentationScopeInfo EXPECTED_SCOPE; - - static { - InstrumentationScopeInfoBuilder builder = - InstrumentationScopeInfo.builder(INSTRUMENTATION_NAME); - if (INSTRUMENTATION_VERSION != null) { - builder.setVersion(INSTRUMENTATION_VERSION); - } - EXPECTED_SCOPE = builder.build(); - } - - private ScopeUtil() {} -} diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/build.gradle.kts b/instrumentation/runtime-telemetry/testing/build.gradle.kts similarity index 96% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/build.gradle.kts rename to instrumentation/runtime-telemetry/testing/build.gradle.kts index dc808ed744aa..284dbdddf59a 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/build.gradle.kts +++ b/instrumentation/runtime-telemetry/testing/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } dependencies { - testImplementation(project(":instrumentation:runtime-telemetry:runtime-telemetry-java8:javaagent")) + testImplementation(project(":instrumentation:runtime-telemetry:javaagent")) testImplementation("io.opentelemetry:opentelemetry-sdk-testing") diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/src/main/java/io/opentelemetry/instrumentation/testapp/DummyApplication.java b/instrumentation/runtime-telemetry/testing/src/main/java/io/opentelemetry/instrumentation/testapp/DummyApplication.java similarity index 100% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/src/main/java/io/opentelemetry/instrumentation/testapp/DummyApplication.java rename to instrumentation/runtime-telemetry/testing/src/main/java/io/opentelemetry/instrumentation/testapp/DummyApplication.java diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzerTest.java b/instrumentation/runtime-telemetry/testing/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzerTest.java similarity index 90% rename from instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzerTest.java rename to instrumentation/runtime-telemetry/testing/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzerTest.java index 4b19e050e73b..e9ceecf1ff14 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/testing/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/JarAnalyzerTest.java +++ b/instrumentation/runtime-telemetry/testing/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JarAnalyzerTest.java @@ -3,15 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8; +package io.opentelemetry.javaagent.instrumentation.runtimetelemetry; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarAnalyzer.PACKAGE_CHECKSUM; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarAnalyzer.PACKAGE_CHECKSUM_ALGORITHM; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarAnalyzer.PACKAGE_DESCRIPTION; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarAnalyzer.PACKAGE_NAME; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarAnalyzer.PACKAGE_PATH; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarAnalyzer.PACKAGE_TYPE; -import static io.opentelemetry.javaagent.instrumentation.runtimemetrics.java8.JarAnalyzer.PACKAGE_VERSION; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarAnalyzer.PACKAGE_CHECKSUM; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarAnalyzer.PACKAGE_CHECKSUM_ALGORITHM; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarAnalyzer.PACKAGE_DESCRIPTION; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarAnalyzer.PACKAGE_NAME; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarAnalyzer.PACKAGE_PATH; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarAnalyzer.PACKAGE_TYPE; +import static io.opentelemetry.javaagent.instrumentation.runtimetelemetry.JarAnalyzer.PACKAGE_VERSION; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -21,7 +21,8 @@ import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; +import io.opentelemetry.api.logs.LogRecordBuilder; +import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.testing.assertj.AttributesAssert; import java.io.File; @@ -40,11 +41,13 @@ class JarAnalyzerTest { @ParameterizedTest @MethodSource("processUrlArguments") void processUrl_EmitsEvents(URL archiveUrl, Consumer attributesConsumer) { - ExtendedLogRecordBuilder builder = mock(ExtendedLogRecordBuilder.class); + Logger logger = mock(Logger.class); + LogRecordBuilder builder = mock(LogRecordBuilder.class); + when(logger.logRecordBuilder()).thenReturn(builder); when(builder.setEventName(eq("package.info"))).thenReturn(builder); when(builder.setAllAttributes((Attributes) any())).thenReturn(builder); - JarAnalyzer.processUrl(builder, archiveUrl); + JarAnalyzer.processUrl(logger, archiveUrl); ArgumentCaptor attributesArgumentCaptor = ArgumentCaptor.forClass(Attributes.class); verify(builder).setAllAttributes(attributesArgumentCaptor.capture()); @@ -66,7 +69,7 @@ private static Stream processUrlArguments() { path -> assertThat( path.matches( - "opentelemetry-javaagent-runtime-telemetry-java8-[0-9a-zA-Z-\\.]+\\.jar")) + "opentelemetry-javaagent-runtime-telemetry-[0-9a-zA-Z-\\.]+\\.jar")) .isTrue()) .containsEntry(PACKAGE_DESCRIPTION, "javaagent by OpenTelemetry") .containsEntry(PACKAGE_CHECKSUM_ALGORITHM, "SHA1") diff --git a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts index de70f96cd783..d0a5268a68f2 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts +++ b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts @@ -68,8 +68,7 @@ dependencies { implementation(project(":instrumentation:logback:logback-mdc-1.0:library")) compileOnly("ch.qos.logback:logback-classic:1.0.0") implementation(project(":instrumentation:jdbc:library")) - implementation(project(":instrumentation:runtime-telemetry:runtime-telemetry-java8:library")) - implementation(project(":instrumentation:runtime-telemetry:runtime-telemetry-java17:library")) + implementation(project(":instrumentation:runtime-telemetry:library")) library("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion") library("org.springframework.boot:spring-boot-starter-aop:$springBootVersion") diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsAutoConfiguration.java deleted file mode 100644 index 3811afcaa8a4..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsAutoConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics; -import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import javax.annotation.Nullable; -import javax.annotation.PreDestroy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.EventListener; - -/** - * Configures runtime metrics collection for Java 8+. This is a fallback configuration that only - * activates when Java17RuntimeMetricsAutoConfiguration is not present (i.e., on Java versions older - * than 17). - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -@ConditionalOnEnabledInstrumentation(module = "runtime-telemetry") -@ConditionalOnMissingBean(Java17RuntimeMetricsAutoConfiguration.class) -@Configuration -public class Java8RuntimeMetricsAutoConfiguration { - - private static final Logger logger = - LoggerFactory.getLogger(Java8RuntimeMetricsAutoConfiguration.class); - - @Nullable private AutoCloseable closeable; - - @PreDestroy - public void stopMetrics() throws Exception { - if (closeable != null) { - closeable.close(); - } - } - - @EventListener - public void handleApplicationReadyEvent(ApplicationReadyEvent event) { - ConfigurableApplicationContext applicationContext = event.getApplicationContext(); - OpenTelemetry openTelemetry = applicationContext.getBean(OpenTelemetry.class); - - logger.debug("Use runtime metrics instrumentation for Java 8"); - this.closeable = - RuntimeMetricsConfigUtil.configure( - RuntimeMetrics.builder(openTelemetry), openTelemetry, true); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimetelemetry/RuntimeMetricsAutoConfiguration.java similarity index 60% rename from instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsAutoConfiguration.java rename to instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimetelemetry/RuntimeMetricsAutoConfiguration.java index efb8ac7d76a3..80ebc96c6afb 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimetelemetry/RuntimeMetricsAutoConfiguration.java @@ -3,37 +3,32 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics; +package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimetelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics; -import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil; +import io.opentelemetry.instrumentation.runtimetelemetry.internal.Internal; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; import javax.annotation.Nullable; import javax.annotation.PreDestroy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnJava; -import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.Range; import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.boot.system.JavaVersion; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; /** - * Configures runtime metrics collection for Java 17+. + * Configures runtime telemetry collection. * *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ @ConditionalOnEnabledInstrumentation(module = "runtime-telemetry") -@ConditionalOnJava(range = Range.EQUAL_OR_NEWER, value = JavaVersion.SEVENTEEN) @Configuration -public class Java17RuntimeMetricsAutoConfiguration { +public class RuntimeMetricsAutoConfiguration { private static final Logger logger = - LoggerFactory.getLogger(Java17RuntimeMetricsAutoConfiguration.class); + LoggerFactory.getLogger(RuntimeMetricsAutoConfiguration.class); @Nullable private AutoCloseable closeable; @@ -49,9 +44,7 @@ public void handleApplicationReadyEvent(ApplicationReadyEvent event) { ConfigurableApplicationContext applicationContext = event.getApplicationContext(); OpenTelemetry openTelemetry = applicationContext.getBean(OpenTelemetry.class); - logger.debug("Use runtime metrics instrumentation for Java 17+"); - this.closeable = - RuntimeMetricsConfigUtil.configure( - RuntimeMetrics.builder(openTelemetry), openTelemetry, true); + logger.debug("Start runtime telemetry instrumentation"); + this.closeable = Internal.configure(openTelemetry, true); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 277f707acb68..22b5b337c30f 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -14,8 +14,7 @@ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.w io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webflux.SpringWebfluxInstrumentationAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webmvc.SpringWebMvc5InstrumentationAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.scheduling.SpringSchedulingInstrumentationAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java17RuntimeMetricsAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java8RuntimeMetricsAutoConfiguration,\ +io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimetelemetry.RuntimeMetricsAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.thread.ThreadDetailsAutoConfiguration org.springframework.context.ApplicationListener=\ diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 41ebb58077f3..6221095ec48c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -18,6 +18,5 @@ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.w io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web.RestClientInstrumentationSpringBoot4AutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webmvc.SpringWebMvc6InstrumentationAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.scheduling.SpringSchedulingInstrumentationAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java17RuntimeMetricsAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java8RuntimeMetricsAutoConfiguration +io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimetelemetry.RuntimeMetricsAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.thread.ThreadDetailsAutoConfiguration diff --git a/settings.gradle.kts b/settings.gradle.kts index 1d965e3f4a75..d40d4aa69013 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -581,9 +581,11 @@ include(":instrumentation:rocketmq:rocketmq-client-4.8:library") include(":instrumentation:rocketmq:rocketmq-client-4.8:testing") include(":instrumentation:rocketmq:rocketmq-client-5.0:javaagent") include(":instrumentation:rocketmq:rocketmq-client-5.0:testing") +include(":instrumentation:runtime-telemetry:javaagent") +include(":instrumentation:runtime-telemetry:library") +include(":instrumentation:runtime-telemetry:testing") include(":instrumentation:runtime-telemetry:runtime-telemetry-java8:javaagent") include(":instrumentation:runtime-telemetry:runtime-telemetry-java8:library") -include(":instrumentation:runtime-telemetry:runtime-telemetry-java8:testing") include(":instrumentation:runtime-telemetry:runtime-telemetry-java17:javaagent") include(":instrumentation:runtime-telemetry:runtime-telemetry-java17:library") include(":instrumentation:rxjava:rxjava-1.0:library") diff --git a/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/AbstractSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/AbstractSpringStarterSmokeTest.java index 6fd9f57f67be..4adbe9324612 100644 --- a/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/AbstractSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/AbstractSpringStarterSmokeTest.java @@ -33,7 +33,10 @@ public abstract class AbstractSpringStarterSmokeTest { "Registering converter from interface java.util.List to interface org.springframework.data.domain.Vector as reading converter although it doesn't convert from a store-supported type; You might want to check your annotation setup at the converter implementation", "Node may not be available.", "Could not configure topics", - "(id: -1 rack: null isFenced: false) disconnected"); + "(id: -1 rack: null isFenced: false) disconnected", + // expected deprecation warnings from tests using old runtime-telemetry properties + "otel.instrumentation.runtime-telemetry-java17.enable-all is deprecated", + "otel.instrumentation.runtime-telemetry.emit-experimental-telemetry is deprecated"); @Autowired protected OpenTelemetry openTelemetry;