diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 33f30d01306..03b1ea0e737 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -9,6 +9,7 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.exporter.internal.okhttp.OkHttpExporterBuilder; +import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; @@ -38,6 +39,7 @@ public final class OtlpHttpMetricExporterBuilder { OtlpHttpMetricExporterBuilder() { delegate = new OkHttpExporterBuilder<>("otlp", "metric", DEFAULT_ENDPOINT); + OtlpUserAgent.addUserAgentHeader(delegate::addHeader); } /** diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index cdfb34f0e72..0f268cbb83e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.okhttp.OkHttpExporterBuilder; +import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -27,6 +28,7 @@ public final class OtlpHttpSpanExporterBuilder { OtlpHttpSpanExporterBuilder() { delegate = new OkHttpExporterBuilder<>("otlp", "span", DEFAULT_ENDPOINT); + OtlpUserAgent.addUserAgentHeader(delegate::addHeader); } /** diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 99998b37ce0..d87a79c76ad 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -11,6 +11,7 @@ import io.grpc.ManagedChannel; import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; +import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; @@ -56,12 +57,17 @@ public final class OtlpGrpcMetricExporterBuilder { DEFAULT_ENDPOINT, () -> MarshalerMetricsServiceGrpc::newFutureStub, GRPC_ENDPOINT_PATH); + OtlpUserAgent.addUserAgentHeader(delegate::addHeader); } /** * Sets the managed chanel to use when communicating with the backend. Takes precedence over * {@link #setEndpoint(String)} if both are called. * + *
Note: calling this overrides the spec compliant {@code User-Agent} header. To ensure spec + * compliance, set {@link io.grpc.ManagedChannelBuilder#userAgent(String)} to {@link + * OtlpUserAgent#getUserAgent()} when building the channel. + * * @param channel the channel to use * @return this builder's instance * @deprecated Use {@link #setEndpoint(String)}. If you have a use case not satisfied by the diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 5db960af3fb..b8e376326a8 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -12,6 +12,7 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; +import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import java.net.URI; import java.time.Duration; @@ -41,12 +42,17 @@ public final class OtlpGrpcSpanExporterBuilder { DEFAULT_ENDPOINT, () -> MarshalerTraceServiceGrpc::newFutureStub, GRPC_ENDPOINT_PATH); + OtlpUserAgent.addUserAgentHeader(delegate::addHeader); } /** * Sets the managed chanel to use when communicating with the backend. Takes precedence over * {@link #setEndpoint(String)} if both are called. * + *
Note: calling this overrides the spec compliant {@code User-Agent} header. To ensure spec
+ * compliance, set {@link io.grpc.ManagedChannelBuilder#userAgent(String)} to {@link
+ * OtlpUserAgent#getUserAgent()} when building the channel.
+ *
* @param channel the channel to use
* @return this builder's instance
* @deprecated Use {@link #setEndpoint(String)}. If you have a use case not satisfied by the
diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts
index 92bbc4ae27d..b91716e7c17 100644
--- a/exporters/otlp/common/build.gradle.kts
+++ b/exporters/otlp/common/build.gradle.kts
@@ -9,7 +9,7 @@ plugins {
}
description = "OpenTelemetry Protocol Exporter"
-otelJava.moduleName.set("io.opentelemetry.exporter.otlp.internal")
+otelJava.moduleName.set("io.opentelemetry.exporter.internal.otlp")
val versions: Map Note: calling this overrides the spec compliant {@code User-Agent} header. To ensure spec
+ * compliance, set {@link io.grpc.ManagedChannelBuilder#userAgent(String)} to {@link
+ * OtlpUserAgent#getUserAgent()} when building the channel.
+ *
* @param channel the channel to use
* @return this builder's instance
* @deprecated Use {@link #setEndpoint(String)}. If you have a use case not satisfied by the
diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java
index a775bf77f4a..77ec4f65cd6 100644
--- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java
+++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java
@@ -216,6 +216,14 @@ void export() {
assertThat(exporter.export(telemetry).join(10, TimeUnit.SECONDS).isSuccess()).isTrue();
List expectedResourceTelemetry = toProto(telemetry);
assertThat(exportedResourceTelemetry).containsExactlyElementsOf(expectedResourceTelemetry);
+
+ // Assert request contains OTLP spec compliant User-Agent header
+ assertThat(httpRequests)
+ .singleElement()
+ .satisfies(
+ req -> {
+ assertThat(req.headers().get("User-Agent")).matches("OTel OTLP Exporter Java/1\\..*");
+ });
}
@Test
diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java
index 1402819ca7c..8a00a522395 100644
--- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java
+++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java
@@ -10,6 +10,7 @@
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.opentelemetry.exporter.internal.grpc.ManagedChannelUtil;
+import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent;
import io.opentelemetry.exporter.internal.retry.RetryPolicy;
import io.opentelemetry.sdk.common.CompletableResultCode;
import java.net.URI;
@@ -51,6 +52,10 @@ public TelemetryExporterBuilder