use semconv attributes for jvm metrics + cleanup (#11257)

Co-authored-by: Lauri Tulmin <ltulmin@splunk.com>
This commit is contained in:
SylvainJuge 2024-05-01 16:32:10 +02:00 committed by GitHub
parent dfc79ebece
commit 745d880c06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 40 additions and 62 deletions

View File

@ -5,17 +5,16 @@
package io.opentelemetry.instrumentation.runtimemetrics.java8;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableList;
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.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
import io.opentelemetry.semconv.JvmAttributes;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
@ -54,9 +53,6 @@ public final class GarbageCollector {
private static final double MILLIS_PER_S = TimeUnit.SECONDS.toMillis(1);
// TODO: use the opentelemetry-semconv classes once we have metrics attributes there
private static final AttributeKey<String> JVM_GC_NAME = stringKey("jvm.gc.name");
private static final AttributeKey<String> JVM_GC_ACTION = stringKey("jvm.gc.action");
static final List<Double> GC_DURATION_BUCKETS = unmodifiableList(asList(0.01, 0.1, 1., 10.));
private static final NotificationFilter GC_FILTER =
@ -131,7 +127,9 @@ public final class GarbageCollector {
String gcAction = notificationInfo.getGcAction();
double duration = notificationInfo.getGcInfo().getDuration() / MILLIS_PER_S;
gcDuration.record(duration, Attributes.of(JVM_GC_NAME, gcName, JVM_GC_ACTION, gcAction));
gcDuration.record(
duration,
Attributes.of(JvmAttributes.JVM_GC_NAME, gcName, JvmAttributes.JVM_GC_ACTION, gcAction));
}
}

View File

@ -5,14 +5,13 @@
package io.opentelemetry.instrumentation.runtimemetrics.java8;
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;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
import io.opentelemetry.semconv.JvmAttributes;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
@ -47,14 +46,6 @@ import java.util.function.Function;
*/
public final class MemoryPools {
// TODO: use the opentelemetry-semconv classes once we have metrics attributes there
private static final AttributeKey<String> JVM_MEMORY_POOL_NAME =
stringKey("jvm.memory.pool.name");
private static final AttributeKey<String> JVM_MEMORY_TYPE = stringKey("jvm.memory.type");
private static final String HEAP = "heap";
private static final String NON_HEAP = "non_heap";
/** Register observers for java runtime memory metrics. */
public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry) {
return registerObservers(openTelemetry, ManagementFactory.getMemoryPoolMXBeans());
@ -73,8 +64,8 @@ public final class MemoryPools {
.setUnit("By")
.buildWithCallback(
callback(
JVM_MEMORY_POOL_NAME,
JVM_MEMORY_TYPE,
JvmAttributes.JVM_MEMORY_POOL_NAME,
JvmAttributes.JVM_MEMORY_TYPE,
poolBeans,
MemoryPoolMXBean::getUsage,
MemoryUsage::getUsed)));
@ -85,8 +76,8 @@ public final class MemoryPools {
.setUnit("By")
.buildWithCallback(
callback(
JVM_MEMORY_POOL_NAME,
JVM_MEMORY_TYPE,
JvmAttributes.JVM_MEMORY_POOL_NAME,
JvmAttributes.JVM_MEMORY_TYPE,
poolBeans,
MemoryPoolMXBean::getUsage,
MemoryUsage::getCommitted)));
@ -97,8 +88,8 @@ public final class MemoryPools {
.setUnit("By")
.buildWithCallback(
callback(
JVM_MEMORY_POOL_NAME,
JVM_MEMORY_TYPE,
JvmAttributes.JVM_MEMORY_POOL_NAME,
JvmAttributes.JVM_MEMORY_TYPE,
poolBeans,
MemoryPoolMXBean::getUsage,
MemoryUsage::getMax)));
@ -110,8 +101,8 @@ public final class MemoryPools {
.setUnit("By")
.buildWithCallback(
callback(
JVM_MEMORY_POOL_NAME,
JVM_MEMORY_TYPE,
JvmAttributes.JVM_MEMORY_POOL_NAME,
JvmAttributes.JVM_MEMORY_TYPE,
poolBeans,
MemoryPoolMXBean::getCollectionUsage,
MemoryUsage::getUsed)));
@ -155,9 +146,9 @@ public final class MemoryPools {
private static String memoryType(MemoryType memoryType) {
switch (memoryType) {
case HEAP:
return HEAP;
return JvmAttributes.JvmMemoryTypeValues.HEAP;
case NON_HEAP:
return NON_HEAP;
return JvmAttributes.JvmMemoryTypeValues.NON_HEAP;
}
return "unknown";
}

View File

@ -5,16 +5,14 @@
package io.opentelemetry.instrumentation.runtimemetrics.java8;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static java.util.Objects.requireNonNull;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
import io.opentelemetry.semconv.JvmAttributes;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
@ -55,10 +53,6 @@ public final class Threads {
// Visible for testing
static final Threads INSTANCE = new Threads();
// TODO: use the opentelemetry-semconv classes once we have metrics attributes there
static final AttributeKey<Boolean> JVM_THREAD_DAEMON = booleanKey("jvm.thread.daemon");
static final AttributeKey<String> JVM_THREAD_STATE = stringKey("jvm.thread.state");
/** Register observers for java runtime class metrics. */
public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry) {
return INSTANCE.registerObservers(openTelemetry, ManagementFactory.getThreadMXBean());
@ -102,10 +96,11 @@ public final class Threads {
return measurement -> {
int daemonThreadCount = threadBean.getDaemonThreadCount();
measurement.record(
daemonThreadCount, Attributes.builder().put(JVM_THREAD_DAEMON, true).build());
daemonThreadCount,
Attributes.builder().put(JvmAttributes.JVM_THREAD_DAEMON, true).build());
measurement.record(
threadBean.getThreadCount() - daemonThreadCount,
Attributes.builder().put(JVM_THREAD_DAEMON, false).build());
Attributes.builder().put(JvmAttributes.JVM_THREAD_DAEMON, false).build());
};
}
@ -133,7 +128,8 @@ public final class Threads {
throw new IllegalStateException("Unexpected error happened during ThreadInfo#isDaemon()", e);
}
String threadState = threadInfo.getThreadState().name().toLowerCase(Locale.ROOT);
return Attributes.of(JVM_THREAD_DAEMON, isDaemon, JVM_THREAD_STATE, threadState);
return Attributes.of(
JvmAttributes.JVM_THREAD_DAEMON, isDaemon, JvmAttributes.JVM_THREAD_STATE, threadState);
}
private Threads() {}

View File

@ -5,14 +5,13 @@
package io.opentelemetry.instrumentation.runtimemetrics.java8.internal;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static java.util.Collections.singletonList;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import io.opentelemetry.semconv.JvmAttributes;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
@ -29,14 +28,6 @@ import java.util.function.Consumer;
*/
public final class ExperimentalMemoryPools {
// TODO: use the opentelemetry-semconv classes once we have metrics attributes there
private static final AttributeKey<String> JVM_MEMORY_POOL_NAME =
stringKey("jvm.memory.pool.name");
private static final AttributeKey<String> JVM_MEMORY_TYPE = stringKey("jvm.memory.type");
private static final String HEAP = "heap";
private static final String NON_HEAP = "non_heap";
/** Register observers for java runtime experimental memory metrics. */
public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry) {
return registerObservers(openTelemetry, ManagementFactory.getMemoryPoolMXBeans());
@ -60,8 +51,8 @@ public final class ExperimentalMemoryPools {
for (MemoryPoolMXBean pool : poolBeans) {
attributeSets.add(
Attributes.builder()
.put(JVM_MEMORY_POOL_NAME, pool.getName())
.put(JVM_MEMORY_TYPE, memoryType(pool.getType()))
.put(JvmAttributes.JVM_MEMORY_POOL_NAME, pool.getName())
.put(JvmAttributes.JVM_MEMORY_TYPE, memoryType(pool.getType()))
.build());
}
@ -84,9 +75,9 @@ public final class ExperimentalMemoryPools {
private static String memoryType(MemoryType memoryType) {
switch (memoryType) {
case HEAP:
return HEAP;
return JvmAttributes.JvmMemoryTypeValues.HEAP;
case NON_HEAP:
return NON_HEAP;
return JvmAttributes.JvmMemoryTypeValues.NON_HEAP;
}
return "unknown";
}

View File

@ -6,8 +6,6 @@
package io.opentelemetry.instrumentation.runtimemetrics.java8;
import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE;
import static io.opentelemetry.instrumentation.runtimemetrics.java8.Threads.JVM_THREAD_DAEMON;
import static io.opentelemetry.instrumentation.runtimemetrics.java8.Threads.JVM_THREAD_STATE;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static org.mockito.Mockito.mock;
@ -16,6 +14,7 @@ import static org.mockito.Mockito.when;
import io.opentelemetry.instrumentation.testing.internal.AutoCleanupExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import io.opentelemetry.semconv.JvmAttributes;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import org.junit.jupiter.api.Test;
@ -67,12 +66,14 @@ class ThreadsStableSemconvTest {
point
.hasValue(2)
.hasAttributesSatisfying(
equalTo(JVM_THREAD_DAEMON, true)),
equalTo(JvmAttributes.JVM_THREAD_DAEMON, true)),
point ->
point
.hasValue(5)
.hasAttributesSatisfying(
equalTo(JVM_THREAD_DAEMON, false))))));
equalTo(
JvmAttributes.JVM_THREAD_DAEMON,
false))))));
}
@Test
@ -110,14 +111,18 @@ class ThreadsStableSemconvTest {
point
.hasValue(1)
.hasAttributesSatisfying(
equalTo(JVM_THREAD_DAEMON, false),
equalTo(JVM_THREAD_STATE, "runnable")),
equalTo(JvmAttributes.JVM_THREAD_DAEMON, false),
equalTo(
JvmAttributes.JVM_THREAD_STATE,
"runnable")),
point ->
point
.hasValue(1)
.hasAttributesSatisfying(
equalTo(JVM_THREAD_DAEMON, true),
equalTo(JVM_THREAD_STATE, "waiting"))))));
equalTo(JvmAttributes.JVM_THREAD_DAEMON, true),
equalTo(
JvmAttributes.JVM_THREAD_STATE,
"waiting"))))));
}
static final class ThreadInfoAnswer implements Answer<Object> {

View File

@ -200,10 +200,7 @@ public class AgentInstaller {
}
private static void copyNecessaryConfigToSystemProperties(ConfigProperties config) {
for (String property :
asList(
"otel.instrumentation.experimental.span-suppression-strategy",
"otel.semconv-stability.opt-in")) {
for (String property : asList("otel.instrumentation.experimental.span-suppression-strategy")) {
String value = config.getString(property);
if (value != null) {
System.setProperty(property, value);