Update to OTel 1.7 (#4340)

* Update to OTel 1.7

* Fix metrics tests
This commit is contained in:
Anuraag Agrawal 2021-10-11 19:52:50 +09:00 committed by GitHub
parent 87038f2899
commit f208ba72b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 269 additions and 272 deletions

View File

@ -13,8 +13,8 @@ rootProject.extra["versions"] = dependencyVersions
// IMPORTANT when updating otelVersion, make sure that grpcVersion below is >= the grpc version // IMPORTANT when updating otelVersion, make sure that grpcVersion below is >= the grpc version
// used by that otel version // used by that otel version
val otelVersion = "1.6.0" val otelVersion = "1.7.0"
val grpcVersion = "1.40.1" val grpcVersion = "1.41.0"
rootProject.extra["otelVersion"] = otelVersion rootProject.extra["otelVersion"] = otelVersion
// Need both BOM and -all // Need both BOM and -all
@ -107,7 +107,7 @@ val DEPENDENCIES = listOf(
"commons-validator:commons-validator:1.7", "commons-validator:commons-validator:1.7",
"info.solidsoft.spock:spock-global-unroll:0.5.1", "info.solidsoft.spock:spock-global-unroll:0.5.1",
"io.netty:netty:3.10.6.Final", "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.awaitility:awaitility:4.1.0",
"org.checkerframework:checker-qual:3.14.0", "org.checkerframework:checker-qual:3.14.0",
"org.codehaus.groovy:groovy-all:${groovyVersion}", "org.codehaus.groovy:groovy-all:${groovyVersion}",

View File

@ -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.OpenTelemetryAssertions.attributeEntry;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; 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.api.common.Attributes;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.RequestListener; import io.opentelemetry.instrumentation.api.instrumenter.RequestListener;
import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.testing.InMemoryMetricReader;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -21,7 +23,9 @@ class HttpClientMetricsTest {
@Test @Test
void collectsMetrics() { 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")); RequestListener listener = HttpClientMetrics.get().create(meterProvider.get("test"));
@ -44,49 +48,68 @@ class HttpClientMetricsTest {
Context context1 = listener.start(Context.current(), requestAttributes, nanos(100)); Context context1 = listener.start(Context.current(), requestAttributes, nanos(100));
Collection<MetricData> metrics = meterProvider.collectAllMetrics(); // TODO(anuraaga): Remove await from this file after 1.8.0 hopefully fixes
assertThat(metrics).isEmpty(); // 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)); Context context2 = listener.start(Context.current(), requestAttributes, nanos(150));
metrics = meterProvider.collectAllMetrics(); await()
assertThat(metrics).isEmpty(); .untilAsserted(
() -> {
Collection<MetricData> metrics = metricReader.collectAllMetrics();
assertThat(metrics).isEmpty();
});
listener.end(context1, responseAttributes, nanos(250)); listener.end(context1, responseAttributes, nanos(250));
metrics = meterProvider.collectAllMetrics(); await()
assertThat(metrics).hasSize(1); .untilAsserted(
assertThat(metrics) () -> {
.anySatisfy( Collection<MetricData> metrics = metricReader.collectAllMetrics();
metric -> assertThat(metrics).hasSize(1);
assertThat(metric) assertThat(metrics)
.hasName("http.client.duration") .anySatisfy(
.hasDoubleHistogram() metric ->
.points() assertThat(metric)
.satisfiesExactly( .hasName("http.client.duration")
point -> .hasDoubleHistogram()
assertThat(point) .points()
.hasSum(150 /* millis */) .satisfiesExactly(
.attributes() point ->
.containsOnly( assertThat(point)
attributeEntry("http.host", "host"), .hasSum(150 /* millis */)
attributeEntry("http.method", "GET"), .attributes()
attributeEntry("http.scheme", "https"), .containsOnly(
attributeEntry("net.host.name", "localhost"), attributeEntry("http.host", "host"),
attributeEntry("net.host.port", 1234L)))); attributeEntry("http.method", "GET"),
attributeEntry("http.scheme", "https"),
attributeEntry("net.host.name", "localhost"),
attributeEntry("net.host.port", 1234L))));
});
listener.end(context2, responseAttributes, nanos(300)); listener.end(context2, responseAttributes, nanos(300));
metrics = meterProvider.collectAllMetrics(); await()
assertThat(metrics).hasSize(1); .untilAsserted(
assertThat(metrics) () -> {
.anySatisfy( Collection<MetricData> metrics = metricReader.collectAllMetrics();
metric -> assertThat(metrics).hasSize(1);
assertThat(metric) assertThat(metrics)
.hasName("http.client.duration") .anySatisfy(
.hasDoubleHistogram() metric ->
.points() assertThat(metric)
.satisfiesExactly(point -> assertThat(point).hasSum(300 /* millis */))); .hasName("http.client.duration")
.hasDoubleHistogram()
.points()
.satisfiesExactly(
point -> assertThat(point).hasSum(300 /* millis */)));
});
} }
private static long nanos(int millis) { private static long nanos(int millis) {

View File

@ -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.OpenTelemetryAssertions.attributeEntry;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; 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.api.common.Attributes;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.RequestListener; import io.opentelemetry.instrumentation.api.instrumenter.RequestListener;
import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.testing.InMemoryMetricReader;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -21,7 +23,9 @@ class HttpServerMetricsTest {
@Test @Test
void collectsMetrics() { 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")); RequestListener listener = HttpServerMetrics.get().create(meterProvider.get("test"));
@ -44,92 +48,111 @@ class HttpServerMetricsTest {
Context context1 = listener.start(Context.current(), requestAttributes, nanos(100)); Context context1 = listener.start(Context.current(), requestAttributes, nanos(100));
Collection<MetricData> metrics = meterProvider.collectAllMetrics(); // TODO(anuraaga): Remove await from this file after 1.8.0 hopefully fixes
assertThat(metrics).hasSize(1); // https://github.com/open-telemetry/opentelemetry-java/issues/3725
assertThat(metrics) await()
.anySatisfy( .untilAsserted(
metric -> () -> {
assertThat(metric) Collection<MetricData> metrics = metricReader.collectAllMetrics();
.hasName("http.server.active_requests") assertThat(metrics).hasSize(1);
.hasDescription( assertThat(metrics)
"The number of concurrent HTTP requests that are currently in-flight") .anySatisfy(
.hasUnit("requests") metric ->
.hasLongSum() assertThat(metric)
.points() .hasName("http.server.active_requests")
.satisfiesExactly( .hasDescription(
point -> "The number of concurrent HTTP requests that are currently in-flight")
assertThat(point) .hasUnit("requests")
.hasValue(1) .hasLongSum()
.attributes() .points()
.containsOnly( .satisfiesExactly(
attributeEntry("http.host", "host"), point ->
attributeEntry("http.method", "GET"), assertThat(point)
attributeEntry("http.scheme", "https")))); .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)); Context context2 = listener.start(Context.current(), requestAttributes, nanos(150));
metrics = meterProvider.collectAllMetrics(); await()
assertThat(metrics).hasSize(1); .untilAsserted(
assertThat(metrics) () -> {
.anySatisfy( Collection<MetricData> metrics = metricReader.collectAllMetrics();
metric -> assertThat(metrics).hasSize(1);
assertThat(metric) assertThat(metrics)
.hasName("http.server.active_requests") .anySatisfy(
.hasLongSum() metric ->
.points() assertThat(metric)
.satisfiesExactly(point -> assertThat(point).hasValue(2))); .hasName("http.server.active_requests")
.hasLongSum()
.points()
.satisfiesExactly(point -> assertThat(point).hasValue(2)));
});
listener.end(context1, responseAttributes, nanos(250)); listener.end(context1, responseAttributes, nanos(250));
metrics = meterProvider.collectAllMetrics(); await()
assertThat(metrics).hasSize(2); .untilAsserted(
assertThat(metrics) () -> {
.anySatisfy( Collection<MetricData> metrics = metricReader.collectAllMetrics();
metric -> assertThat(metrics).hasSize(2);
assertThat(metric) assertThat(metrics)
.hasName("http.server.active_requests") .anySatisfy(
.hasLongSum() metric ->
.points() assertThat(metric)
.satisfiesExactly(point -> assertThat(point).hasValue(1))); .hasName("http.server.active_requests")
assertThat(metrics) .hasLongSum()
.anySatisfy( .points()
metric -> .satisfiesExactly(point -> assertThat(point).hasValue(1)));
assertThat(metric) assertThat(metrics)
.hasName("http.server.duration") .anySatisfy(
.hasDoubleHistogram() metric ->
.points() assertThat(metric)
.satisfiesExactly( .hasName("http.server.duration")
point -> .hasDoubleHistogram()
assertThat(point) .points()
.hasSum(150 /* millis */) .satisfiesExactly(
.attributes() point ->
.containsOnly( assertThat(point)
attributeEntry("http.host", "host"), .hasSum(150 /* millis */)
attributeEntry("http.method", "GET"), .attributes()
attributeEntry("http.scheme", "https"), .containsOnly(
attributeEntry("net.host.name", "localhost"), attributeEntry("http.host", "host"),
attributeEntry("net.host.port", 1234L)))); attributeEntry("http.method", "GET"),
attributeEntry("http.scheme", "https"),
attributeEntry("net.host.name", "localhost"),
attributeEntry("net.host.port", 1234L))));
});
listener.end(context2, responseAttributes, nanos(300)); listener.end(context2, responseAttributes, nanos(300));
metrics = meterProvider.collectAllMetrics(); await()
assertThat(metrics).hasSize(2); .untilAsserted(
assertThat(metrics) () -> {
.anySatisfy( Collection<MetricData> metrics = metricReader.collectAllMetrics();
metric -> assertThat(metrics).hasSize(2);
assertThat(metric) assertThat(metrics)
.hasName("http.server.active_requests") .anySatisfy(
.hasLongSum() metric ->
.points() assertThat(metric)
.satisfiesExactly(point -> assertThat(point).hasValue(0))); .hasName("http.server.active_requests")
assertThat(metrics) .hasLongSum()
.anySatisfy( .points()
metric -> .satisfiesExactly(point -> assertThat(point).hasValue(0)));
assertThat(metric) assertThat(metrics)
.hasName("http.server.duration") .anySatisfy(
.hasDoubleHistogram() metric ->
.points() assertThat(metric)
.satisfiesExactly(point -> assertThat(point).hasSum(300 /* millis */))); .hasName("http.server.duration")
.hasDoubleHistogram()
.points()
.satisfiesExactly(
point -> assertThat(point).hasSum(300 /* millis */)));
});
} }
private static long nanos(int millis) { private static long nanos(int millis) {

View File

@ -5,9 +5,11 @@
package io.opentelemetry.instrumentation.awslambda.v1_0; 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.OpenTelemetrySdk;
import io.opentelemetry.sdk.common.CompletableResultCode; 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.Arrays;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -15,7 +17,13 @@ final class LambdaUtils {
static void forceFlush(OpenTelemetrySdk openTelemetrySdk, long flushTimeout, TimeUnit unit) { static void forceFlush(OpenTelemetrySdk openTelemetrySdk, long flushTimeout, TimeUnit unit) {
CompletableResultCode traceFlush = openTelemetrySdk.getSdkTracerProvider().forceFlush(); 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); CompletableResultCode.ofAll(Arrays.asList(traceFlush, metricsFlush)).join(flushTimeout, unit);
} }

View File

@ -6,112 +6,41 @@
package io.opentelemetry.instrumentation.oshi; package io.opentelemetry.instrumentation.oshi;
import static org.assertj.core.api.Assertions.assertThat; 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.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.MetricData;
import io.opentelemetry.sdk.metrics.data.MetricDataType; import io.opentelemetry.sdk.metrics.testing.InMemoryMetricReader;
import io.opentelemetry.sdk.metrics.data.PointData; import io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions;
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader; import io.opentelemetry.sdk.testing.assertj.metrics.MetricDataAssert;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.function.Consumer;
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 org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
class AbstractMetricsTest { class AbstractMetricsTest {
TestMetricExporter testMetricExporter;
static SdkMeterProvider meterProvider; static SdkMeterProvider meterProvider;
static InMemoryMetricReader metricReader;
@BeforeAll @BeforeAll
static void initializeOpenTelemetry() { static void initializeOpenTelemetry() {
meterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); metricReader = new InMemoryMetricReader();
meterProvider =
SdkMeterProvider.builder().registerMetricReader(metricReader).buildAndRegisterGlobal();
} }
@BeforeEach protected void waitAndAssertMetrics(Consumer<MetricDataAssert>... assertions) {
void beforeEach() { await()
testMetricExporter = new TestMetricExporter(); .untilAsserted(
} () -> {
Collection<MetricData> metrics = metricReader.collectAllMetrics();
IntervalMetricReader createIntervalMetricReader() { assertThat(metrics).isNotEmpty();
return IntervalMetricReader.builder()
.setExportIntervalMillis(100)
.setMetricExporter(testMetricExporter)
.setMetricProducers(Collections.singletonList(meterProvider))
.buildAndStart();
}
public void verify( for (Consumer<MetricDataAssert> assertion : assertions) {
String metricName, String unit, MetricDataType type, boolean checkNonZeroValue) { assertThat(metrics)
List<MetricData> metricDataList = testMetricExporter.metricDataList; .anySatisfy(metric -> assertion.accept(MetricAssertions.assertThat(metric)));
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);
}
} }
} }

View File

@ -5,26 +5,30 @@
package io.opentelemetry.instrumentation.oshi; package io.opentelemetry.instrumentation.oshi;
import io.opentelemetry.sdk.metrics.data.MetricDataType; import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class ProcessMetricsTest extends AbstractMetricsTest { public class ProcessMetricsTest extends AbstractMetricsTest {
@Test @Test
public void test() throws Exception { public void test() {
ProcessMetrics.registerObservers(); ProcessMetrics.registerObservers();
IntervalMetricReader intervalMetricReader = createIntervalMetricReader();
testMetricExporter.waitForData(); waitAndAssertMetrics(
intervalMetricReader.shutdown(); metric ->
metric
verify( .hasName("runtime.java.memory")
"runtime.java.memory", "bytes", MetricDataType.LONG_GAUGE, /* checkNonZeroValue= */ true); .hasUnit("bytes")
verify( .hasLongGauge()
"runtime.java.cpu_time", .points()
"seconds", .anySatisfy(point -> assertThat(point.getValue()).isPositive()),
MetricDataType.DOUBLE_GAUGE, metric ->
/* checkNonZeroValue= */ true); metric
.hasName("runtime.java.cpu_time")
.hasUnit("seconds")
.hasDoubleGauge()
.points()
.anySatisfy(point -> assertThat(point.getValue()).isPositive()));
} }
} }

View File

@ -5,44 +5,34 @@
package io.opentelemetry.instrumentation.oshi; package io.opentelemetry.instrumentation.oshi;
import io.opentelemetry.sdk.metrics.data.MetricDataType; import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import io.opentelemetry.sdk.metrics.export.IntervalMetricReader;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class SystemMetricsTest extends AbstractMetricsTest { public class SystemMetricsTest extends AbstractMetricsTest {
@Test @Test
public void test() throws Exception { public void test() {
SystemMetrics.registerObservers(); SystemMetrics.registerObservers();
IntervalMetricReader intervalMetricReader = createIntervalMetricReader();
testMetricExporter.waitForData(); waitAndAssertMetrics(
intervalMetricReader.shutdown(); metric ->
metric
verify("system.memory.usage", "By", MetricDataType.LONG_GAUGE, /* checkNonZeroValue= */ true); .hasName("system.memory.usage")
verify( .hasUnit("By")
"system.memory.utilization", .hasLongGauge()
"1", .points()
MetricDataType.DOUBLE_GAUGE, .anySatisfy(point -> assertThat(point.getValue()).isPositive()),
/* checkNonZeroValue= */ true); metric ->
metric
verify("system.network.io", "By", MetricDataType.LONG_GAUGE, /* checkNonZeroValue= */ false); .hasName("system.memory.utilization")
verify( .hasUnit("1")
"system.network.packets", .hasDoubleGauge()
"packets", .points()
MetricDataType.LONG_GAUGE, .anySatisfy(point -> assertThat(point.getValue()).isPositive()),
/* checkNonZeroValue= */ false); metric -> metric.hasName("system.network.io").hasUnit("By").hasLongGauge(),
verify( metric -> metric.hasName("system.network.packets").hasUnit("packets").hasLongGauge(),
"system.network.errors", metric -> metric.hasName("system.network.errors").hasUnit("errors").hasLongGauge(),
"errors", metric -> metric.hasName("system.disk.operations").hasUnit("operations").hasLongGauge());
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);
} }
} }

View File

@ -7,6 +7,8 @@ package io.opentelemetry.javaagent.tooling;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.api.GlobalOpenTelemetry; 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.extension.noopapi.NoopOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config; import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.extension.AgentListener; 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.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.OpenTelemetrySdkAutoConfiguration; import io.opentelemetry.sdk.autoconfigure.OpenTelemetrySdkAutoConfiguration;
import io.opentelemetry.sdk.common.CompletableResultCode; 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.Arrays;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -51,8 +53,14 @@ public class OpenTelemetryInstaller implements AgentListener {
OpenTelemetrySdkAccess.internalSetForceFlush( OpenTelemetrySdkAccess.internalSetForceFlush(
(timeout, unit) -> { (timeout, unit) -> {
CompletableResultCode traceResult = sdk.getSdkTracerProvider().forceFlush(); CompletableResultCode traceResult = sdk.getSdkTracerProvider().forceFlush();
CompletableResultCode flushResult = IntervalMetricReader.forceFlushGlobal(); MeterProvider meterProvider = GlobalMeterProvider.get();
CompletableResultCode.ofAll(Arrays.asList(traceResult, flushResult)) final CompletableResultCode metricsResult;
if (meterProvider instanceof SdkMeterProvider) {
metricsResult = ((SdkMeterProvider) meterProvider).forceFlush();
} else {
metricsResult = CompletableResultCode.ofSuccess();
}
CompletableResultCode.ofAll(Arrays.asList(traceResult, metricsResult))
.join(timeout, unit); .join(timeout, unit);
}); });
} }

View File

@ -26,6 +26,6 @@ public class AgentTestingExporterFactory {
} }
public static boolean forceFlushCalled() { public static boolean forceFlushCalled() {
return AgentTestingSdkCustomizer.spanProcessor.forceFlushCalled; return AgentTestingTracingCustomizer.spanProcessor.forceFlushCalled;
} }
} }

View File

@ -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)));
}
}

View File

@ -6,17 +6,13 @@
package io.opentelemetry.javaagent.testing.exporter; package io.opentelemetry.javaagent.testing.exporter;
import com.google.auto.service.AutoService; 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.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer; 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.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import java.util.Collections;
@AutoService(SdkTracerProviderConfigurer.class) @AutoService(SdkTracerProviderConfigurer.class)
public class AgentTestingSdkCustomizer implements SdkTracerProviderConfigurer { public class AgentTestingTracingCustomizer implements SdkTracerProviderConfigurer {
static final AgentTestingSpanProcessor spanProcessor = static final AgentTestingSpanProcessor spanProcessor =
new AgentTestingSpanProcessor( new AgentTestingSpanProcessor(
@ -29,13 +25,5 @@ public class AgentTestingSdkCustomizer implements SdkTracerProviderConfigurer {
@Override @Override
public void configure(SdkTracerProviderBuilder tracerProviderBuilder, ConfigProperties config) { public void configure(SdkTracerProviderBuilder tracerProviderBuilder, ConfigProperties config) {
tracerProviderBuilder.addSpanProcessor(spanProcessor); 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();
} }
} }