From 6720aae2d77572d50bfb657f3b09b33946b6b29f Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Wed, 3 Jun 2026 08:57:26 +0530 Subject: [PATCH 1/4] Enforce OTLP request size limits --- .../opentelemetry-exporter-otlp.txt | 19 ++++- .../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 | 42 ++++++++++ .../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, 465 insertions(+), 4 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 0bf665aa4c6..ddce74dfe28 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.63.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.62.0.jar -No changes. \ No newline at end of file +*** 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 eaaad3c8659..cde9412622f 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.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -42,6 +43,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, @@ -50,12 +52,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) { @@ -70,6 +91,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), @@ -78,6 +104,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 f44de7f72ce..5af16bfef24 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,11 +8,13 @@ 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.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.HttpResponse; import io.opentelemetry.sdk.common.export.HttpSender; import io.opentelemetry.sdk.common.internal.ComponentId; @@ -21,7 +23,9 @@ 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.util.concurrent.TimeUnit; import java.util.function.Consumer; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -197,6 +201,44 @@ void testInternalTelemetry(StandardComponentId.ExporterType exporterType) { } } + @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, + 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 9b21a1c206a..26bbf55c51c 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 @@ -832,6 +832,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(); @@ -912,6 +916,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 de6233526325a1c3bdb618bc1b6b85fed0e680c4 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Thu, 4 Jun 2026 14:02:30 +0530 Subject: [PATCH 2/4] 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 cde9412622f..1ce335aea98 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 @@ -108,15 +108,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 26bbf55c51c..a6a11d51fba 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 @@ -918,7 +918,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 d70ba3357bf8d78cedb6c8a9c99331fc9115af99 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Thu, 4 Jun 2026 21:25:15 +0530 Subject: [PATCH 3/4] 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 5af16bfef24..a23a739da9b 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 @@ -14,9 +14,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 afad5b0c189a30eda9f4b9e4d20d39e4582da186 Mon Sep 17 00:00:00 2001 From: ADITYA-CODE-SOURCE Date: Thu, 4 Jun 2026 21:33:13 +0530 Subject: [PATCH 4/4] Fix OTLP exporter test imports --- .../opentelemetry/exporter/otlp/internal/GrpcExporterTest.java | 1 + .../opentelemetry/exporter/otlp/internal/HttpExporterTest.java | 1 + 2 files changed, 2 insertions(+) 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; 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 a23a739da9b..bdf0c917631 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 @@ -27,6 +27,7 @@ import java.net.URI; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mockito;