parent
87038f2899
commit
f208ba72b7
|
@ -13,8 +13,8 @@ rootProject.extra["versions"] = dependencyVersions
|
|||
|
||||
// IMPORTANT when updating otelVersion, make sure that grpcVersion below is >= the grpc version
|
||||
// used by that otel version
|
||||
val otelVersion = "1.6.0"
|
||||
val grpcVersion = "1.40.1"
|
||||
val otelVersion = "1.7.0"
|
||||
val grpcVersion = "1.41.0"
|
||||
rootProject.extra["otelVersion"] = otelVersion
|
||||
|
||||
// Need both BOM and -all
|
||||
|
@ -107,7 +107,7 @@ val DEPENDENCIES = listOf(
|
|||
"commons-validator:commons-validator:1.7",
|
||||
"info.solidsoft.spock:spock-global-unroll:0.5.1",
|
||||
"io.netty:netty:3.10.6.Final",
|
||||
"org.assertj:assertj-core:3.19.0",
|
||||
"org.assertj:assertj-core:3.21.0",
|
||||
"org.awaitility:awaitility:4.1.0",
|
||||
"org.checkerframework:checker-qual:3.14.0",
|
||||
"org.codehaus.groovy:groovy-all:${groovyVersion}",
|
||||
|
|
|
@ -7,12 +7,14 @@ package io.opentelemetry.instrumentation.api.instrumenter.http;
|
|||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
|
||||
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.RequestListener;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import io.opentelemetry.sdk.metrics.testing.InMemoryMetricReader;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -21,7 +23,9 @@ class HttpClientMetricsTest {
|
|||
|
||||
@Test
|
||||
void collectsMetrics() {
|
||||
SdkMeterProvider meterProvider = SdkMeterProvider.builder().build();
|
||||
InMemoryMetricReader metricReader = new InMemoryMetricReader();
|
||||
SdkMeterProvider meterProvider =
|
||||
SdkMeterProvider.builder().registerMetricReader(metricReader).build();
|
||||
|
||||
RequestListener listener = HttpClientMetrics.get().create(meterProvider.get("test"));
|
||||
|
||||
|
@ -44,49 +48,68 @@ class HttpClientMetricsTest {
|
|||
|
||||
Context context1 = listener.start(Context.current(), requestAttributes, nanos(100));
|
||||
|
||||
Collection<MetricData> metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).isEmpty();
|
||||
// TODO(anuraaga): Remove await from this file after 1.8.0 hopefully fixes
|
||||
// https://github.com/open-telemetry/opentelemetry-java/issues/3725
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).isEmpty();
|
||||
});
|
||||
|
||||
Context context2 = listener.start(Context.current(), requestAttributes, nanos(150));
|
||||
|
||||
metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).isEmpty();
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).isEmpty();
|
||||
});
|
||||
|
||||
listener.end(context1, responseAttributes, nanos(250));
|
||||
|
||||
metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.hasSum(150 /* millis */)
|
||||
.attributes()
|
||||
.containsOnly(
|
||||
attributeEntry("http.host", "host"),
|
||||
attributeEntry("http.method", "GET"),
|
||||
attributeEntry("http.scheme", "https"),
|
||||
attributeEntry("net.host.name", "localhost"),
|
||||
attributeEntry("net.host.port", 1234L))));
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.hasSum(150 /* millis */)
|
||||
.attributes()
|
||||
.containsOnly(
|
||||
attributeEntry("http.host", "host"),
|
||||
attributeEntry("http.method", "GET"),
|
||||
attributeEntry("http.scheme", "https"),
|
||||
attributeEntry("net.host.name", "localhost"),
|
||||
attributeEntry("net.host.port", 1234L))));
|
||||
});
|
||||
|
||||
listener.end(context2, responseAttributes, nanos(300));
|
||||
|
||||
metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasSum(300 /* millis */)));
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point -> assertThat(point).hasSum(300 /* millis */)));
|
||||
});
|
||||
}
|
||||
|
||||
private static long nanos(int millis) {
|
||||
|
|
|
@ -7,12 +7,14 @@ package io.opentelemetry.instrumentation.api.instrumenter.http;
|
|||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
|
||||
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.RequestListener;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import io.opentelemetry.sdk.metrics.testing.InMemoryMetricReader;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -21,7 +23,9 @@ class HttpServerMetricsTest {
|
|||
|
||||
@Test
|
||||
void collectsMetrics() {
|
||||
SdkMeterProvider meterProvider = SdkMeterProvider.builder().build();
|
||||
InMemoryMetricReader metricReader = new InMemoryMetricReader();
|
||||
SdkMeterProvider meterProvider =
|
||||
SdkMeterProvider.builder().registerMetricReader(metricReader).build();
|
||||
|
||||
RequestListener listener = HttpServerMetrics.get().create(meterProvider.get("test"));
|
||||
|
||||
|
@ -44,92 +48,111 @@ class HttpServerMetricsTest {
|
|||
|
||||
Context context1 = listener.start(Context.current(), requestAttributes, nanos(100));
|
||||
|
||||
Collection<MetricData> metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasDescription(
|
||||
"The number of concurrent HTTP requests that are currently in-flight")
|
||||
.hasUnit("requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.hasValue(1)
|
||||
.attributes()
|
||||
.containsOnly(
|
||||
attributeEntry("http.host", "host"),
|
||||
attributeEntry("http.method", "GET"),
|
||||
attributeEntry("http.scheme", "https"))));
|
||||
// TODO(anuraaga): Remove await from this file after 1.8.0 hopefully fixes
|
||||
// https://github.com/open-telemetry/opentelemetry-java/issues/3725
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasDescription(
|
||||
"The number of concurrent HTTP requests that are currently in-flight")
|
||||
.hasUnit("requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.hasValue(1)
|
||||
.attributes()
|
||||
.containsOnly(
|
||||
attributeEntry("http.host", "host"),
|
||||
attributeEntry("http.method", "GET"),
|
||||
attributeEntry("http.scheme", "https"))));
|
||||
});
|
||||
|
||||
Context context2 = listener.start(Context.current(), requestAttributes, nanos(150));
|
||||
|
||||
metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasValue(2)));
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(1);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasValue(2)));
|
||||
});
|
||||
|
||||
listener.end(context1, responseAttributes, nanos(250));
|
||||
|
||||
metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(2);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasValue(1)));
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.hasSum(150 /* millis */)
|
||||
.attributes()
|
||||
.containsOnly(
|
||||
attributeEntry("http.host", "host"),
|
||||
attributeEntry("http.method", "GET"),
|
||||
attributeEntry("http.scheme", "https"),
|
||||
attributeEntry("net.host.name", "localhost"),
|
||||
attributeEntry("net.host.port", 1234L))));
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(2);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasValue(1)));
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.hasSum(150 /* millis */)
|
||||
.attributes()
|
||||
.containsOnly(
|
||||
attributeEntry("http.host", "host"),
|
||||
attributeEntry("http.method", "GET"),
|
||||
attributeEntry("http.scheme", "https"),
|
||||
attributeEntry("net.host.name", "localhost"),
|
||||
attributeEntry("net.host.port", 1234L))));
|
||||
});
|
||||
|
||||
listener.end(context2, responseAttributes, nanos(300));
|
||||
|
||||
metrics = meterProvider.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(2);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasValue(0)));
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasSum(300 /* millis */)));
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
assertThat(metrics).hasSize(2);
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.active_requests")
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(point -> assertThat(point).hasValue(0)));
|
||||
assertThat(metrics)
|
||||
.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.server.duration")
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point -> assertThat(point).hasSum(300 /* millis */)));
|
||||
});
|
||||
}
|
||||
|
||||
private static long nanos(int millis) {
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.awslambda.v1_0;
|
||||
|
||||
import io.opentelemetry.api.metrics.GlobalMeterProvider;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -15,7 +17,13 @@ final class LambdaUtils {
|
|||
|
||||
static void forceFlush(OpenTelemetrySdk openTelemetrySdk, long flushTimeout, TimeUnit unit) {
|
||||
CompletableResultCode traceFlush = openTelemetrySdk.getSdkTracerProvider().forceFlush();
|
||||
CompletableResultCode metricsFlush = IntervalMetricReader.forceFlushGlobal();
|
||||
MeterProvider meterProvider = GlobalMeterProvider.get();
|
||||
final CompletableResultCode metricsFlush;
|
||||
if (meterProvider instanceof SdkMeterProvider) {
|
||||
metricsFlush = ((SdkMeterProvider) meterProvider).forceFlush();
|
||||
} else {
|
||||
metricsFlush = CompletableResultCode.ofSuccess();
|
||||
}
|
||||
CompletableResultCode.ofAll(Arrays.asList(traceFlush, metricsFlush)).join(flushTimeout, unit);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,112 +6,41 @@
|
|||
package io.opentelemetry.instrumentation.oshi;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.metrics.data.DoublePointData;
|
||||
import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData;
|
||||
import io.opentelemetry.sdk.metrics.data.LongPointData;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricDataType;
|
||||
import io.opentelemetry.sdk.metrics.data.PointData;
|
||||
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
|
||||
import io.opentelemetry.sdk.metrics.export.MetricExporter;
|
||||
import java.util.ArrayList;
|
||||
import io.opentelemetry.sdk.metrics.testing.InMemoryMetricReader;
|
||||
import io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions;
|
||||
import io.opentelemetry.sdk.testing.assertj.metrics.MetricDataAssert;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import java.util.function.Consumer;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
class AbstractMetricsTest {
|
||||
TestMetricExporter testMetricExporter;
|
||||
|
||||
static SdkMeterProvider meterProvider;
|
||||
static InMemoryMetricReader metricReader;
|
||||
|
||||
@BeforeAll
|
||||
static void initializeOpenTelemetry() {
|
||||
meterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal();
|
||||
metricReader = new InMemoryMetricReader();
|
||||
meterProvider =
|
||||
SdkMeterProvider.builder().registerMetricReader(metricReader).buildAndRegisterGlobal();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
testMetricExporter = new TestMetricExporter();
|
||||
}
|
||||
protected void waitAndAssertMetrics(Consumer<MetricDataAssert>... assertions) {
|
||||
await()
|
||||
.untilAsserted(
|
||||
() -> {
|
||||
Collection<MetricData> metrics = metricReader.collectAllMetrics();
|
||||
|
||||
IntervalMetricReader createIntervalMetricReader() {
|
||||
return IntervalMetricReader.builder()
|
||||
.setExportIntervalMillis(100)
|
||||
.setMetricExporter(testMetricExporter)
|
||||
.setMetricProducers(Collections.singletonList(meterProvider))
|
||||
.buildAndStart();
|
||||
}
|
||||
assertThat(metrics).isNotEmpty();
|
||||
|
||||
public void verify(
|
||||
String metricName, String unit, MetricDataType type, boolean checkNonZeroValue) {
|
||||
List<MetricData> metricDataList = testMetricExporter.metricDataList;
|
||||
for (MetricData metricData : metricDataList) {
|
||||
if (metricData.getName().equals(metricName)) {
|
||||
assertThat(metricData.getDescription()).isNotEmpty();
|
||||
assertThat(metricData.getUnit()).isEqualTo(unit);
|
||||
List<PointData> points = new ArrayList<>();
|
||||
points.addAll(metricData.getDoubleGaugeData().getPoints());
|
||||
points.addAll(metricData.getDoubleSumData().getPoints());
|
||||
points.addAll(metricData.getDoubleSummaryData().getPoints());
|
||||
points.addAll(metricData.getLongGaugeData().getPoints());
|
||||
points.addAll(metricData.getLongSumData().getPoints());
|
||||
|
||||
assertThat(points).isNotEmpty();
|
||||
assertThat(metricData.getType()).isEqualTo(type);
|
||||
if (checkNonZeroValue) {
|
||||
for (PointData point : points) {
|
||||
if (point instanceof LongPointData) {
|
||||
LongPointData longPoint = (LongPointData) point;
|
||||
assertThat(longPoint.getValue()).isGreaterThan(0);
|
||||
} else if (point instanceof DoublePointData) {
|
||||
DoublePointData doublePoint = (DoublePointData) point;
|
||||
assertThat(doublePoint.getValue()).isGreaterThan(0.0);
|
||||
} else if (point instanceof DoubleSummaryPointData) {
|
||||
DoubleSummaryPointData summaryPoint = (DoubleSummaryPointData) point;
|
||||
assertThat(summaryPoint.getSum()).isGreaterThan(0.0);
|
||||
} else {
|
||||
Assertions.fail("unexpected type " + metricData.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Assertions.fail("No metric for " + metricName);
|
||||
}
|
||||
|
||||
static class TestMetricExporter implements MetricExporter {
|
||||
private final List<MetricData> metricDataList = new CopyOnWriteArrayList<>();
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public CompletableResultCode export(Collection<MetricData> collection) {
|
||||
metricDataList.addAll(collection);
|
||||
latch.countDown();
|
||||
return CompletableResultCode.ofSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableResultCode flush() {
|
||||
return CompletableResultCode.ofSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableResultCode shutdown() {
|
||||
return CompletableResultCode.ofSuccess();
|
||||
}
|
||||
|
||||
public void waitForData() throws InterruptedException {
|
||||
latch.await(20, TimeUnit.SECONDS);
|
||||
}
|
||||
for (Consumer<MetricDataAssert> assertion : assertions) {
|
||||
assertThat(metrics)
|
||||
.anySatisfy(metric -> assertion.accept(MetricAssertions.assertThat(metric)));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,26 +5,30 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.oshi;
|
||||
|
||||
import io.opentelemetry.sdk.metrics.data.MetricDataType;
|
||||
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
|
||||
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ProcessMetricsTest extends AbstractMetricsTest {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
public void test() {
|
||||
ProcessMetrics.registerObservers();
|
||||
IntervalMetricReader intervalMetricReader = createIntervalMetricReader();
|
||||
|
||||
testMetricExporter.waitForData();
|
||||
intervalMetricReader.shutdown();
|
||||
|
||||
verify(
|
||||
"runtime.java.memory", "bytes", MetricDataType.LONG_GAUGE, /* checkNonZeroValue= */ true);
|
||||
verify(
|
||||
"runtime.java.cpu_time",
|
||||
"seconds",
|
||||
MetricDataType.DOUBLE_GAUGE,
|
||||
/* checkNonZeroValue= */ true);
|
||||
waitAndAssertMetrics(
|
||||
metric ->
|
||||
metric
|
||||
.hasName("runtime.java.memory")
|
||||
.hasUnit("bytes")
|
||||
.hasLongGauge()
|
||||
.points()
|
||||
.anySatisfy(point -> assertThat(point.getValue()).isPositive()),
|
||||
metric ->
|
||||
metric
|
||||
.hasName("runtime.java.cpu_time")
|
||||
.hasUnit("seconds")
|
||||
.hasDoubleGauge()
|
||||
.points()
|
||||
.anySatisfy(point -> assertThat(point.getValue()).isPositive()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,44 +5,34 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.oshi;
|
||||
|
||||
import io.opentelemetry.sdk.metrics.data.MetricDataType;
|
||||
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
|
||||
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SystemMetricsTest extends AbstractMetricsTest {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
public void test() {
|
||||
SystemMetrics.registerObservers();
|
||||
IntervalMetricReader intervalMetricReader = createIntervalMetricReader();
|
||||
|
||||
testMetricExporter.waitForData();
|
||||
intervalMetricReader.shutdown();
|
||||
|
||||
verify("system.memory.usage", "By", MetricDataType.LONG_GAUGE, /* checkNonZeroValue= */ true);
|
||||
verify(
|
||||
"system.memory.utilization",
|
||||
"1",
|
||||
MetricDataType.DOUBLE_GAUGE,
|
||||
/* checkNonZeroValue= */ true);
|
||||
|
||||
verify("system.network.io", "By", MetricDataType.LONG_GAUGE, /* checkNonZeroValue= */ false);
|
||||
verify(
|
||||
"system.network.packets",
|
||||
"packets",
|
||||
MetricDataType.LONG_GAUGE,
|
||||
/* checkNonZeroValue= */ false);
|
||||
verify(
|
||||
"system.network.errors",
|
||||
"errors",
|
||||
MetricDataType.LONG_GAUGE,
|
||||
/* checkNonZeroValue= */ false);
|
||||
|
||||
verify("system.disk.io", "By", MetricDataType.LONG_GAUGE, /* checkNonZeroValue= */ false);
|
||||
verify(
|
||||
"system.disk.operations",
|
||||
"operations",
|
||||
MetricDataType.LONG_GAUGE,
|
||||
/* checkNonZeroValue= */ false);
|
||||
waitAndAssertMetrics(
|
||||
metric ->
|
||||
metric
|
||||
.hasName("system.memory.usage")
|
||||
.hasUnit("By")
|
||||
.hasLongGauge()
|
||||
.points()
|
||||
.anySatisfy(point -> assertThat(point.getValue()).isPositive()),
|
||||
metric ->
|
||||
metric
|
||||
.hasName("system.memory.utilization")
|
||||
.hasUnit("1")
|
||||
.hasDoubleGauge()
|
||||
.points()
|
||||
.anySatisfy(point -> assertThat(point.getValue()).isPositive()),
|
||||
metric -> metric.hasName("system.network.io").hasUnit("By").hasLongGauge(),
|
||||
metric -> metric.hasName("system.network.packets").hasUnit("packets").hasLongGauge(),
|
||||
metric -> metric.hasName("system.network.errors").hasUnit("errors").hasLongGauge(),
|
||||
metric -> metric.hasName("system.disk.operations").hasUnit("operations").hasLongGauge());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ package io.opentelemetry.javaagent.tooling;
|
|||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.metrics.GlobalMeterProvider;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.extension.noopapi.NoopOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.config.Config;
|
||||
import io.opentelemetry.javaagent.extension.AgentListener;
|
||||
|
@ -15,7 +17,7 @@ import io.opentelemetry.javaagent.tooling.config.ConfigPropertiesAdapter;
|
|||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.OpenTelemetrySdkAutoConfiguration;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -51,8 +53,14 @@ public class OpenTelemetryInstaller implements AgentListener {
|
|||
OpenTelemetrySdkAccess.internalSetForceFlush(
|
||||
(timeout, unit) -> {
|
||||
CompletableResultCode traceResult = sdk.getSdkTracerProvider().forceFlush();
|
||||
CompletableResultCode flushResult = IntervalMetricReader.forceFlushGlobal();
|
||||
CompletableResultCode.ofAll(Arrays.asList(traceResult, flushResult))
|
||||
MeterProvider meterProvider = GlobalMeterProvider.get();
|
||||
final CompletableResultCode metricsResult;
|
||||
if (meterProvider instanceof SdkMeterProvider) {
|
||||
metricsResult = ((SdkMeterProvider) meterProvider).forceFlush();
|
||||
} else {
|
||||
metricsResult = CompletableResultCode.ofSuccess();
|
||||
}
|
||||
CompletableResultCode.ofAll(Arrays.asList(traceResult, metricsResult))
|
||||
.join(timeout, unit);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,6 +26,6 @@ public class AgentTestingExporterFactory {
|
|||
}
|
||||
|
||||
public static boolean forceFlushCalled() {
|
||||
return AgentTestingSdkCustomizer.spanProcessor.forceFlushCalled;
|
||||
return AgentTestingTracingCustomizer.spanProcessor.forceFlushCalled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.testing.exporter;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.metrics.SdkMeterProviderConfigurer;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
|
||||
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
|
||||
import java.time.Duration;
|
||||
|
||||
@AutoService(SdkMeterProviderConfigurer.class)
|
||||
public class AgentTestingMetricsCustomizer implements SdkMeterProviderConfigurer {
|
||||
@Override
|
||||
public void configure(
|
||||
SdkMeterProviderBuilder sdkMeterProviderBuilder, ConfigProperties configProperties) {
|
||||
sdkMeterProviderBuilder.registerMetricReader(
|
||||
PeriodicMetricReader.create(
|
||||
AgentTestingExporterFactory.metricExporter, Duration.ofMillis(100)));
|
||||
}
|
||||
}
|
|
@ -6,17 +6,13 @@
|
|||
package io.opentelemetry.javaagent.testing.exporter;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.api.metrics.GlobalMeterProvider;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
|
||||
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
|
||||
import java.util.Collections;
|
||||
|
||||
@AutoService(SdkTracerProviderConfigurer.class)
|
||||
public class AgentTestingSdkCustomizer implements SdkTracerProviderConfigurer {
|
||||
public class AgentTestingTracingCustomizer implements SdkTracerProviderConfigurer {
|
||||
|
||||
static final AgentTestingSpanProcessor spanProcessor =
|
||||
new AgentTestingSpanProcessor(
|
||||
|
@ -29,13 +25,5 @@ public class AgentTestingSdkCustomizer implements SdkTracerProviderConfigurer {
|
|||
@Override
|
||||
public void configure(SdkTracerProviderBuilder tracerProviderBuilder, ConfigProperties config) {
|
||||
tracerProviderBuilder.addSpanProcessor(spanProcessor);
|
||||
|
||||
// Until metrics story settles down there is no SPI for it, we rely on the fact that metrics is
|
||||
// already set up when tracing configuration begins.
|
||||
IntervalMetricReader.builder()
|
||||
.setExportIntervalMillis(100)
|
||||
.setMetricExporter(AgentTestingExporterFactory.metricExporter)
|
||||
.setMetricProducers(Collections.singleton((SdkMeterProvider) GlobalMeterProvider.get()))
|
||||
.buildAndStart();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue