Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.exporter.otlp.internal;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.common.InternalTelemetryVersion;
import java.util.Locale;
import javax.annotation.Nullable;

/**
* Reads the desired SDK internal telemetry version from {@link ConfigProperties}.
*
* <p>This is the same as {@code io.opentelemetry.sdk.autoconfigure.InternalTelemetryConfiguration}.
* Any changes should be reflected there as well.
*/
final class InternalTelemetryConfiguration {

@Nullable
static InternalTelemetryVersion getVersion(ConfigProperties config) {
String version = config.getString("otel.experimental.sdk.telemetry.version");
if (version == null) {
return null;
}
switch (version.toLowerCase(Locale.ROOT)) {
case "legacy":
return InternalTelemetryVersion.LEGACY;
case "latest":
return InternalTelemetryVersion.LATEST;
default:
throw new ConfigurationException("Invalid sdk telemetry version: " + version);
}
}

private InternalTelemetryConfiguration() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.opentelemetry.exporter.internal.ExporterBuilderUtil;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.common.InternalTelemetryVersion;
import io.opentelemetry.sdk.common.export.MemoryMode;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import java.io.File;
Expand Down Expand Up @@ -62,7 +63,8 @@ public static void configureOtlpExporterBuilder(
Consumer<byte[]> setTrustedCertificates,
BiConsumer<byte[], byte[]> setClientTls,
Consumer<RetryPolicy> setRetryPolicy,
Consumer<MemoryMode> setMemoryMode) {
Consumer<MemoryMode> setMemoryMode,
Consumer<InternalTelemetryVersion> setInternalTelemetryVersion) {
setComponentLoader.accept(config.getComponentLoader());

String protocol = getOtlpProtocol(dataType, config);
Expand Down Expand Up @@ -107,6 +109,11 @@ public static void configureOtlpExporterBuilder(
setTimeout.accept(timeout);
}

InternalTelemetryVersion telemetryVersion = InternalTelemetryConfiguration.getVersion(config);
if (telemetryVersion != null) {
setInternalTelemetryVersion.accept(telemetryVersion);
}

String certificatePath =
config.getString(
determinePropertyByType(config, "otel.exporter.otlp", dataType, "certificate"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public LogRecordExporter createExporter(ConfigProperties config) {
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
builder::setMemoryMode,
builder::setInternalTelemetryVersion);
builder.setMeterProvider(meterProviderRef::get);

return builder.build();
Expand All @@ -71,7 +72,8 @@ public LogRecordExporter createExporter(ConfigProperties config) {
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
builder::setMemoryMode,
builder::setInternalTelemetryVersion);
builder.setMeterProvider(meterProviderRef::get);

return builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public MetricExporter createExporter(ConfigProperties config) {
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
builder::setMemoryMode,
builder::setInternalTelemetryVersion);
ExporterBuilderUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation(
Expand All @@ -76,7 +77,8 @@ public MetricExporter createExporter(ConfigProperties config) {
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
builder::setMemoryMode,
builder::setInternalTelemetryVersion);
ExporterBuilderUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public SpanExporter createExporter(ConfigProperties config) {
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
builder::setMemoryMode,
builder::setInternalTelemetryVersion);
builder.setMeterProvider(meterProviderRef::get);

return builder.build();
Expand All @@ -70,7 +71,8 @@ public SpanExporter createExporter(ConfigProperties config) {
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
builder::setMemoryMode,
builder::setInternalTelemetryVersion);
builder.setMeterProvider(meterProviderRef::get);

return builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ private static String configureEndpoint(String dataType, Map<String, String> pro
value -> {},
(value1, value2) -> {},
value -> {},
value -> {},
value -> {});

return endpoint.get();
Expand Down
1 change: 1 addition & 0 deletions sdk-extensions/autoconfigure/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ testing {
environment("OTEL_EXPORTER_OTLP_TIMEOUT", "5000")
environment("OTEL_TEST_CONFIGURED", "true")
environment("OTEL_TEST_WRAPPED", "1")
environment("OTEL_EXPERIMENTAL_SDK_TELEMETRY_VERSION", "latest")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.autoconfigure;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.common.InternalTelemetryVersion;
import java.util.Locale;
import javax.annotation.Nullable;

/**
* Reads the desired SDK internal telemetry version from {@link ConfigProperties}.
*
* <p>This is the same as {@code
* io.opentelemetry.exporter.otlp.internal.InternalTelemetryConfiguration}. Any changes should be
* reflected there as well.
*/
final class InternalTelemetryConfiguration {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too bad we need two copies of this code. Maybe each can have a note in the javadoc referencing the other to increase the chance of keeping changes in sync?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah added the references


@Nullable
static InternalTelemetryVersion getVersion(ConfigProperties config) {
String version = config.getString("otel.experimental.sdk.telemetry.version");
if (version == null) {
return null;
}
switch (version.toLowerCase(Locale.ROOT)) {
case "legacy":
return InternalTelemetryVersion.LEGACY;
case "latest":
return InternalTelemetryVersion.LATEST;
default:
throw new ConfigurationException("Invalid sdk telemetry version: " + version);
}
}

private InternalTelemetryConfiguration() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.common.InternalTelemetryVersion;
import io.opentelemetry.sdk.logs.LogLimits;
import io.opentelemetry.sdk.logs.LogLimitsBuilder;
import io.opentelemetry.sdk.logs.LogRecordProcessor;
Expand Down Expand Up @@ -119,6 +120,11 @@ static BatchLogRecordProcessor configureBatchLogRecordProcessor(
builder.setExporterTimeout(timeout);
}

InternalTelemetryVersion telemetryVersion = InternalTelemetryConfiguration.getVersion(config);
if (telemetryVersion != null) {
builder.setInternalTelemetryVersion(telemetryVersion);
}

return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider;
import io.opentelemetry.sdk.common.InternalTelemetryVersion;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;
import io.opentelemetry.sdk.trace.SpanLimitsBuilder;
Expand Down Expand Up @@ -125,6 +126,11 @@ static BatchSpanProcessor configureBatchSpanProcessor(
builder.setExporterTimeout(timeout);
}

InternalTelemetryVersion telemetryVersion = InternalTelemetryConfiguration.getVersion(config);
if (telemetryVersion != null) {
builder.setInternalTelemetryVersion(telemetryVersion);
}

return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@
import io.opentelemetry.proto.common.v1.AnyValue;
import io.opentelemetry.proto.common.v1.KeyValue;
import io.opentelemetry.proto.metrics.v1.Metric;
import io.opentelemetry.proto.metrics.v1.ScopeMetrics;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -220,6 +222,8 @@ void configures() throws Exception {
assertHasKeyValue(span.getAttributesList(), "cat", "meow");
assertHasKeyValue(span.getAttributesList(), "extra-key", "extra-value");

// Flush again to get metric exporter metrics.
openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS);
// await on assertions since metrics may come in different order for BatchSpanProcessor,
// exporter, or the ones we created in the test.
await()
Expand Down Expand Up @@ -252,19 +256,62 @@ void configures() throws Exception {
})
// This verifies that AutoConfigureListener was invoked and the OTLP
// span / log exporters received the autoconfigured OpenTelemetrySdk
// instance
// instance as well as setting telemetry version.
.anySatisfy(
scopeMetrics -> {
assertThat(scopeMetrics.getScope().getName())
.isEqualTo("io.opentelemetry.exporters.otlp-grpc");
assertThat(scopeMetrics.getMetricsList())
.satisfiesExactlyInAnyOrder(
metric ->
assertThat(metric.getName())
.isEqualTo("otlp.exporter.seen"),
metric ->
assertThat(metric.getName())
.isEqualTo("otlp.exporter.exported"));
.isEqualTo(
"io.opentelemetry.exporters.otlp_grpc_metric_exporter");
assertMetricNames(
scopeMetrics,
"otel.sdk.exporter.metric_data_point.inflight",
"otel.sdk.exporter.operation.duration",
"otel.sdk.exporter.metric_data_point.exported");
})
.anySatisfy(
scopeMetrics -> {
assertThat(scopeMetrics.getScope().getName())
.isEqualTo(
"io.opentelemetry.exporters.otlp_grpc_log_exporter");
assertMetricNames(
scopeMetrics,
"otel.sdk.exporter.log.inflight",
"otel.sdk.exporter.operation.duration",
"otel.sdk.exporter.log.exported");
})
.anySatisfy(
scopeMetrics -> {
assertThat(scopeMetrics.getScope().getName())
.isEqualTo(
"io.opentelemetry.exporters.otlp_grpc_span_exporter");
assertMetricNames(
scopeMetrics,
"otel.sdk.exporter.span.inflight",
"otel.sdk.exporter.operation.duration",
"otel.sdk.exporter.span.exported");
})
.anySatisfy(
scopeMetrics -> {
assertThat(scopeMetrics.getScope().getName())
.isEqualTo("io.opentelemetry.sdk.logs");
assertMetricNames(
scopeMetrics,
"otel.sdk.log.created",
"otel.sdk.processor.log.processed",
"otel.sdk.processor.log.queue.capacity",
"otel.sdk.processor.log.queue.size");
})
Comment on lines 293 to 303
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#nit if we're not going to assert on the attributes, maybe a more terse assert syntax

Suggested change
.anySatisfy(
scopeMetrics -> {
assertThat(scopeMetrics.getScope().getName())
.isEqualTo("io.opentelemetry.sdk.logs");
assertThat(scopeMetrics.getMetricsList())
.satisfiesExactlyInAnyOrder(
metric ->
assertThat(metric.getName())
.isEqualTo("otel.sdk.log.created"),
metric ->
assertThat(metric.getName())
.isEqualTo("otel.sdk.processor.log.processed"),
metric ->
assertThat(metric.getName())
.isEqualTo(
"otel.sdk.processor.log.queue.capacity"),
metric ->
assertThat(metric.getName())
.isEqualTo("otel.sdk.processor.log.queue.size"));
})
.anySatisfy(
scopeMetrics -> {
assertThat(scopeMetrics.getScope().getName())
.isEqualTo("io.opentelemetry.sdk.logs");
assertThat(
scopeMetrics.getMetricsList().stream()
.map(Metric::getName)
.collect(Collectors.toSet()))
.isEqualTo(
new HashSet<>(
Arrays.asList(
"otel.sdk.log.created",
"otel.sdk.processor.log.processed",
"otel.sdk.processor.log.queue.capacity",
"otel.sdk.processor.log.queue.size")));

Or maybe even something like maintaining a Map<String, Set<String>>, with keys of each expected scope and values being the set of metric names expected for that scope.

Not critical, but this test does get pretty long with so many verbose asserts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call - I added a helper too, it seems to be both much smaller and more readable

.anySatisfy(
scopeMetrics -> {
assertThat(scopeMetrics.getScope().getName())
.isEqualTo("io.opentelemetry.sdk.trace");
assertMetricNames(
scopeMetrics,
"otel.sdk.span.live",
"otel.sdk.span.started",
"otel.sdk.processor.span.processed",
"otel.sdk.processor.span.queue.capacity",
"otel.sdk.processor.span.queue.size");
});
});
});
Expand Down Expand Up @@ -318,6 +365,12 @@ private static void assertHasKeyValue(List<KeyValue> keyValues, String key, Stri
.build());
}

private static void assertMetricNames(ScopeMetrics scopeMetrics, String... names) {
assertThat(
scopeMetrics.getMetricsList().stream().map(Metric::getName).collect(Collectors.toSet()))
.containsExactlyInAnyOrder(names);
}

private static List<KeyValue> getFirstDataPointLabels(Metric metric) {
switch (metric.getDataCase()) {
case GAUGE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ public CompletableResultCode export(Collection<MetricData> metrics) {
|| metricData
.getInstrumentationScopeInfo()
.getName()
.startsWith("io.opentelemetry.exporters"))
.startsWith("io.opentelemetry.exporters")
|| metricData
.getInstrumentationScopeInfo()
.getName()
.startsWith("io.opentelemetry.sdk"))
.collect(Collectors.toList());
return delegate.export(filtered);
}
Expand Down
Loading