Skip to content

Commit 288afdd

Browse files
committed
add experimental metric to jvm runtime metrics
1 parent 310287f commit 288afdd

File tree

3 files changed

+139
-0
lines changed

3 files changed

+139
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.runtimemetrics.java8.internal;
7+
8+
import io.opentelemetry.api.OpenTelemetry;
9+
import io.opentelemetry.api.metrics.Meter;
10+
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil;
11+
import java.lang.management.ManagementFactory;
12+
import java.lang.management.OperatingSystemMXBean;
13+
import java.util.ArrayList;
14+
import java.util.List;
15+
16+
/**
17+
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
18+
* any time.
19+
*/
20+
public final class ExperimentalFileDescriptor {
21+
22+
/** Register observers for java runtime file descriptor metrics. */
23+
public static List<AutoCloseable> registerObservers(OpenTelemetry openTelemetry) {
24+
return registerObservers(openTelemetry, ManagementFactory.getOperatingSystemMXBean());
25+
}
26+
27+
// Visible for testing
28+
static List<AutoCloseable> registerObservers(
29+
OpenTelemetry openTelemetry, OperatingSystemMXBean osBean) {
30+
Meter meter = JmxRuntimeMetricsUtil.getMeter(openTelemetry);
31+
List<AutoCloseable> observables = new ArrayList<>();
32+
33+
if (osBean instanceof com.sun.management.UnixOperatingSystemMXBean) {
34+
observables.add(
35+
meter
36+
.upDownCounterBuilder("jvm.file_descriptor.count")
37+
.setDescription("Number of open file descriptors as reported by the JVM.")
38+
.setUnit("{file_descriptor}")
39+
.buildWithCallback(
40+
observableMeasurement -> {
41+
long openFileDescriptorCount =
42+
((com.sun.management.UnixOperatingSystemMXBean) osBean)
43+
.getOpenFileDescriptorCount();
44+
if (openFileDescriptorCount >= 0) {
45+
observableMeasurement.record(openFileDescriptorCount);
46+
}
47+
}));
48+
}
49+
50+
return observables;
51+
}
52+
53+
private ExperimentalFileDescriptor() {}
54+
}

instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/JmxRuntimeMetricsFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public static List<AutoCloseable> buildObservables(
3333
observables.addAll(ExperimentalBufferPools.registerObservers(openTelemetry));
3434
observables.addAll(ExperimentalCpu.registerObservers(openTelemetry));
3535
observables.addAll(ExperimentalMemoryPools.registerObservers(openTelemetry));
36+
observables.addAll(ExperimentalFileDescriptor.registerObservers(openTelemetry));
3637
}
3738
return observables;
3839
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.runtimemetrics.java8.internal;
7+
8+
import static io.opentelemetry.instrumentation.runtimemetrics.java8.ScopeUtil.EXPECTED_SCOPE;
9+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
10+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
11+
import static org.mockito.Mockito.when;
12+
13+
import com.sun.management.UnixOperatingSystemMXBean;
14+
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
15+
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
16+
import java.lang.management.ManagementFactory;
17+
import java.lang.management.OperatingSystemMXBean;
18+
import org.junit.jupiter.api.BeforeEach;
19+
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.api.extension.ExtendWith;
21+
import org.junit.jupiter.api.extension.RegisterExtension;
22+
import org.mockito.Mock;
23+
import org.mockito.junit.jupiter.MockitoExtension;
24+
25+
@ExtendWith(MockitoExtension.class)
26+
class ExperimentalFileDescriptorTest {
27+
28+
@RegisterExtension
29+
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
30+
31+
@Mock private UnixOperatingSystemMXBean osBean;
32+
33+
@BeforeEach
34+
void setUp() {
35+
// Skip tests on non-Unix systems since UnixOperatingSystemMXBean is only available on Unix
36+
OperatingSystemMXBean realOsBean = ManagementFactory.getOperatingSystemMXBean();
37+
assumeTrue(realOsBean instanceof UnixOperatingSystemMXBean,
38+
"Skipping test: UnixOperatingSystemMXBean is only available on Unix systems");
39+
}
40+
41+
@Test
42+
// verify that mock is called with the correct value
43+
void registerObservers() {
44+
when(osBean.getOpenFileDescriptorCount()).thenReturn(42L);
45+
ExperimentalFileDescriptor.registerObservers(testing.getOpenTelemetry(), osBean);
46+
47+
testing.waitAndAssertMetrics(
48+
"io.opentelemetry.runtime-telemetry-java8",
49+
"jvm.file_descriptor.count",
50+
metrics ->
51+
metrics.anySatisfy(
52+
metricData ->
53+
assertThat(metricData)
54+
.hasInstrumentationScope(EXPECTED_SCOPE)
55+
.hasDescription("Number of open file descriptors as reported by the JVM.")
56+
.hasUnit("{file_descriptor}")
57+
.hasLongSumSatisfying(
58+
sum ->
59+
sum.hasPointsSatisfying(
60+
point -> point.hasValue(42)))));
61+
}
62+
63+
@Test
64+
// Verify that no metrics are emitted with non-zero values
65+
void registerObservers_NegativeValue() {
66+
when(osBean.getOpenFileDescriptorCount()).thenReturn(-1L);
67+
ExperimentalFileDescriptor.registerObservers(testing.getOpenTelemetry(), osBean);
68+
69+
testing.waitAndAssertMetrics(
70+
"io.opentelemetry.runtime-telemetry-java8",
71+
"jvm.file_descriptor.count",
72+
metrics ->
73+
metrics.allSatisfy(
74+
metricData ->
75+
assertThat(metricData)
76+
.hasInstrumentationScope(EXPECTED_SCOPE)
77+
.hasDescription("Number of open file descriptors as reported by the JVM.")
78+
.hasUnit("{file_descriptor}")
79+
.hasLongSumSatisfying(
80+
sum ->
81+
sum.hasPointsSatisfying(
82+
point -> point.hasValue(0)))));
83+
}
84+
}

0 commit comments

Comments
 (0)