From f63a92105476cc3141c546f90a66be20f74f9748 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Wed, 3 Jun 2026 08:57:26 +0530 Subject: [PATCH 1/8] Enforce OTLP request size limits --- .../opentelemetry-exporter-otlp.txt | 21 ++++- .../OtlpHttpLogRecordExporterBuilder.java | 11 +++ .../OtlpHttpMetricExporterBuilder.java | 11 +++ .../trace/OtlpHttpSpanExporterBuilder.java | 11 +++ .../exporter/otlp/internal/GrpcExporter.java | 78 +++++++++++++++++- .../otlp/internal/GrpcExporterBuilder.java | 12 ++- .../exporter/otlp/internal/HttpExporter.java | 75 +++++++++++++++++ .../otlp/internal/HttpExporterBuilder.java | 12 ++- .../OtlpGrpcLogRecordExporterBuilder.java | 11 +++ .../OtlpGrpcMetricExporterBuilder.java | 11 +++ .../trace/OtlpGrpcSpanExporterBuilder.java | 11 +++ .../internal/GrpcExporterBuilderTest.java | 7 ++ .../otlp/internal/GrpcExporterTest.java | 39 +++++++++ .../internal/HttpExporterBuilderTest.java | 7 ++ .../otlp/internal/HttpExporterTest.java | 80 +++++++++++++++++++ .../OtlpGrpcProfilesExporterBuilder.java | 11 +++ .../AbstractGrpcTelemetryExporterTest.java | 24 ++++++ .../AbstractHttpTelemetryExporterTest.java | 21 +++++ .../GrpcLogRecordExporterBuilderWrapper.java | 6 ++ .../GrpcMetricExporterBuilderWrapper.java | 6 ++ .../GrpcProfilesExporterBuilderWrapper.java | 6 ++ .../GrpcSpanExporterBuilderWrapper.java | 6 ++ .../HttpLogRecordExporterBuilderWrapper.java | 6 ++ .../HttpMetricExporterBuilderWrapper.java | 6 ++ .../HttpSpanExporterBuilderWrapper.java | 6 ++ ...anagedChannelTelemetryExporterBuilder.java | 6 ++ .../internal/TelemetryExporterBuilder.java | 8 ++ 27 files changed, 504 insertions(+), 5 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 9c08edf8a45..07455b4b491 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,19 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.65.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.64.0.jar -No changes. \ No newline at end of file +Comparing source compatibility of opentelemetry-exporter-otlp-1.65.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.63.0.jar +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMaxRequestBodySize(long) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setMaxRequestBodySize(long) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMaxRequestBodySize(long) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize(long) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setMaxRequestMessageSize(long) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMaxRequestMessageSize(long) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 9918de27b85..4c9142d76aa 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -37,6 +37,7 @@ public final class OtlpHttpLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/logs"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; + private static final long DEFAULT_MAX_REQUEST_BODY_SIZE = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; @@ -44,6 +45,7 @@ public final class OtlpHttpLogRecordExporterBuilder { OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; + this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -98,6 +100,15 @@ public OtlpHttpLogRecordExporterBuilder setConnectTimeout(Duration timeout) { return this; } + /** + * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. + */ + public OtlpHttpLogRecordExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + checkArgument(maxRequestBodySize >= 0, "maxRequestBodySize must be non-negative"); + delegate.setMaxRequestBodySize(maxRequestBodySize); + return this; + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT}. The * endpoint must start with either http:// or https://, and include the full HTTP path. 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 d408c5543f5..fed5a29a418 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 @@ -46,6 +46,7 @@ public final class OtlpHttpMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; + private static final long DEFAULT_MAX_REQUEST_BODY_SIZE = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; @@ -62,6 +63,7 @@ public final class OtlpHttpMetricExporterBuilder { this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; this.memoryMode = memoryMode; + this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -118,6 +120,15 @@ public OtlpHttpMetricExporterBuilder setConnectTimeout(Duration timeout) { return this; } + /** + * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. + */ + public OtlpHttpMetricExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + checkArgument(maxRequestBodySize >= 0, "maxRequestBodySize must be non-negative"); + delegate.setMaxRequestBodySize(maxRequestBodySize); + return this; + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT}. The * endpoint must start with either http:// or https://, and include the full HTTP path. 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 11f3e2d63a9..8c66d7acac6 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 @@ -37,6 +37,7 @@ public final class OtlpHttpSpanExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/traces"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; + private static final long DEFAULT_MAX_REQUEST_BODY_SIZE = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; @@ -44,6 +45,7 @@ public final class OtlpHttpSpanExporterBuilder { OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; + this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -98,6 +100,15 @@ public OtlpHttpSpanExporterBuilder setConnectTimeout(Duration timeout) { return this; } + /** + * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. + */ + public OtlpHttpSpanExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + checkArgument(maxRequestBodySize >= 0, "maxRequestBodySize must be non-negative"); + delegate.setMaxRequestBodySize(maxRequestBodySize); + return this; + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT}. The * endpoint must start with either http:// or https://, and include the full HTTP path. diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java index 62d5695baf0..8e0de5369d2 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java @@ -14,8 +14,11 @@ import io.opentelemetry.sdk.common.export.GrpcResponse; import io.opentelemetry.sdk.common.export.GrpcSender; import io.opentelemetry.sdk.common.export.GrpcStatusCode; +import io.opentelemetry.sdk.common.export.MessageWriter; import io.opentelemetry.sdk.common.internal.StandardComponentId; import io.opentelemetry.sdk.common.internal.ThrottlingLogger; +import java.io.IOException; +import java.io.OutputStream; import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -42,6 +45,7 @@ public final class GrpcExporter { private final String type; private final GrpcSender grpcSender; private final ExporterInstrumentation exporterMetrics; + private final long maxRequestMessageSize; public GrpcExporter( GrpcSender grpcSender, @@ -49,11 +53,28 @@ public GrpcExporter( StandardComponentId componentId, Supplier meterProviderSupplier, URI endpoint) { + this( + grpcSender, + internalTelemetryVersion, + componentId, + meterProviderSupplier, + endpoint, + Long.MAX_VALUE); + } + + public GrpcExporter( + GrpcSender grpcSender, + InternalTelemetryVersion internalTelemetryVersion, + StandardComponentId componentId, + Supplier meterProviderSupplier, + URI endpoint, + long maxRequestMessageSize) { this.type = componentId.getStandardType().signal().logFriendlyName(); this.grpcSender = grpcSender; this.exporterMetrics = new ExporterInstrumentation( internalTelemetryVersion, meterProviderSupplier, componentId, endpoint); + this.maxRequestMessageSize = maxRequestMessageSize; } public CompletableResultCode export(Marshaler exportRequest, int numItems) { @@ -65,15 +86,70 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { exporterMetrics.startRecordingExport(numItems); CompletableResultCode result = new CompletableResultCode(); + MessageWriter messageWriter = exportRequest.toBinaryMessageWriter(); + + long requestMessageSize = getRequestMessageSize(messageWriter); + if (requestMessageSize > maxRequestMessageSize) { + return failRequestTooLarge(result, metricRecording, requestMessageSize); + } grpcSender.send( - exportRequest.toBinaryMessageWriter(), + messageWriter, grpcResponse -> onResponse(result, metricRecording, grpcResponse), throwable -> onError(result, metricRecording, throwable)); return result; } + private CompletableResultCode failRequestTooLarge( + CompletableResultCode result, + ExporterInstrumentation.Recording metricRecording, + long requestMessageSize) { + IOException exception = + new IOException( + "OTLP gRPC request message size " + + requestMessageSize + + " exceeded limit of " + + maxRequestMessageSize + + " bytes"); + metricRecording.finishFailed(exception); + logger.log(Level.WARNING, exception.getMessage()); + result.failExceptionally(FailedExportException.grpcFailedExceptionally(exception)); + return result; + } + + private static long getRequestMessageSize(MessageWriter messageWriter) { + int contentLength = messageWriter.getContentLength(); + if (contentLength >= 0) { + return contentLength; + } + try { + CountingOutputStream countingOutputStream = new CountingOutputStream(); + messageWriter.writeMessage(countingOutputStream); + return countingOutputStream.getCount(); + } catch (IOException e) { + return Long.MAX_VALUE; + } + } + + private static final class CountingOutputStream extends OutputStream { + private long count; + + @Override + public void write(int b) { + count++; + } + + @Override + public void write(byte[] b, int off, int len) { + count += len; + } + + private long getCount() { + return count; + } + } + private void onResponse( CompletableResultCode result, ExporterInstrumentation.Recording metricRecording, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java index ad5b9cbd0d1..9ef5aec1a1a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java @@ -47,6 +47,7 @@ public class GrpcExporterBuilder { public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; + public static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = Long.MAX_VALUE; private static final Logger LOGGER = Logger.getLogger(GrpcExporterBuilder.class.getName()); @@ -68,6 +69,7 @@ public class GrpcExporterBuilder { private ComponentLoader componentLoader = ComponentLoader.forClassLoader(GrpcExporterBuilder.class.getClassLoader()); @Nullable private ExecutorService executorService; + private long maxRequestMessageSize = DEFAULT_MAX_REQUEST_MESSAGE_SIZE; // Use Object type since gRPC may not be on the classpath. @Nullable private Object grpcChannel; @@ -170,6 +172,11 @@ public GrpcExporterBuilder setExecutorService(ExecutorService executorService) { return this; } + public GrpcExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + this.maxRequestMessageSize = maxRequestMessageSize; + return this; + } + @SuppressWarnings("BuilderReturnThis") public GrpcExporterBuilder copy() { GrpcExporterBuilder copy = @@ -189,6 +196,7 @@ public GrpcExporterBuilder copy() { copy.internalTelemetryVersion = internalTelemetryVersion; copy.grpcChannel = grpcChannel; copy.componentLoader = componentLoader; + copy.maxRequestMessageSize = maxRequestMessageSize; return copy; } @@ -240,7 +248,8 @@ public GrpcExporter build() { internalTelemetryVersion, ComponentId.generateLazy(exporterType), meterProviderSupplier, - endpoint); + endpoint, + maxRequestMessageSize); } public String toString(boolean includePrefixAndSuffix) { @@ -272,6 +281,7 @@ public String toString(boolean includePrefixAndSuffix) { if (executorService != null) { joiner.add("executorService=" + executorService); } + joiner.add("maxRequestMessageSize=" + maxRequestMessageSize); joiner.add("exporterType=" + exporterType.toString()); joiner.add("internalTelemetrySchemaVersion=" + internalTelemetryVersion); // Note: omit tlsConfigHelper because we can't log the configuration in any readable way diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java index ea2b108f20e..04b3fd349c2 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.common.internal.StandardComponentId; import io.opentelemetry.sdk.common.internal.ThrottlingLogger; import java.io.IOException; +import java.io.OutputStream; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicBoolean; @@ -45,6 +46,7 @@ public final class HttpExporter { private final HttpSender httpSender; private final ExporterInstrumentation exporterMetrics; private final boolean exportAsJson; + private final long maxRequestBodySize; public HttpExporter( StandardComponentId componentId, @@ -53,12 +55,31 @@ public HttpExporter( InternalTelemetryVersion internalTelemetryVersion, URI endpoint, boolean exportAsJson) { + this( + componentId, + httpSender, + meterProviderSupplier, + internalTelemetryVersion, + endpoint, + exportAsJson, + Long.MAX_VALUE); + } + + public HttpExporter( + StandardComponentId componentId, + HttpSender httpSender, + Supplier meterProviderSupplier, + InternalTelemetryVersion internalTelemetryVersion, + URI endpoint, + boolean exportAsJson, + long maxRequestBodySize) { this.type = componentId.getStandardType().signal().logFriendlyName(); this.httpSender = httpSender; this.exporterMetrics = new ExporterInstrumentation( internalTelemetryVersion, meterProviderSupplier, componentId, endpoint); this.exportAsJson = exportAsJson; + this.maxRequestBodySize = maxRequestBodySize; } public CompletableResultCode export(Marshaler exportRequest, int numItems) { @@ -73,6 +94,11 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { MessageWriter messageWriter = exportAsJson ? exportRequest.toJsonMessageWriter() : exportRequest.toBinaryMessageWriter(); + long requestBodySize = getRequestBodySize(messageWriter); + if (requestBodySize > maxRequestBodySize) { + return failRequestTooLarge(result, metricRecording, requestBodySize); + } + httpSender.send( messageWriter, httpResponse -> onResponse(result, metricRecording, httpResponse), @@ -81,6 +107,55 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { return result; } + private CompletableResultCode failRequestTooLarge( + CompletableResultCode result, + ExporterInstrumentation.Recording metricRecording, + long requestBodySize) { + IOException exception = + new IOException( + "OTLP HTTP request body size " + + requestBodySize + + " exceeded limit of " + + maxRequestBodySize + + " bytes"); + metricRecording.finishFailed(exception); + logger.log(Level.WARNING, exception.getMessage()); + result.failExceptionally(FailedExportException.httpFailedExceptionally(exception)); + return result; + } + + private static long getRequestBodySize(MessageWriter messageWriter) { + int contentLength = messageWriter.getContentLength(); + if (contentLength >= 0) { + return contentLength; + } + try { + CountingOutputStream countingOutputStream = new CountingOutputStream(); + messageWriter.writeMessage(countingOutputStream); + return countingOutputStream.getCount(); + } catch (IOException e) { + return Long.MAX_VALUE; + } + } + + private static final class CountingOutputStream extends OutputStream { + private long count; + + @Override + public void write(int b) { + count++; + } + + @Override + public void write(byte[] b, int off, int len) { + count += len; + } + + private long getCount() { + return count; + } + } + private void onResponse( CompletableResultCode result, ExporterInstrumentation.Recording metricRecording, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java index 98a5a2e2b85..d1eb5866481 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java @@ -46,6 +46,7 @@ public final class HttpExporterBuilder { public static final long DEFAULT_TIMEOUT_SECS = 10; public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; + public static final long DEFAULT_MAX_REQUEST_BODY_SIZE = Long.MAX_VALUE; private static final Logger LOGGER = Logger.getLogger(HttpExporterBuilder.class.getName()); @@ -69,6 +70,7 @@ public final class HttpExporterBuilder { private ComponentLoader componentLoader = ComponentLoader.forClassLoader(HttpExporterBuilder.class.getClassLoader()); @Nullable private ExecutorService executorService; + private long maxRequestBodySize = DEFAULT_MAX_REQUEST_BODY_SIZE; public HttpExporterBuilder( StandardComponentId.ExporterType exporterType, String defaultEndpoint) { @@ -167,6 +169,11 @@ public HttpExporterBuilder setExecutorService(ExecutorService executorService) { return this; } + public HttpExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + this.maxRequestBodySize = maxRequestBodySize; + return this; + } + public HttpExporterBuilder exportAsJson() { this.exportAsJson = true; exporterType = mapToJsonTypeIfPossible(exporterType); @@ -204,6 +211,7 @@ public HttpExporterBuilder copy() { copy.internalTelemetryVersion = internalTelemetryVersion; copy.proxyOptions = proxyOptions; copy.componentLoader = componentLoader; + copy.maxRequestBodySize = maxRequestBodySize; return copy; } @@ -256,7 +264,8 @@ public HttpExporter build() { meterProviderSupplier, internalTelemetryVersion, endpoint, - exportAsJson); + exportAsJson, + maxRequestBodySize); } public String toString(boolean includePrefixAndSuffix) { @@ -286,6 +295,7 @@ public String toString(boolean includePrefixAndSuffix) { if (executorService != null) { joiner.add("executorService=" + executorService); } + joiner.add("maxRequestBodySize=" + maxRequestBodySize); joiner.add("exporterType=" + exporterType); joiner.add("internalTelemetrySchemaVersion=" + internalTelemetryVersion); // Note: omit tlsConfigHelper because we can't log the configuration in any readable way diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index e111962d83e..8a3d174d8e6 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -43,6 +43,7 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -51,6 +52,7 @@ public final class OtlpGrpcLogRecordExporterBuilder { OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -127,6 +129,15 @@ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(Duration timeout) { return this; } + /** + * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. + */ + public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. The * endpoint must start with either http:// or https://. 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 73e0861e6cd..9875062d895 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 @@ -51,6 +51,7 @@ public final class OtlpGrpcMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -68,6 +69,7 @@ public final class OtlpGrpcMetricExporterBuilder { this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; this.memoryMode = memoryMode; + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -146,6 +148,15 @@ public OtlpGrpcMetricExporterBuilder setConnectTimeout(Duration timeout) { return this; } + /** + * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. + */ + public OtlpGrpcMetricExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. The * endpoint must start with either http:// or https://. 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 edceb408381..e6c6b119633 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 @@ -40,6 +40,7 @@ public final class OtlpGrpcSpanExporterBuilder { private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -48,6 +49,7 @@ public final class OtlpGrpcSpanExporterBuilder { OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -124,6 +126,15 @@ public OtlpGrpcSpanExporterBuilder setConnectTimeout(Duration timeout) { return this; } + /** + * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. + */ + public OtlpGrpcSpanExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. The * endpoint must start with either http:// or https://. diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilderTest.java index 70db9cd2639..95f0f1c83e1 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilderTest.java @@ -94,4 +94,11 @@ void compressionString_usesServiceClassLoader() { builder.setCompression("none"); assertThat(builder).extracting("compressor").isNull(); } + + @Test + void maxRequestMessageSize() { + builder.setMaxRequestMessageSize(1234); + + assertThat(builder).extracting("maxRequestMessageSize").isEqualTo(1234L); + } } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java index a618b8574c8..95698f19856 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java @@ -9,11 +9,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.verifyNoInteractions; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InternalTelemetryVersion; +import io.opentelemetry.sdk.common.export.MessageWriter; import io.opentelemetry.sdk.common.export.GrpcResponse; import io.opentelemetry.sdk.common.export.GrpcSender; import io.opentelemetry.sdk.common.export.GrpcStatusCode; @@ -25,6 +27,9 @@ import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.io.IOException; import java.net.URI; +import java.io.OutputStream; +import java.time.Duration; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import javax.annotation.Nullable; import org.junit.jupiter.params.ParameterizedTest; @@ -206,6 +211,40 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { } } + @Test + @SuppressLogger(GrpcExporter.class) + void export_requestMessageTooLargeFailsBeforeSend() { + GrpcSender mockSender = Mockito.mock(GrpcSender.class); + GrpcExporter exporter = + new GrpcExporter( + mockSender, + InternalTelemetryVersion.LATEST, + ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), + SdkMeterProvider::noop, + URI.create("http://testing:1234"), + 1); + + Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter messageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) throws IOException {} + + @Override + public int getContentLength() { + return 2; + } + }; + Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(messageWriter); + + io.opentelemetry.sdk.common.CompletableResultCode result = exporter.export(mockMarshaller, 1); + + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + assertThat(result.getFailureThrowable()) + .hasMessageContaining("OTLP gRPC request message size 2 exceeded limit of 1 bytes"); + verifyNoInteractions(mockSender); + } + private static GrpcResponse grpcResponse(GrpcStatusCode statusCode) { return new GrpcResponse() { @Override diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilderTest.java index 4cbfc023be2..8e016ed5aa1 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilderTest.java @@ -89,4 +89,11 @@ void compressionString_usesServiceClassLoader() { builder.setCompression("none"); assertThat(builder).extracting("compressor").isNull(); } + + @Test + void maxRequestBodySize() { + builder.setMaxRequestBodySize(1234); + + assertThat(builder).extracting("maxRequestBodySize").isEqualTo(1234L); + } } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java index a88df7affa9..bd58e1c6c94 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java @@ -8,6 +8,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.verifyNoInteractions; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.common.Attributes; @@ -15,6 +16,7 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InternalTelemetryVersion; +import io.opentelemetry.sdk.common.export.MessageWriter; import io.opentelemetry.sdk.common.export.HttpResponse; import io.opentelemetry.sdk.common.export.HttpSender; import io.opentelemetry.sdk.common.internal.ComponentId; @@ -23,6 +25,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.io.IOException; +import java.io.OutputStream; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.concurrent.TimeUnit; @@ -211,6 +214,7 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { void export_httpJsonErrorBodyUsesBodyTextWithoutGrpcParseWarning() { HttpSender mockSender = Mockito.mock(HttpSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + HttpExporter exporter = new HttpExporter( ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER), @@ -239,6 +243,44 @@ void export_httpJsonErrorBodyUsesBodyTextWithoutGrpcParseWarning() { logs.assertDoesNotContain("Unable to parse response body"); } + @Test + @SuppressLogger(HttpExporter.class) + void export_requestBodyTooLargeFailsBeforeSend() { + HttpSender mockSender = Mockito.mock(HttpSender.class); + HttpExporter exporter = + new HttpExporter( + ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER), + mockSender, + MeterProvider::noop, + InternalTelemetryVersion.LATEST, + URI.create("http://testing:1234"), + false, + 1); + + Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter messageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) throws IOException { + output.write(new byte[] {1, 2}); + } + + @Override + public int getContentLength() { + return 2; + } + }; + Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(messageWriter); + + io.opentelemetry.sdk.common.CompletableResultCode result = exporter.export(mockMarshaller, 1); + + org.assertj.core.api.Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()) + .isFalse(); + org.assertj.core.api.Assertions.assertThat(result.getFailureThrowable()) + .hasMessageContaining("OTLP HTTP request body size 2 exceeded limit of 1 bytes"); + verifyNoInteractions(mockSender); + } + @Test @SuppressLogger(HttpExporter.class) void export_nullErrorBodyUsesMissingBodyMessage() { @@ -298,6 +340,44 @@ void export_whitespaceErrorBodyFallsBackToStatusMessage() { logs.assertDoesNotContain("Response body:"); } + @Test + @SuppressLogger(HttpExporter.class) + void export_unknownRequestBodyTooLargeFailsBeforeSend() { + HttpSender mockSender = Mockito.mock(HttpSender.class); + HttpExporter exporter = + new HttpExporter( + ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER), + mockSender, + SdkMeterProvider::noop, + InternalTelemetryVersion.LATEST, + URI.create("http://testing:1234"), + true, + 1); + + Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter messageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) throws IOException { + output.write(new byte[] {1, 2}); + } + + @Override + public int getContentLength() { + return -1; + } + }; + Mockito.when(mockMarshaller.toJsonMessageWriter()).thenReturn(messageWriter); + + io.opentelemetry.sdk.common.CompletableResultCode result = exporter.export(mockMarshaller, 1); + + org.assertj.core.api.Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()) + .isFalse(); + org.assertj.core.api.Assertions.assertThat(result.getFailureThrowable()) + .hasMessageContaining("OTLP HTTP request body size 2 exceeded limit of 1 bytes"); + verifyNoInteractions(mockSender); + } + private static class FakeHttpResponse implements HttpResponse { final int statusCode; diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java index 7e50aa9d274..06c8ec0c075 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java @@ -35,6 +35,7 @@ public final class OtlpGrpcProfilesExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; // TODO maybe make more efficient by adding support for MEMORY_MODE @@ -44,6 +45,7 @@ public final class OtlpGrpcProfilesExporterBuilder { OtlpGrpcProfilesExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; delegate.setMeterProvider(MeterProvider::noop); + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -115,6 +117,15 @@ public OtlpGrpcProfilesExporterBuilder setConnectTimeout(Duration timeout) { return this; } + /** + * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. + */ + public OtlpGrpcProfilesExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. The * endpoint must start with either http:// or https://. 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 365fa2ca659..d4c418c6c82 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 @@ -1056,6 +1056,10 @@ void validConfig() { assertThatCode( () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestMessageSize(0))) + .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestMessageSize(1))) + .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost:4317")) .doesNotThrowAnyException(); @@ -1167,6 +1171,26 @@ void invalidConfig() { .isInstanceOf(IllegalArgumentException.class) .hasMessage( "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); + assertThatThrownBy(() -> exporterBuilder().setMaxRequestMessageSize(-1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("maxRequestMessageSize must be non-negative"); + } + + @Test + void requestMessageSizeLimit() { + try (TelemetryExporter exporter = + exporterBuilder() + .setEndpoint(server.httpUri().toString()) + .setMaxRequestMessageSize(1) + .build()) { + CompletableResultCode result = + exporter.export(Collections.singletonList(generateFakeTelemetry())); + + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + Assertions.assertThat(result.getFailureThrowable()) + .hasMessageContaining("OTLP gRPC request message size") + .hasMessageContaining("exceeded limit of 1 bytes"); + } } @Test diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 5f5b13b1adf..f36ecef6379 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -833,6 +833,10 @@ void validConfig() { assertThatCode( () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestBodySize(0))) + .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestBodySize(1))) + .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost:4318")) .doesNotThrowAnyException(); @@ -913,6 +917,23 @@ void invalidConfig() { .isInstanceOf(IllegalArgumentException.class) .hasMessage( "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); + assertThatThrownBy(() -> exporterBuilder().setMaxRequestBodySize(-1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("maxRequestBodySize must be non-negative"); + } + + @Test + void requestBodySizeLimit() { + try (TelemetryExporter exporter = + exporterBuilder().setEndpoint(server.httpUri() + path).setMaxRequestBodySize(1).build()) { + CompletableResultCode result = + exporter.export(Collections.singletonList(generateFakeTelemetry())); + + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + Assertions.assertThat(result.getFailureThrowable()) + .hasMessageContaining("OTLP HTTP request body size") + .hasMessageContaining("exceeded limit of 1 bytes"); + } } @Test diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 87165e2467d..0925e0ee3b4 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -59,6 +59,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeou return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + builder.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index f0bda1c9ac4..0eb76c58cd7 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -59,6 +59,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + builder.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java index ac34a9504e2..20518dec6b7 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java @@ -59,6 +59,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + builder.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 06eb21c5850..babf82a12ea 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -60,6 +60,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + builder.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index 8963b2c21b0..c0f40843b39 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -60,6 +60,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeou return this; } + @Override + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + builder.setMaxRequestBodySize(maxRequestBodySize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index e9152cfac0c..c826c11d1f2 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -59,6 +59,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) return this; } + @Override + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + builder.setMaxRequestBodySize(maxRequestBodySize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index d3a51130ff6..5dc7ad03bc0 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -59,6 +59,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + builder.setMaxRequestBodySize(maxRequestBodySize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); 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 55d20c4bd0d..da5b0959c74 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 @@ -103,6 +103,12 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + delegate.setMaxRequestMessageSize(maxRequestMessageSize); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { delegate.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 779cc63905e..ef2e3bf904f 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -55,6 +55,14 @@ static TelemetryExporterBuilder wrap(OtlpGrpcProfilesExporterBuilde TelemetryExporterBuilder setConnectTimeout(Duration timeout); + default TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + throw new UnsupportedOperationException("Not implemented"); + } + + default TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + throw new UnsupportedOperationException("Not implemented"); + } + TelemetryExporterBuilder setCompression(String compression); TelemetryExporterBuilder addHeader(String key, String value); From 39f88dfe22c17c6800513a29b6012ef8ce283467 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Thu, 4 Jun 2026 14:02:30 +0530 Subject: [PATCH 2/8] Fix OTLP request limit CI issues --- .../logs/OtlpHttpLogRecordExporterBuilder.java | 10 +++++----- .../metrics/OtlpHttpMetricExporterBuilder.java | 10 +++++----- .../http/trace/OtlpHttpSpanExporterBuilder.java | 10 +++++----- .../exporter/otlp/internal/GrpcExporter.java | 16 ++++++++-------- .../exporter/otlp/internal/HttpExporter.java | 16 ++++++++-------- .../logs/OtlpGrpcLogRecordExporterBuilder.java | 11 ++++++----- .../metrics/OtlpGrpcMetricExporterBuilder.java | 11 ++++++----- .../otlp/trace/OtlpGrpcSpanExporterBuilder.java | 11 ++++++----- .../OtlpGrpcProfilesExporterBuilder.java | 11 ++++++----- .../AbstractGrpcTelemetryExporterTest.java | 2 +- .../AbstractHttpTelemetryExporterTest.java | 2 +- 11 files changed, 57 insertions(+), 53 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 4c9142d76aa..145a5df75af 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -37,7 +37,7 @@ public final class OtlpHttpLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/logs"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_BODY_SIZE = 64 * 1024L * 1024L; + private static final long DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; @@ -45,7 +45,7 @@ public final class OtlpHttpLogRecordExporterBuilder { OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE); + this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -103,9 +103,9 @@ public OtlpHttpLogRecordExporterBuilder setConnectTimeout(Duration timeout) { /** * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ - public OtlpHttpLogRecordExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - checkArgument(maxRequestBodySize >= 0, "maxRequestBodySize must be non-negative"); - delegate.setMaxRequestBodySize(maxRequestBodySize); + public OtlpHttpLogRecordExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { + checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); + delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); return this; } 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 fed5a29a418..1e130a7a91d 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 @@ -46,7 +46,7 @@ public final class OtlpHttpMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_BODY_SIZE = 64 * 1024L * 1024L; + private static final long DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; @@ -63,7 +63,7 @@ public final class OtlpHttpMetricExporterBuilder { this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; this.memoryMode = memoryMode; - this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE); + this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -123,9 +123,9 @@ public OtlpHttpMetricExporterBuilder setConnectTimeout(Duration timeout) { /** * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ - public OtlpHttpMetricExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - checkArgument(maxRequestBodySize >= 0, "maxRequestBodySize must be non-negative"); - delegate.setMaxRequestBodySize(maxRequestBodySize); + public OtlpHttpMetricExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { + checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); + delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); return this; } 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 8c66d7acac6..0cf1b38e5bd 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 @@ -37,7 +37,7 @@ public final class OtlpHttpSpanExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/traces"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_BODY_SIZE = 64 * 1024L * 1024L; + private static final long DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; @@ -45,7 +45,7 @@ public final class OtlpHttpSpanExporterBuilder { OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE); + this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -103,9 +103,9 @@ public OtlpHttpSpanExporterBuilder setConnectTimeout(Duration timeout) { /** * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ - public OtlpHttpSpanExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - checkArgument(maxRequestBodySize >= 0, "maxRequestBodySize must be non-negative"); - delegate.setMaxRequestBodySize(maxRequestBodySize); + public OtlpHttpSpanExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { + checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); + delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java index 8e0de5369d2..5c010890686 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java @@ -105,15 +105,15 @@ private CompletableResultCode failRequestTooLarge( CompletableResultCode result, ExporterInstrumentation.Recording metricRecording, long requestMessageSize) { - IOException exception = - new IOException( - "OTLP gRPC request message size " - + requestMessageSize - + " exceeded limit of " - + maxRequestMessageSize - + " bytes"); + String errorMessage = + "OTLP gRPC request message size " + + requestMessageSize + + " exceeded limit of " + + maxRequestMessageSize + + " bytes"; + IOException exception = new IOException(errorMessage); metricRecording.finishFailed(exception); - logger.log(Level.WARNING, exception.getMessage()); + logger.log(Level.WARNING, errorMessage); result.failExceptionally(FailedExportException.grpcFailedExceptionally(exception)); return result; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java index 04b3fd349c2..f00163f75c4 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java @@ -111,15 +111,15 @@ private CompletableResultCode failRequestTooLarge( CompletableResultCode result, ExporterInstrumentation.Recording metricRecording, long requestBodySize) { - IOException exception = - new IOException( - "OTLP HTTP request body size " - + requestBodySize - + " exceeded limit of " - + maxRequestBodySize - + " bytes"); + String errorMessage = + "OTLP HTTP request body size " + + requestBodySize + + " exceeded limit of " + + maxRequestBodySize + + " bytes"; + IOException exception = new IOException(errorMessage); metricRecording.finishFailed(exception); - logger.log(Level.WARNING, exception.getMessage()); + logger.log(Level.WARNING, errorMessage); result.failExceptionally(FailedExportException.httpFailedExceptionally(exception)); return result; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 8a3d174d8e6..b0cbe2b5af7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -43,7 +43,7 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -52,7 +52,7 @@ public final class OtlpGrpcLogRecordExporterBuilder { OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -132,9 +132,10 @@ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(Duration timeout) { /** * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ - public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); - delegate.setMaxRequestMessageSize(maxRequestMessageSize); + public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { + checkArgument( + maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 9875062d895..64b6dbdd61d 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 @@ -51,7 +51,7 @@ public final class OtlpGrpcMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -69,7 +69,7 @@ public final class OtlpGrpcMetricExporterBuilder { this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; this.memoryMode = memoryMode; - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -151,9 +151,10 @@ public OtlpGrpcMetricExporterBuilder setConnectTimeout(Duration timeout) { /** * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ - public OtlpGrpcMetricExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); - delegate.setMaxRequestMessageSize(maxRequestMessageSize); + public OtlpGrpcMetricExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { + checkArgument( + maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 e6c6b119633..5b100c9d598 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 @@ -40,7 +40,7 @@ public final class OtlpGrpcSpanExporterBuilder { private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -49,7 +49,7 @@ public final class OtlpGrpcSpanExporterBuilder { OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -129,9 +129,10 @@ public OtlpGrpcSpanExporterBuilder setConnectTimeout(Duration timeout) { /** * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ - public OtlpGrpcSpanExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); - delegate.setMaxRequestMessageSize(maxRequestMessageSize); + public OtlpGrpcSpanExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { + checkArgument( + maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java index 06c8ec0c075..57600d867e6 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java @@ -35,7 +35,7 @@ public final class OtlpGrpcProfilesExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; + private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // TODO maybe make more efficient by adding support for MEMORY_MODE @@ -45,7 +45,7 @@ public final class OtlpGrpcProfilesExporterBuilder { OtlpGrpcProfilesExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; delegate.setMeterProvider(MeterProvider::noop); - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE); + this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -120,9 +120,10 @@ public OtlpGrpcProfilesExporterBuilder setConnectTimeout(Duration timeout) { /** * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ - public OtlpGrpcProfilesExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - checkArgument(maxRequestMessageSize >= 0, "maxRequestMessageSize must be non-negative"); - delegate.setMaxRequestMessageSize(maxRequestMessageSize); + public OtlpGrpcProfilesExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { + checkArgument( + maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 d4c418c6c82..883806b6b1f 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 @@ -1173,7 +1173,7 @@ void invalidConfig() { "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); assertThatThrownBy(() -> exporterBuilder().setMaxRequestMessageSize(-1)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("maxRequestMessageSize must be non-negative"); + .hasMessage("maxRequestMessageSizeBytes must be non-negative"); } @Test diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index f36ecef6379..de5c3e2fc5d 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -919,7 +919,7 @@ void invalidConfig() { "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); assertThatThrownBy(() -> exporterBuilder().setMaxRequestBodySize(-1)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("maxRequestBodySize must be non-negative"); + .hasMessage("maxRequestBodySizeBytes must be non-negative"); } @Test From d3f4d426298982d9310021a9e6c34ac4aec9767a Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Thu, 4 Jun 2026 21:25:15 +0530 Subject: [PATCH 3/8] Apply spotless fixes for OTLP request limits --- .../otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java | 4 +--- .../otlp/http/metrics/OtlpHttpMetricExporterBuilder.java | 4 +--- .../otlp/http/trace/OtlpHttpSpanExporterBuilder.java | 4 +--- .../otlp/logs/OtlpGrpcLogRecordExporterBuilder.java | 7 +++---- .../otlp/metrics/OtlpGrpcMetricExporterBuilder.java | 4 +--- .../exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java | 4 +--- .../exporter/otlp/internal/GrpcExporterTest.java | 5 ++--- .../exporter/otlp/internal/HttpExporterTest.java | 2 +- 8 files changed, 11 insertions(+), 23 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 145a5df75af..85cf75f5f45 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -100,9 +100,7 @@ public OtlpHttpLogRecordExporterBuilder setConnectTimeout(Duration timeout) { return this; } - /** - * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. - */ + /** Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ public OtlpHttpLogRecordExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); 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 1e130a7a91d..bc204ea0fef 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 @@ -120,9 +120,7 @@ public OtlpHttpMetricExporterBuilder setConnectTimeout(Duration timeout) { return this; } - /** - * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. - */ + /** Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ public OtlpHttpMetricExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); 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 0cf1b38e5bd..5ddd6006574 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 @@ -100,9 +100,7 @@ public OtlpHttpSpanExporterBuilder setConnectTimeout(Duration timeout) { return this; } - /** - * Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. - */ + /** Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ public OtlpHttpSpanExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index b0cbe2b5af7..afa6b27323f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -129,10 +129,9 @@ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(Duration timeout) { return this; } - /** - * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. - */ - public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { + /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ + public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize( + long maxRequestMessageSizeBytes) { checkArgument( maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); 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 64b6dbdd61d..3be4b60f5fc 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 @@ -148,9 +148,7 @@ public OtlpGrpcMetricExporterBuilder setConnectTimeout(Duration timeout) { return this; } - /** - * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. - */ + /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcMetricExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { checkArgument( maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); 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 5b100c9d598..ea08f47bf97 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 @@ -126,9 +126,7 @@ public OtlpGrpcSpanExporterBuilder setConnectTimeout(Duration timeout) { return this; } - /** - * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. - */ + /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcSpanExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { checkArgument( maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java index 95698f19856..7f57bc5a56f 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java @@ -15,10 +15,10 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InternalTelemetryVersion; -import io.opentelemetry.sdk.common.export.MessageWriter; import io.opentelemetry.sdk.common.export.GrpcResponse; import io.opentelemetry.sdk.common.export.GrpcSender; import io.opentelemetry.sdk.common.export.GrpcStatusCode; +import io.opentelemetry.sdk.common.export.MessageWriter; import io.opentelemetry.sdk.common.internal.ComponentId; import io.opentelemetry.sdk.common.internal.SemConvAttributes; import io.opentelemetry.sdk.common.internal.StandardComponentId; @@ -26,9 +26,8 @@ import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.io.IOException; -import java.net.URI; import java.io.OutputStream; -import java.time.Duration; +import java.net.URI; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import javax.annotation.Nullable; diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java index bd58e1c6c94..d3d33f9e177 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java @@ -16,9 +16,9 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InternalTelemetryVersion; -import io.opentelemetry.sdk.common.export.MessageWriter; import io.opentelemetry.sdk.common.export.HttpResponse; import io.opentelemetry.sdk.common.export.HttpSender; +import io.opentelemetry.sdk.common.export.MessageWriter; import io.opentelemetry.sdk.common.internal.ComponentId; import io.opentelemetry.sdk.common.internal.SemConvAttributes; import io.opentelemetry.sdk.common.internal.StandardComponentId; From ba4c9e2bc562719da2afeede75bf70ed20f3f6e8 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Thu, 4 Jun 2026 21:33:13 +0530 Subject: [PATCH 4/8] Fix OTLP exporter test imports --- .../opentelemetry/exporter/otlp/internal/GrpcExporterTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java index 7f57bc5a56f..dd367894734 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java @@ -31,6 +31,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mockito; From 7e4fced36ba959bc536247e04b52b44f23ebc322 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Thu, 11 Jun 2026 10:19:24 +0530 Subject: [PATCH 5/8] Address OTLP request limit review feedback --- .../otlp/trace/OltpExporterBenchmark.java | 7 +- .../OtlpHttpLogRecordExporterBuilder.java | 4 +- .../OtlpHttpMetricExporterBuilder.java | 4 +- .../trace/OtlpHttpSpanExporterBuilder.java | 4 +- .../exporter/otlp/internal/GrpcExporter.java | 29 +++----- .../otlp/internal/GrpcExporterBuilder.java | 2 +- .../exporter/otlp/internal/HttpExporter.java | 66 +++---------------- .../otlp/internal/HttpExporterBuilder.java | 2 +- .../OtlpGrpcLogRecordExporterBuilder.java | 4 +- .../OtlpGrpcMetricExporterBuilder.java | 4 +- .../trace/OtlpGrpcSpanExporterBuilder.java | 4 +- .../otlp/internal/GrpcExporterTest.java | 9 ++- .../otlp/internal/HttpExporterTest.java | 63 ++++++++++++++++-- .../OtlpGrpcProfilesExporterBuilder.java | 4 +- .../AbstractGrpcTelemetryExporterTest.java | 27 +++++--- .../AbstractHttpTelemetryExporterTest.java | 24 +++++-- .../GrpcLogRecordExporterBuilderWrapper.java | 8 ++- .../GrpcMetricExporterBuilderWrapper.java | 5 ++ .../GrpcProfilesExporterBuilderWrapper.java | 8 ++- .../GrpcSpanExporterBuilderWrapper.java | 5 ++ .../HttpLogRecordExporterBuilderWrapper.java | 6 ++ .../HttpMetricExporterBuilderWrapper.java | 5 ++ .../HttpSpanExporterBuilderWrapper.java | 5 ++ ...anagedChannelTelemetryExporterBuilder.java | 5 ++ .../internal/TelemetryExporterBuilder.java | 8 +-- 25 files changed, 176 insertions(+), 136 deletions(-) diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index d73bb2989c2..7a7b4fffaa9 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -13,6 +13,7 @@ import io.grpc.stub.StreamObserver; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.otlp.internal.GrpcExporter; +import io.opentelemetry.exporter.otlp.internal.GrpcExporterBuilder; import io.opentelemetry.exporter.otlp.internal.HttpExporter; import io.opentelemetry.exporter.otlp.internal.HttpExporterBuilder; import io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSender; @@ -95,7 +96,8 @@ public void setUp() { InternalTelemetryVersion.LATEST, ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), MeterProvider::noop, - URI.create("http://localhost")); + URI.create("http://localhost"), + GrpcExporterBuilder.DEFAULT_MAX_REQUEST_MESSAGE_SIZE); okhttpGrpcSender = new GrpcExporter( @@ -115,7 +117,8 @@ public void setUp() { InternalTelemetryVersion.LATEST, ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), MeterProvider::noop, - URI.create("http://localhost")); + URI.create("http://localhost"), + GrpcExporterBuilder.DEFAULT_MAX_REQUEST_MESSAGE_SIZE); httpExporter = new HttpExporterBuilder( diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 85cf75f5f45..d2b5aa60e54 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -37,7 +37,6 @@ public final class OtlpHttpLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/logs"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; @@ -45,7 +44,6 @@ public final class OtlpHttpLogRecordExporterBuilder { OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -102,7 +100,7 @@ public OtlpHttpLogRecordExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ public OtlpHttpLogRecordExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { - checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); + checkArgument(maxRequestBodySizeBytes > 0, "maxRequestBodySizeBytes must be positive"); delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); return this; } 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 bc204ea0fef..d0fb197c3dd 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 @@ -46,7 +46,6 @@ public final class OtlpHttpMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; @@ -63,7 +62,6 @@ public final class OtlpHttpMetricExporterBuilder { this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; this.memoryMode = memoryMode; - this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -122,7 +120,7 @@ public OtlpHttpMetricExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ public OtlpHttpMetricExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { - checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); + checkArgument(maxRequestBodySizeBytes > 0, "maxRequestBodySizeBytes must be positive"); delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); return this; } 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 5ddd6006574..df125287f76 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 @@ -37,7 +37,6 @@ public final class OtlpHttpSpanExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/traces"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES = 64 * 1024L * 1024L; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; @@ -45,7 +44,6 @@ public final class OtlpHttpSpanExporterBuilder { OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestBodySize(DEFAULT_MAX_REQUEST_BODY_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } @@ -102,7 +100,7 @@ public OtlpHttpSpanExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP HTTP request body size in bytes. If unset, defaults to 64 MiB. */ public OtlpHttpSpanExporterBuilder setMaxRequestBodySize(long maxRequestBodySizeBytes) { - checkArgument(maxRequestBodySizeBytes >= 0, "maxRequestBodySizeBytes must be non-negative"); + checkArgument(maxRequestBodySizeBytes > 0, "maxRequestBodySizeBytes must be positive"); delegate.setMaxRequestBodySize(maxRequestBodySizeBytes); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java index 5c010890686..851940f5f31 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java @@ -47,21 +47,6 @@ public final class GrpcExporter { private final ExporterInstrumentation exporterMetrics; private final long maxRequestMessageSize; - public GrpcExporter( - GrpcSender grpcSender, - InternalTelemetryVersion internalTelemetryVersion, - StandardComponentId componentId, - Supplier meterProviderSupplier, - URI endpoint) { - this( - grpcSender, - internalTelemetryVersion, - componentId, - meterProviderSupplier, - endpoint, - Long.MAX_VALUE); - } - public GrpcExporter( GrpcSender grpcSender, InternalTelemetryVersion internalTelemetryVersion, @@ -85,14 +70,15 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { ExporterInstrumentation.Recording metricRecording = exporterMetrics.startRecordingExport(numItems); - CompletableResultCode result = new CompletableResultCode(); MessageWriter messageWriter = exportRequest.toBinaryMessageWriter(); long requestMessageSize = getRequestMessageSize(messageWriter); if (requestMessageSize > maxRequestMessageSize) { - return failRequestTooLarge(result, metricRecording, requestMessageSize); + return failRequestTooLarge(metricRecording, requestMessageSize); } + CompletableResultCode result = new CompletableResultCode(); + grpcSender.send( messageWriter, grpcResponse -> onResponse(result, metricRecording, grpcResponse), @@ -102,11 +88,11 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { } private CompletableResultCode failRequestTooLarge( - CompletableResultCode result, - ExporterInstrumentation.Recording metricRecording, - long requestMessageSize) { + ExporterInstrumentation.Recording metricRecording, long requestMessageSize) { String errorMessage = - "OTLP gRPC request message size " + "Failed to export " + + type + + "s. Request message size " + requestMessageSize + " exceeded limit of " + maxRequestMessageSize @@ -114,6 +100,7 @@ private CompletableResultCode failRequestTooLarge( IOException exception = new IOException(errorMessage); metricRecording.finishFailed(exception); logger.log(Level.WARNING, errorMessage); + CompletableResultCode result = new CompletableResultCode(); result.failExceptionally(FailedExportException.grpcFailedExceptionally(exception)); return result; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java index 9ef5aec1a1a..814fd62da3b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterBuilder.java @@ -47,7 +47,7 @@ public class GrpcExporterBuilder { public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; - public static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = Long.MAX_VALUE; + public static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE = 64 * 1024L * 1024L; private static final Logger LOGGER = Logger.getLogger(GrpcExporterBuilder.class.getName()); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java index f00163f75c4..92eae5968f5 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java @@ -17,7 +17,6 @@ import io.opentelemetry.sdk.common.internal.StandardComponentId; import io.opentelemetry.sdk.common.internal.ThrottlingLogger; import java.io.IOException; -import java.io.OutputStream; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicBoolean; @@ -48,23 +47,6 @@ public final class HttpExporter { private final boolean exportAsJson; private final long maxRequestBodySize; - public HttpExporter( - StandardComponentId componentId, - HttpSender httpSender, - Supplier meterProviderSupplier, - InternalTelemetryVersion internalTelemetryVersion, - URI endpoint, - boolean exportAsJson) { - this( - componentId, - httpSender, - meterProviderSupplier, - internalTelemetryVersion, - endpoint, - exportAsJson, - Long.MAX_VALUE); - } - public HttpExporter( StandardComponentId componentId, HttpSender httpSender, @@ -90,15 +72,16 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { ExporterInstrumentation.Recording metricRecording = exporterMetrics.startRecordingExport(numItems); - CompletableResultCode result = new CompletableResultCode(); MessageWriter messageWriter = exportAsJson ? exportRequest.toJsonMessageWriter() : exportRequest.toBinaryMessageWriter(); - long requestBodySize = getRequestBodySize(messageWriter); + int requestBodySize = messageWriter.getContentLength(); if (requestBodySize > maxRequestBodySize) { - return failRequestTooLarge(result, metricRecording, requestBodySize); + return failRequestTooLarge(metricRecording, requestBodySize); } + CompletableResultCode result = new CompletableResultCode(); + httpSender.send( messageWriter, httpResponse -> onResponse(result, metricRecording, httpResponse), @@ -108,11 +91,11 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { } private CompletableResultCode failRequestTooLarge( - CompletableResultCode result, - ExporterInstrumentation.Recording metricRecording, - long requestBodySize) { + ExporterInstrumentation.Recording metricRecording, long requestBodySize) { String errorMessage = - "OTLP HTTP request body size " + "Failed to export " + + type + + "s. Request body size " + requestBodySize + " exceeded limit of " + maxRequestBodySize @@ -120,42 +103,11 @@ private CompletableResultCode failRequestTooLarge( IOException exception = new IOException(errorMessage); metricRecording.finishFailed(exception); logger.log(Level.WARNING, errorMessage); + CompletableResultCode result = new CompletableResultCode(); result.failExceptionally(FailedExportException.httpFailedExceptionally(exception)); return result; } - private static long getRequestBodySize(MessageWriter messageWriter) { - int contentLength = messageWriter.getContentLength(); - if (contentLength >= 0) { - return contentLength; - } - try { - CountingOutputStream countingOutputStream = new CountingOutputStream(); - messageWriter.writeMessage(countingOutputStream); - return countingOutputStream.getCount(); - } catch (IOException e) { - return Long.MAX_VALUE; - } - } - - private static final class CountingOutputStream extends OutputStream { - private long count; - - @Override - public void write(int b) { - count++; - } - - @Override - public void write(byte[] b, int off, int len) { - count += len; - } - - private long getCount() { - return count; - } - } - private void onResponse( CompletableResultCode result, ExporterInstrumentation.Recording metricRecording, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java index d1eb5866481..e211d39e8c8 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporterBuilder.java @@ -46,7 +46,7 @@ public final class HttpExporterBuilder { public static final long DEFAULT_TIMEOUT_SECS = 10; public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; - public static final long DEFAULT_MAX_REQUEST_BODY_SIZE = Long.MAX_VALUE; + public static final long DEFAULT_MAX_REQUEST_BODY_SIZE = 64 * 1024L * 1024L; private static final Logger LOGGER = Logger.getLogger(HttpExporterBuilder.class.getName()); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index afa6b27323f..59353446460 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -43,7 +43,6 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -52,7 +51,6 @@ public final class OtlpGrpcLogRecordExporterBuilder { OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -133,7 +131,7 @@ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(Duration timeout) { public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize( long maxRequestMessageSizeBytes) { checkArgument( - maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 3be4b60f5fc..c0704b324de 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 @@ -51,7 +51,6 @@ public final class OtlpGrpcMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -69,7 +68,6 @@ public final class OtlpGrpcMetricExporterBuilder { this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; this.memoryMode = memoryMode; - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -151,7 +149,7 @@ public OtlpGrpcMetricExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcMetricExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { checkArgument( - maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 ea08f47bf97..179205fd988 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 @@ -40,7 +40,6 @@ public final class OtlpGrpcSpanExporterBuilder { private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // Visible for testing final GrpcExporterBuilder delegate; @@ -49,7 +48,6 @@ public final class OtlpGrpcSpanExporterBuilder { OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -129,7 +127,7 @@ public OtlpGrpcSpanExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcSpanExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { checkArgument( - maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java index dd367894734..59093b9d0cf 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java @@ -11,6 +11,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verifyNoInteractions; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; @@ -86,7 +87,8 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { InternalTelemetryVersion.LATEST, id, () -> meterProvider, - URI.create("http://testing:1234")); + URI.create("http://testing:1234"), + GrpcExporterBuilder.DEFAULT_MAX_REQUEST_MESSAGE_SIZE); doAnswer( invoc -> { @@ -220,7 +222,7 @@ void export_requestMessageTooLargeFailsBeforeSend() { mockSender, InternalTelemetryVersion.LATEST, ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_GRPC_SPAN_EXPORTER), - SdkMeterProvider::noop, + MeterProvider::noop, URI.create("http://testing:1234"), 1); @@ -241,7 +243,8 @@ public int getContentLength() { assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); assertThat(result.getFailureThrowable()) - .hasMessageContaining("OTLP gRPC request message size 2 exceeded limit of 1 bytes"); + .hasMessageContaining( + "Failed to export spans. Request message size 2 exceeded limit of 1 bytes"); verifyNoInteractions(mockSender); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java index d3d33f9e177..6f4b64fbf57 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java @@ -82,6 +82,18 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { HttpSender mockSender = Mockito.mock(HttpSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter emptyMessageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) {} + + @Override + public int getContentLength() { + return 0; + } + }; + Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(emptyMessageWriter); + Mockito.when(mockMarshaller.toJsonMessageWriter()).thenReturn(emptyMessageWriter); HttpExporter exporter = new HttpExporter( @@ -90,7 +102,8 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { () -> meterProvider, InternalTelemetryVersion.LATEST, URI.create("http://testing:1234"), - false); + false, + HttpExporterBuilder.DEFAULT_MAX_REQUEST_BODY_SIZE); doAnswer( invoc -> { @@ -214,6 +227,17 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { void export_httpJsonErrorBodyUsesBodyTextWithoutGrpcParseWarning() { HttpSender mockSender = Mockito.mock(HttpSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter emptyMessageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) {} + + @Override + public int getContentLength() { + return 0; + } + }; + Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(emptyMessageWriter); HttpExporter exporter = new HttpExporter( @@ -222,7 +246,8 @@ void export_httpJsonErrorBodyUsesBodyTextWithoutGrpcParseWarning() { MeterProvider::noop, InternalTelemetryVersion.LATEST, URI.create("http://testing:1234"), - false); + false, + HttpExporterBuilder.DEFAULT_MAX_REQUEST_BODY_SIZE); doAnswer( invoc -> { @@ -277,7 +302,7 @@ public int getContentLength() { org.assertj.core.api.Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()) .isFalse(); org.assertj.core.api.Assertions.assertThat(result.getFailureThrowable()) - .hasMessageContaining("OTLP HTTP request body size 2 exceeded limit of 1 bytes"); + .hasMessageContaining("Failed to export spans. Request body size 2 exceeded limit of 1 bytes"); verifyNoInteractions(mockSender); } @@ -286,6 +311,17 @@ public int getContentLength() { void export_nullErrorBodyUsesMissingBodyMessage() { HttpSender mockSender = Mockito.mock(HttpSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter emptyMessageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) {} + + @Override + public int getContentLength() { + return 0; + } + }; + Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(emptyMessageWriter); HttpExporter exporter = new HttpExporter( ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER), @@ -293,7 +329,8 @@ void export_nullErrorBodyUsesMissingBodyMessage() { MeterProvider::noop, InternalTelemetryVersion.LATEST, URI.create("http://testing:1234"), - false); + false, + HttpExporterBuilder.DEFAULT_MAX_REQUEST_BODY_SIZE); doAnswer( invoc -> { @@ -314,6 +351,17 @@ void export_nullErrorBodyUsesMissingBodyMessage() { void export_whitespaceErrorBodyFallsBackToStatusMessage() { HttpSender mockSender = Mockito.mock(HttpSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter emptyMessageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) {} + + @Override + public int getContentLength() { + return 0; + } + }; + Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(emptyMessageWriter); HttpExporter exporter = new HttpExporter( ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER), @@ -321,7 +369,8 @@ void export_whitespaceErrorBodyFallsBackToStatusMessage() { MeterProvider::noop, InternalTelemetryVersion.LATEST, URI.create("http://testing:1234"), - false); + false, + HttpExporterBuilder.DEFAULT_MAX_REQUEST_BODY_SIZE); doAnswer( invoc -> { @@ -348,7 +397,7 @@ void export_unknownRequestBodyTooLargeFailsBeforeSend() { new HttpExporter( ComponentId.generateLazy(StandardComponentId.ExporterType.OTLP_HTTP_SPAN_EXPORTER), mockSender, - SdkMeterProvider::noop, + MeterProvider::noop, InternalTelemetryVersion.LATEST, URI.create("http://testing:1234"), true, @@ -374,7 +423,7 @@ public int getContentLength() { org.assertj.core.api.Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()) .isFalse(); org.assertj.core.api.Assertions.assertThat(result.getFailureThrowable()) - .hasMessageContaining("OTLP HTTP request body size 2 exceeded limit of 1 bytes"); + .hasMessageContaining("Failed to export spans. Request body size 2 exceeded limit of 1 bytes"); verifyNoInteractions(mockSender); } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java index 57600d867e6..ee5dc115641 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java @@ -35,7 +35,6 @@ public final class OtlpGrpcProfilesExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); - private static final long DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES = 64 * 1024L * 1024L; // TODO maybe make more efficient by adding support for MEMORY_MODE @@ -45,7 +44,6 @@ public final class OtlpGrpcProfilesExporterBuilder { OtlpGrpcProfilesExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; delegate.setMeterProvider(MeterProvider::noop); - this.delegate.setMaxRequestMessageSize(DEFAULT_MAX_REQUEST_MESSAGE_SIZE_BYTES); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -122,7 +120,7 @@ public OtlpGrpcProfilesExporterBuilder setConnectTimeout(Duration timeout) { */ public OtlpGrpcProfilesExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { checkArgument( - maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative"); + maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 883806b6b1f..a67b3493e1f 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 @@ -42,6 +42,7 @@ import io.opentelemetry.exporter.internal.TlsUtil; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.GrpcExporter; +import io.opentelemetry.exporter.otlp.internal.GrpcExporterBuilder; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; @@ -922,7 +923,8 @@ protected void testExport_Unimplemented() { + "s. Server responded with UNIMPLEMENTED. " + "This usually means that your collector is not configured with an otlp " + "receiver in the \"pipelines\" section of the configuration. " - + "If export is not desired and you are using OpenTelemetry autoconfiguration or the javaagent, " + + "If export is not desired and you are using OpenTelemetry autoconfiguration " + + "or the javaagent, " + "disable export by setting " + envVar + "=none. " @@ -1056,8 +1058,6 @@ void validConfig() { assertThatCode( () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); - assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestMessageSize(0))) - .doesNotThrowAnyException(); assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestMessageSize(1))) .doesNotThrowAnyException(); @@ -1170,10 +1170,14 @@ void invalidConfig() { assertThatThrownBy(() -> exporterBuilder().setCompression("foo")) .isInstanceOf(IllegalArgumentException.class) .hasMessage( - "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); + "Unsupported compressionMethod. Compression method must be \"none\" or one of:" + + " [base64,gzip]"); + assertThatThrownBy(() -> exporterBuilder().setMaxRequestMessageSize(0)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("maxRequestMessageSizeBytes must be positive"); assertThatThrownBy(() -> exporterBuilder().setMaxRequestMessageSize(-1)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("maxRequestMessageSizeBytes must be non-negative"); + .hasMessage("maxRequestMessageSizeBytes must be positive"); } @Test @@ -1187,8 +1191,9 @@ void requestMessageSizeLimit() { exporter.export(Collections.singletonList(generateFakeTelemetry())); assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); - Assertions.assertThat(result.getFailureThrowable()) - .hasMessageContaining("OTLP gRPC request message size") + assertThat(result.getFailureThrowable()) + .hasMessageContaining("Failed to export") + .hasMessageContaining("Request message size") .hasMessageContaining("exceeded limit of 1 bytes"); } } @@ -1266,6 +1271,8 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "compressorEncoding=null, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" + + ".*maxRequestMessageSize=" + + GrpcExporterBuilder.DEFAULT_MAX_REQUEST_MESSAGE_SIZE + ".*" // Maybe additional grpcChannel field, signal specific fields + "\\}"); } @@ -1302,7 +1309,11 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "compressorEncoding=gzip, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " - + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3, retryExceptionPredicate=null\\}" + + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, " + + "maxBackoff=PT3S, backoffMultiplier=1\\.3, " + + "retryExceptionPredicate=null\\}" + + ".*maxRequestMessageSize=" + + GrpcExporterBuilder.DEFAULT_MAX_REQUEST_MESSAGE_SIZE + ".*" // Maybe additional grpcChannel field, signal specific fields + "\\}"); } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index de5c3e2fc5d..6da25e29335 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -35,6 +35,7 @@ import io.opentelemetry.exporter.internal.TlsUtil; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.HttpExporter; +import io.opentelemetry.exporter.otlp.internal.HttpExporterBuilder; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; @@ -833,8 +834,6 @@ void validConfig() { assertThatCode( () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); - assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestBodySize(0))) - .doesNotThrowAnyException(); assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestBodySize(1))) .doesNotThrowAnyException(); @@ -916,10 +915,14 @@ void invalidConfig() { assertThatThrownBy(() -> exporterBuilder().setCompression("foo")) .isInstanceOf(IllegalArgumentException.class) .hasMessage( - "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); + "Unsupported compressionMethod. Compression method must be \"none\" or one of:" + + " [base64,gzip]"); + assertThatThrownBy(() -> exporterBuilder().setMaxRequestBodySize(0)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("maxRequestBodySizeBytes must be positive"); assertThatThrownBy(() -> exporterBuilder().setMaxRequestBodySize(-1)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("maxRequestBodySizeBytes must be non-negative"); + .hasMessage("maxRequestBodySizeBytes must be positive"); } @Test @@ -930,8 +933,9 @@ void requestBodySizeLimit() { exporter.export(Collections.singletonList(generateFakeTelemetry())); assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); - Assertions.assertThat(result.getFailureThrowable()) - .hasMessageContaining("OTLP HTTP request body size") + assertThat(result.getFailureThrowable()) + .hasMessageContaining("Failed to export") + .hasMessageContaining("Request body size") .hasMessageContaining("exceeded limit of 1 bytes"); } } @@ -1042,6 +1046,8 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "exportAsJson=false, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" + + ".*maxRequestBodySize=" + + HttpExporterBuilder.DEFAULT_MAX_REQUEST_BODY_SIZE + ".*" // Maybe additional signal specific fields + "\\}"); } @@ -1079,7 +1085,11 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "exportAsJson=false, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " - + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3, retryExceptionPredicate=null\\}" + + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, " + + "maxBackoff=PT3S, backoffMultiplier=1\\.3, " + + "retryExceptionPredicate=null\\}" + + ".*maxRequestBodySize=" + + HttpExporterBuilder.DEFAULT_MAX_REQUEST_BODY_SIZE + ".*" // Maybe additional signal specific fields + "\\}"); } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 0925e0ee3b4..03e3b20da5f 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -60,7 +60,13 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeou } @Override - public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + throw new UnsupportedOperationException("Request body size is not supported for gRPC"); + } + + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize( + long maxRequestMessageSize) { builder.setMaxRequestMessageSize(maxRequestMessageSize); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index 0eb76c58cd7..313614f69af 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -59,6 +59,11 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) return this; } + @Override + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + throw new UnsupportedOperationException("Request body size is not supported for gRPC"); + } + @Override public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { builder.setMaxRequestMessageSize(maxRequestMessageSize); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java index 20518dec6b7..3c0986f5798 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java @@ -60,7 +60,13 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) } @Override - public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + throw new UnsupportedOperationException("Request body size is not supported for gRPC"); + } + + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize( + long maxRequestMessageSize) { builder.setMaxRequestMessageSize(maxRequestMessageSize); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index babf82a12ea..76fc9596137 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -60,6 +60,11 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + throw new UnsupportedOperationException("Request body size is not supported for gRPC"); + } + @Override public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { builder.setMaxRequestMessageSize(maxRequestMessageSize); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index c0f40843b39..466ddf9caab 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -66,6 +66,12 @@ public TelemetryExporterBuilder setMaxRequestBodySize(long maxReq return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize( + long maxRequestMessageSize) { + throw new UnsupportedOperationException("Request message size is not supported for HTTP"); + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index c826c11d1f2..f38e44274e0 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -65,6 +65,11 @@ public TelemetryExporterBuilder setMaxRequestBodySize(long maxReques return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + throw new UnsupportedOperationException("Request message size is not supported for HTTP"); + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 5dc7ad03bc0..4eebc551d25 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -65,6 +65,11 @@ public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestB return this; } + @Override + public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { + throw new UnsupportedOperationException("Request message size is not supported for HTTP"); + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); 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 da5b0959c74..76b4610c412 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 @@ -103,6 +103,11 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { + throw new UnsupportedOperationException("Request body size is not supported for gRPC"); + } + @Override public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { delegate.setMaxRequestMessageSize(maxRequestMessageSize); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index ef2e3bf904f..0bd5b9cd2ac 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -55,13 +55,9 @@ static TelemetryExporterBuilder wrap(OtlpGrpcProfilesExporterBuilde TelemetryExporterBuilder setConnectTimeout(Duration timeout); - default TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - throw new UnsupportedOperationException("Not implemented"); - } + TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize); - default TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - throw new UnsupportedOperationException("Not implemented"); - } + TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize); TelemetryExporterBuilder setCompression(String compression); From 38c6f40a5aa4c65509ea7f567f86ad166c2ac2d7 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Sun, 14 Jun 2026 22:14:29 +0530 Subject: [PATCH 6/8] Fix OTLP request limit formatting --- .../exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java | 3 +-- .../exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java | 3 +-- .../exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java | 3 +-- .../opentelemetry/exporter/otlp/internal/GrpcExporterTest.java | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 59353446460..c800192348f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -130,8 +130,7 @@ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize( long maxRequestMessageSizeBytes) { - checkArgument( - maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); + checkArgument(maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 c0704b324de..5cfa9409f4f 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 @@ -148,8 +148,7 @@ public OtlpGrpcMetricExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcMetricExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { - checkArgument( - maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); + checkArgument(maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } 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 179205fd988..0740aeb745a 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 @@ -126,8 +126,7 @@ public OtlpGrpcSpanExporterBuilder setConnectTimeout(Duration timeout) { /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcSpanExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { - checkArgument( - maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); + checkArgument(maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java index 59093b9d0cf..2bfd53f76ce 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java @@ -11,8 +11,8 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verifyNoInteractions; -import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InternalTelemetryVersion; From ae7360a98012960f7bf36dbd6391023920f0db16 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Sun, 14 Jun 2026 22:31:20 +0530 Subject: [PATCH 7/8] Fix OTLP profiles builder formatting --- .../otlp/profiles/OtlpGrpcProfilesExporterBuilder.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java index ee5dc115641..82f5a173c16 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java @@ -115,12 +115,9 @@ public OtlpGrpcProfilesExporterBuilder setConnectTimeout(Duration timeout) { return this; } - /** - * Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. - */ + /** Sets the maximum OTLP gRPC request message size in bytes. If unset, defaults to 64 MiB. */ public OtlpGrpcProfilesExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSizeBytes) { - checkArgument( - maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); + checkArgument(maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive"); delegate.setMaxRequestMessageSize(maxRequestMessageSizeBytes); return this; } From 565fbb05ccb07430c8cbb3bdd9867e8dfe86ac9a Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Sat, 11 Jul 2026 12:36:14 +0530 Subject: [PATCH 8/8] Fix OTLP request limit enforcement --- .../opentelemetry-exporter-otlp.txt | 2 +- .../exporter/otlp/internal/GrpcExporter.java | 44 ++------------- .../exporter/otlp/internal/HttpExporter.java | 53 +++++++++++++++++-- .../otlp/internal/GrpcExporterTest.java | 26 ++++----- .../otlp/internal/HttpExporterTest.java | 22 ++++---- .../AbstractGrpcTelemetryExporterTest.java | 11 ++-- .../AbstractHttpTelemetryExporterTest.java | 8 +-- .../GrpcLogRecordExporterBuilderWrapper.java | 10 +--- .../GrpcMetricExporterBuilderWrapper.java | 9 +--- .../GrpcProfilesExporterBuilderWrapper.java | 10 +--- .../GrpcSpanExporterBuilderWrapper.java | 9 +--- .../HttpLogRecordExporterBuilderWrapper.java | 10 +--- .../HttpMetricExporterBuilderWrapper.java | 9 +--- .../HttpSpanExporterBuilderWrapper.java | 9 +--- ...anagedChannelTelemetryExporterBuilder.java | 9 +--- .../internal/TelemetryExporterBuilder.java | 4 +- 16 files changed, 106 insertions(+), 139 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 07455b4b491..cec7d3534aa 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,4 +1,4 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.65.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.63.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.65.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.64.0.jar *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMaxRequestBodySize(long) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java index 851940f5f31..5f6752e2fe6 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/GrpcExporter.java @@ -18,7 +18,6 @@ import io.opentelemetry.sdk.common.internal.StandardComponentId; import io.opentelemetry.sdk.common.internal.ThrottlingLogger; import java.io.IOException; -import java.io.OutputStream; import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -70,13 +69,13 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { ExporterInstrumentation.Recording metricRecording = exporterMetrics.startRecordingExport(numItems); - MessageWriter messageWriter = exportRequest.toBinaryMessageWriter(); - - long requestMessageSize = getRequestMessageSize(messageWriter); + int requestMessageSize = exportRequest.getBinarySerializedSize(); if (requestMessageSize > maxRequestMessageSize) { return failRequestTooLarge(metricRecording, requestMessageSize); } + MessageWriter messageWriter = exportRequest.toBinaryMessageWriter(); + CompletableResultCode result = new CompletableResultCode(); grpcSender.send( @@ -100,41 +99,8 @@ private CompletableResultCode failRequestTooLarge( IOException exception = new IOException(errorMessage); metricRecording.finishFailed(exception); logger.log(Level.WARNING, errorMessage); - CompletableResultCode result = new CompletableResultCode(); - result.failExceptionally(FailedExportException.grpcFailedExceptionally(exception)); - return result; - } - - private static long getRequestMessageSize(MessageWriter messageWriter) { - int contentLength = messageWriter.getContentLength(); - if (contentLength >= 0) { - return contentLength; - } - try { - CountingOutputStream countingOutputStream = new CountingOutputStream(); - messageWriter.writeMessage(countingOutputStream); - return countingOutputStream.getCount(); - } catch (IOException e) { - return Long.MAX_VALUE; - } - } - - private static final class CountingOutputStream extends OutputStream { - private long count; - - @Override - public void write(int b) { - count++; - } - - @Override - public void write(byte[] b, int off, int len) { - count += len; - } - - private long getCount() { - return count; - } + return CompletableResultCode.ofExceptionalFailure( + FailedExportException.grpcFailedExceptionally(exception)); } private void onResponse( diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java index 92eae5968f5..eb461b29c5f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/HttpExporter.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.common.internal.StandardComponentId; import io.opentelemetry.sdk.common.internal.ThrottlingLogger; import java.io.IOException; +import java.io.OutputStream; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicBoolean; @@ -75,7 +76,12 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) { MessageWriter messageWriter = exportAsJson ? exportRequest.toJsonMessageWriter() : exportRequest.toBinaryMessageWriter(); - int requestBodySize = messageWriter.getContentLength(); + long requestBodySize; + try { + requestBodySize = getRequestBodySize(messageWriter); + } catch (IOException e) { + return failRequestBodySizeComputation(metricRecording, e); + } if (requestBodySize > maxRequestBodySize) { return failRequestTooLarge(metricRecording, requestBodySize); } @@ -103,9 +109,48 @@ private CompletableResultCode failRequestTooLarge( IOException exception = new IOException(errorMessage); metricRecording.finishFailed(exception); logger.log(Level.WARNING, errorMessage); - CompletableResultCode result = new CompletableResultCode(); - result.failExceptionally(FailedExportException.httpFailedExceptionally(exception)); - return result; + return CompletableResultCode.ofExceptionalFailure( + FailedExportException.httpFailedExceptionally(exception)); + } + + private CompletableResultCode failRequestBodySizeComputation( + ExporterInstrumentation.Recording metricRecording, IOException exception) { + metricRecording.finishFailed(exception); + logger.log( + Level.SEVERE, + "Failed to export " + type + "s. The request body size could not be computed.", + exception); + return CompletableResultCode.ofExceptionalFailure( + FailedExportException.httpFailedExceptionally(exception)); + } + + private static long getRequestBodySize(MessageWriter messageWriter) throws IOException { + int contentLength = messageWriter.getContentLength(); + if (contentLength >= 0) { + return contentLength; + } + + CountingOutputStream countingOutputStream = new CountingOutputStream(); + messageWriter.writeMessage(countingOutputStream); + return countingOutputStream.getCount(); + } + + private static final class CountingOutputStream extends OutputStream { + private long count; + + @Override + public void write(int b) { + count++; + } + + @Override + public void write(byte[] b, int off, int len) { + count += len; + } + + private long getCount() { + return count; + } } private void onResponse( diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java index 2bfd53f76ce..97d040c5eb2 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/GrpcExporterTest.java @@ -15,6 +15,7 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; +import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.GrpcResponse; import io.opentelemetry.sdk.common.export.GrpcSender; @@ -80,6 +81,17 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { GrpcSender mockSender = Mockito.mock(GrpcSender.class); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); + MessageWriter emptyMessageWriter = + new MessageWriter() { + @Override + public void writeMessage(OutputStream output) {} + + @Override + public int getContentLength() { + return 0; + } + }; + Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(emptyMessageWriter); GrpcExporter exporter = new GrpcExporter( @@ -227,19 +239,9 @@ void export_requestMessageTooLargeFailsBeforeSend() { 1); Marshaler mockMarshaller = Mockito.mock(Marshaler.class); - MessageWriter messageWriter = - new MessageWriter() { - @Override - public void writeMessage(OutputStream output) throws IOException {} - - @Override - public int getContentLength() { - return 2; - } - }; - Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(messageWriter); + Mockito.when(mockMarshaller.getBinarySerializedSize()).thenReturn(2); - io.opentelemetry.sdk.common.CompletableResultCode result = exporter.export(mockMarshaller, 1); + CompletableResultCode result = exporter.export(mockMarshaller, 1); assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); assertThat(result.getFailureThrowable()) diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java index 6f4b64fbf57..27e9d0e666a 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/HttpExporterTest.java @@ -15,6 +15,7 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; +import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.HttpResponse; import io.opentelemetry.sdk.common.export.HttpSender; @@ -31,6 +32,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import javax.annotation.Nullable; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; @@ -297,12 +299,12 @@ public int getContentLength() { }; Mockito.when(mockMarshaller.toBinaryMessageWriter()).thenReturn(messageWriter); - io.opentelemetry.sdk.common.CompletableResultCode result = exporter.export(mockMarshaller, 1); + CompletableResultCode result = exporter.export(mockMarshaller, 1); - org.assertj.core.api.Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()) - .isFalse(); - org.assertj.core.api.Assertions.assertThat(result.getFailureThrowable()) - .hasMessageContaining("Failed to export spans. Request body size 2 exceeded limit of 1 bytes"); + Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + Assertions.assertThat(result.getFailureThrowable()) + .hasMessageContaining( + "Failed to export spans. Request body size 2 exceeded limit of 1 bytes"); verifyNoInteractions(mockSender); } @@ -418,12 +420,12 @@ public int getContentLength() { }; Mockito.when(mockMarshaller.toJsonMessageWriter()).thenReturn(messageWriter); - io.opentelemetry.sdk.common.CompletableResultCode result = exporter.export(mockMarshaller, 1); + CompletableResultCode result = exporter.export(mockMarshaller, 1); - org.assertj.core.api.Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()) - .isFalse(); - org.assertj.core.api.Assertions.assertThat(result.getFailureThrowable()) - .hasMessageContaining("Failed to export spans. Request body size 2 exceeded limit of 1 bytes"); + Assertions.assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + Assertions.assertThat(result.getFailureThrowable()) + .hasMessageContaining( + "Failed to export spans. Request body size 2 exceeded limit of 1 bytes"); verifyNoInteractions(mockSender); } 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 a67b3493e1f..5eaa26066e3 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 @@ -1058,7 +1058,7 @@ void validConfig() { assertThatCode( () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); - assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestMessageSize(1))) + assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestSize(1))) .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost:4317")) @@ -1172,10 +1172,10 @@ void invalidConfig() { .hasMessage( "Unsupported compressionMethod. Compression method must be \"none\" or one of:" + " [base64,gzip]"); - assertThatThrownBy(() -> exporterBuilder().setMaxRequestMessageSize(0)) + assertThatThrownBy(() -> exporterBuilder().setMaxRequestSize(0)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("maxRequestMessageSizeBytes must be positive"); - assertThatThrownBy(() -> exporterBuilder().setMaxRequestMessageSize(-1)) + assertThatThrownBy(() -> exporterBuilder().setMaxRequestSize(-1)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("maxRequestMessageSizeBytes must be positive"); } @@ -1183,10 +1183,7 @@ void invalidConfig() { @Test void requestMessageSizeLimit() { try (TelemetryExporter exporter = - exporterBuilder() - .setEndpoint(server.httpUri().toString()) - .setMaxRequestMessageSize(1) - .build()) { + exporterBuilder().setEndpoint(server.httpUri().toString()).setMaxRequestSize(1).build()) { CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 6da25e29335..10eea614b7a 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -834,7 +834,7 @@ void validConfig() { assertThatCode( () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); - assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestBodySize(1))) + assertThatCode(() -> buildAndShutdown(exporterBuilder().setMaxRequestSize(1))) .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost:4318")) @@ -917,10 +917,10 @@ void invalidConfig() { .hasMessage( "Unsupported compressionMethod. Compression method must be \"none\" or one of:" + " [base64,gzip]"); - assertThatThrownBy(() -> exporterBuilder().setMaxRequestBodySize(0)) + assertThatThrownBy(() -> exporterBuilder().setMaxRequestSize(0)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("maxRequestBodySizeBytes must be positive"); - assertThatThrownBy(() -> exporterBuilder().setMaxRequestBodySize(-1)) + assertThatThrownBy(() -> exporterBuilder().setMaxRequestSize(-1)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("maxRequestBodySizeBytes must be positive"); } @@ -928,7 +928,7 @@ void invalidConfig() { @Test void requestBodySizeLimit() { try (TelemetryExporter exporter = - exporterBuilder().setEndpoint(server.httpUri() + path).setMaxRequestBodySize(1).build()) { + exporterBuilder().setEndpoint(server.httpUri() + path).setMaxRequestSize(1).build()) { CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 03e3b20da5f..8e7e1720a61 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -60,14 +60,8 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeou } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - throw new UnsupportedOperationException("Request body size is not supported for gRPC"); - } - - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize( - long maxRequestMessageSize) { - builder.setMaxRequestMessageSize(maxRequestMessageSize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + builder.setMaxRequestMessageSize(maxRequestSize); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index 313614f69af..7d65d465a41 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -60,13 +60,8 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - throw new UnsupportedOperationException("Request body size is not supported for gRPC"); - } - - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - builder.setMaxRequestMessageSize(maxRequestMessageSize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + builder.setMaxRequestMessageSize(maxRequestSize); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java index 3c0986f5798..decd9ec2320 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcProfilesExporterBuilderWrapper.java @@ -60,14 +60,8 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - throw new UnsupportedOperationException("Request body size is not supported for gRPC"); - } - - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize( - long maxRequestMessageSize) { - builder.setMaxRequestMessageSize(maxRequestMessageSize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + builder.setMaxRequestMessageSize(maxRequestSize); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 76fc9596137..be724c89f91 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -61,13 +61,8 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - throw new UnsupportedOperationException("Request body size is not supported for gRPC"); - } - - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - builder.setMaxRequestMessageSize(maxRequestMessageSize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + builder.setMaxRequestMessageSize(maxRequestSize); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index 466ddf9caab..fbe22830d67 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -61,17 +61,11 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeou } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - builder.setMaxRequestBodySize(maxRequestBodySize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + builder.setMaxRequestBodySize(maxRequestSize); return this; } - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize( - long maxRequestMessageSize) { - throw new UnsupportedOperationException("Request message size is not supported for HTTP"); - } - @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index f38e44274e0..fd919103222 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -60,16 +60,11 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - builder.setMaxRequestBodySize(maxRequestBodySize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + builder.setMaxRequestBodySize(maxRequestSize); return this; } - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - throw new UnsupportedOperationException("Request message size is not supported for HTTP"); - } - @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 4eebc551d25..04b8246edeb 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -60,16 +60,11 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - builder.setMaxRequestBodySize(maxRequestBodySize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + builder.setMaxRequestBodySize(maxRequestSize); return this; } - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - throw new UnsupportedOperationException("Request message size is not supported for HTTP"); - } - @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); 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 76b4610c412..29b8f990baa 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 @@ -104,13 +104,8 @@ public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { } @Override - public TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize) { - throw new UnsupportedOperationException("Request body size is not supported for gRPC"); - } - - @Override - public TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize) { - delegate.setMaxRequestMessageSize(maxRequestMessageSize); + public TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize) { + delegate.setMaxRequestSize(maxRequestSize); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 0bd5b9cd2ac..c588f50a568 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -55,9 +55,7 @@ static TelemetryExporterBuilder wrap(OtlpGrpcProfilesExporterBuilde TelemetryExporterBuilder setConnectTimeout(Duration timeout); - TelemetryExporterBuilder setMaxRequestBodySize(long maxRequestBodySize); - - TelemetryExporterBuilder setMaxRequestMessageSize(long maxRequestMessageSize); + TelemetryExporterBuilder setMaxRequestSize(long maxRequestSize); TelemetryExporterBuilder setCompression(String compression);