From 039bdfa7540b0e0e0fed7ec049801efbda64e26e Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Thu, 9 May 2024 12:42:25 -0500 Subject: [PATCH] Add low allocation support to OTLP log exporters --- .../http/logs/OtlpHttpLogRecordExporter.java | 45 +++++++++++++++---- .../OtlpHttpLogRecordExporterBuilder.java | 21 ++++++--- .../otlp/internal/OtlpConfigUtil.java | 22 +++++++++ .../OtlpLogRecordExporterProvider.java | 7 +++ .../otlp/logs/MarshalerLogsServiceGrpc.java | 30 ++++++------- .../otlp/logs/OtlpGrpcLogRecordExporter.java | 41 ++++++++++++++--- .../OtlpGrpcLogRecordExporterBuilder.java | 22 ++++++--- .../exporter/otlp/logs/OtlpGrpcLogUtil.java | 19 ++++++++ .../OtlpLogRecordExporterProviderTest.java | 7 +++ .../OtlpSpanExporterProviderTest.java | 1 + .../otlp/KeyValueStatelessMarshaler.java | 4 +- .../metrics/ExemplarStatelessMarshaler.java | 6 +-- ...lHistogramDataPointStatelessMarshaler.java | 6 +-- .../HistogramDataPointStatelessMarshaler.java | 6 +-- .../NumberDataPointStatelessMarshaler.java | 6 +-- .../SummaryDataPointStatelessMarshaler.java | 6 +-- 16 files changed, 192 insertions(+), 57 deletions(-) create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java index de48a358f41..4f3202ceb99 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java @@ -7,11 +7,17 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LowAllocationLogsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** @@ -22,14 +28,18 @@ @ThreadSafe public final class OtlpHttpLogRecordExporter implements LogRecordExporter { - private final HttpExporterBuilder builder; - private final HttpExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final HttpExporterBuilder builder; + private final HttpExporter delegate; + private final MemoryMode memoryMode; OtlpHttpLogRecordExporter( - HttpExporterBuilder builder, - HttpExporter delegate) { + HttpExporterBuilder builder, + HttpExporter delegate, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; + this.memoryMode = memoryMode; } /** @@ -61,7 +71,7 @@ public static OtlpHttpLogRecordExporterBuilder builder() { * @since 1.29.0 */ public OtlpHttpLogRecordExporterBuilder toBuilder() { - return new OtlpHttpLogRecordExporterBuilder(builder.copy()); + return new OtlpHttpLogRecordExporterBuilder(builder.copy(), memoryMode); } /** @@ -72,8 +82,24 @@ public OtlpHttpLogRecordExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection logs) { - LogsRequestMarshaler exportRequest = LogsRequestMarshaler.create(logs); - return delegate.export(exportRequest, logs.size()); + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationLogsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationLogsRequestMarshaler(); + } + LowAllocationLogsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(logs); + return delegate + .export(exportMarshaler, logs.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA + LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); + return delegate.export(request, logs.size()); } @Override @@ -89,6 +115,9 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpHttpLogRecordExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpHttpLogRecordExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } 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 4d330c42546..619914f26e3 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 @@ -14,8 +14,9 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; @@ -33,16 +34,19 @@ public final class OtlpHttpLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/logs"; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; - private final HttpExporterBuilder delegate; + private final HttpExporterBuilder delegate; + private MemoryMode memoryMode; - OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate) { + OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } OtlpHttpLogRecordExporterBuilder() { - this(new HttpExporterBuilder<>("otlp", "log", DEFAULT_ENDPOINT)); + this(new HttpExporterBuilder<>("otlp", "log", DEFAULT_ENDPOINT), DEFAULT_MEMORY_MODE); } /** @@ -206,12 +210,19 @@ public OtlpHttpLogRecordExporterBuilder setMeterProvider( return this; } + /** Set the {@link MemoryMode}. */ + OtlpHttpLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * * @return a new exporter's instance */ public OtlpHttpLogRecordExporter build() { - return new OtlpHttpLogRecordExporter(delegate, delegate.build()); + return new OtlpHttpLogRecordExporter(delegate, delegate.build(), memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 48b7a26900b..c06d5f1f60e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -7,8 +7,10 @@ import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -257,6 +259,26 @@ public static void setMemoryModeOnOtlpExporterBuilder(Object builder, MemoryMode OtlpHttpSpanExporterBuilder.class.getDeclaredMethod("setMemoryMode", MemoryMode.class); method.setAccessible(true); method.invoke(builder, memoryMode); + } else if (builder instanceof OtlpGrpcLogRecordExporterBuilder) { + // Calling getDeclaredMethod causes all private methods to be read, which causes a + // ClassNotFoundException when running with the OkHttHttpProvider as the private + // setManagedChanel(io.grpc.ManagedChannel) is reached and io.grpc.ManagedChannel is not on + // the classpath. io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogUtil provides a layer + // of indirection which avoids scanning the OtlpGrpcLogRecordExporterBuilder private + // methods. + Class otlpGrpcMetricUtil = + Class.forName("io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogUtil"); + Method method = + otlpGrpcMetricUtil.getDeclaredMethod( + "setMemoryMode", OtlpGrpcLogRecordExporterBuilder.class, MemoryMode.class); + method.setAccessible(true); + method.invoke(null, builder, memoryMode); + } else if (builder instanceof OtlpHttpLogRecordExporterBuilder) { + Method method = + OtlpHttpLogRecordExporterBuilder.class.getDeclaredMethod( + "setMemoryMode", MemoryMode.class); + method.setAccessible(true); + method.invoke(builder, memoryMode); } else { throw new IllegalArgumentException( "Cannot set memory mode. Unrecognized OTLP exporter builder"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java index 1694189d69b..04cf661b58b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java @@ -10,6 +10,7 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; @@ -53,6 +54,9 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy); builder.setMeterProvider(meterProviderRef::get); + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -69,6 +73,9 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy); builder.setMeterProvider(meterProviderRef::get); + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java index 06d7da50bff..451e5abae32 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java @@ -14,7 +14,7 @@ import io.grpc.stub.ClientCalls; import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import java.io.InputStream; import javax.annotation.Nullable; @@ -23,15 +23,15 @@ final class MarshalerLogsServiceGrpc { private static final String SERVICE_NAME = "opentelemetry.proto.collector.logs.v1.LogsService"; - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { + private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = + new MethodDescriptor.Marshaller() { @Override - public InputStream stream(LogsRequestMarshaler value) { + public InputStream stream(Marshaler value) { return new MarshalerInputStream(value); } @Override - public LogsRequestMarshaler parse(InputStream stream) { + public Marshaler parse(InputStream stream) { throw new UnsupportedOperationException("Only for serializing"); } }; @@ -49,14 +49,13 @@ public ExportLogsServiceResponse parse(InputStream stream) { } }; - private static final MethodDescriptor - getExportMethod = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); + private static final MethodDescriptor getExportMethod = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) + .setRequestMarshaller(REQUEST_MARSHALLER) + .setResponseMarshaller(RESPONSE_MARSHALER) + .build(); static LogsServiceFutureStub newFutureStub(Channel channel, @Nullable String authorityOverride) { return LogsServiceFutureStub.newStub( @@ -65,8 +64,7 @@ static LogsServiceFutureStub newFutureStub(Channel channel, @Nullable String aut } static final class LogsServiceFutureStub - extends MarshalerServiceStub< - LogsRequestMarshaler, ExportLogsServiceResponse, LogsServiceFutureStub> { + extends MarshalerServiceStub { private LogsServiceFutureStub(Channel channel, CallOptions callOptions) { super(channel, callOptions); } @@ -78,7 +76,7 @@ protected MarshalerLogsServiceGrpc.LogsServiceFutureStub build( } @Override - public ListenableFuture export(LogsRequestMarshaler request) { + public ListenableFuture export(Marshaler request) { return ClientCalls.futureUnaryCall( getChannel().newCall(getExportMethod, getCallOptions()), request); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java index a97a9553d13..efde0010450 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java @@ -7,11 +7,17 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LowAllocationLogsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** @@ -22,8 +28,10 @@ @ThreadSafe public final class OtlpGrpcLogRecordExporter implements LogRecordExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; + private final MemoryMode memoryMode; /** * Returns a new {@link OtlpGrpcLogRecordExporter} using the default values. @@ -47,10 +55,12 @@ public static OtlpGrpcLogRecordExporterBuilder builder() { } OtlpGrpcLogRecordExporter( - GrpcExporterBuilder builder, - GrpcExporter delegate) { + GrpcExporterBuilder builder, + GrpcExporter delegate, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; + this.memoryMode = memoryMode; } /** @@ -61,7 +71,7 @@ public static OtlpGrpcLogRecordExporterBuilder builder() { * @since 1.29.0 */ public OtlpGrpcLogRecordExporterBuilder toBuilder() { - return new OtlpGrpcLogRecordExporterBuilder(builder.copy()); + return new OtlpGrpcLogRecordExporterBuilder(builder.copy(), memoryMode); } /** @@ -72,6 +82,22 @@ public OtlpGrpcLogRecordExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection logs) { + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationLogsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationLogsRequestMarshaler(); + } + LowAllocationLogsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(logs); + return delegate + .export(exportMarshaler, logs.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); return delegate.export(request, logs.size()); } @@ -92,6 +118,9 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpGrpcLogRecordExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpGrpcLogRecordExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } 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 df5f4769588..58cfc8e3c61 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 @@ -15,8 +15,9 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.time.Duration; @@ -41,12 +42,15 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final long DEFAULT_TIMEOUT_SECS = 10; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; + private MemoryMode memoryMode; - OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate) { + OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -58,7 +62,8 @@ public final class OtlpGrpcLogRecordExporterBuilder { DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, () -> MarshalerLogsServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH)); + GRPC_ENDPOINT_PATH), + DEFAULT_MEMORY_MODE); } /** @@ -238,12 +243,19 @@ public OtlpGrpcLogRecordExporterBuilder setMeterProvider( return this; } + /** Set the {@link MemoryMode}. */ + OtlpGrpcLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * * @return a new exporter's instance */ public OtlpGrpcLogRecordExporter build() { - return new OtlpGrpcLogRecordExporter(delegate, delegate.build()); + return new OtlpGrpcLogRecordExporter(delegate, delegate.build(), memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java new file mode 100644 index 00000000000..1602514e8d5 --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.logs; + +import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; +import io.opentelemetry.sdk.common.export.MemoryMode; + +final class OtlpGrpcLogUtil { + + private OtlpGrpcLogUtil() {} + + /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpExporterBuilder(Object, MemoryMode)}. */ + static void setMemoryMode(OtlpGrpcLogRecordExporterBuilder builder, MemoryMode memoryMode) { + builder.setMemoryMode(memoryMode); + } +} diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java index 8bfb90e1714..5619ddf5aa4 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java @@ -20,6 +20,7 @@ import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.io.IOException; import java.nio.file.Files; @@ -127,6 +128,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -176,6 +178,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.logs.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.logs.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -188,6 +191,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -207,6 +211,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -259,6 +264,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.logs.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.logs.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -271,6 +277,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java index 343f92de66f..b2b67b56b61 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java @@ -212,6 +212,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java index 0f14f0d354c..4b095d640d6 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java @@ -14,9 +14,9 @@ import java.io.IOException; /** A Marshaler of key value pairs. See {@link AnyValueMarshaler}. */ -final class KeyValueStatelessMarshaler implements StatelessMarshaler { +public final class KeyValueStatelessMarshaler implements StatelessMarshaler { - static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); + public static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); private static final byte[] EMPTY_BYTES = new byte[0]; private KeyValueStatelessMarshaler() {} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java index 3982b697ee0..9959beb7160 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java @@ -14,7 +14,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.LongExemplarData; @@ -52,7 +52,7 @@ public void writeTo(Serializer output, ExemplarData exemplar, MarshalerContext c output.serializeRepeatedMessageWithContext( io.opentelemetry.proto.metrics.v1.internal.Exemplar.FILTERED_ATTRIBUTES, exemplar.getFilteredAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -85,7 +85,7 @@ public int getBinarySerializedSize(ExemplarData exemplar, MarshalerContext conte StatelessMarshalerUtil.sizeRepeatedMessageWithContext( io.opentelemetry.proto.metrics.v1.internal.Exemplar.FILTERED_ATTRIBUTES, exemplar.getFilteredAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java index 23117aab5d5..bbf2a1d6881 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.ExponentialHistogramDataPoint; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; import java.io.IOException; @@ -58,7 +58,7 @@ public void writeTo( output.serializeRepeatedMessageWithContext( ExponentialHistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -105,7 +105,7 @@ public int getBinarySerializedSize( StatelessMarshalerUtil.sizeRepeatedMessageWithContext( ExponentialHistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java index 2102aa8bf35..c078a9739f4 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.HistogramDataPoint; import io.opentelemetry.sdk.metrics.data.HistogramPointData; import java.io.IOException; @@ -45,7 +45,7 @@ public void writeTo(Serializer output, HistogramPointData point, MarshalerContex output.serializeRepeatedMessageWithContext( HistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -77,7 +77,7 @@ public int getBinarySerializedSize(HistogramPointData point, MarshalerContext co StatelessMarshalerUtil.sizeRepeatedMessageWithContext( HistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java index 2981e8cd598..c907d59a7e7 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java @@ -13,7 +13,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.NumberDataPoint; import io.opentelemetry.sdk.metrics.data.DoublePointData; import io.opentelemetry.sdk.metrics.data.LongPointData; @@ -45,7 +45,7 @@ public void writeTo(Serializer output, PointData point, MarshalerContext context output.serializeRepeatedMessageWithContext( NumberDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -71,7 +71,7 @@ public int getBinarySerializedSize(PointData point, MarshalerContext context) { StatelessMarshalerUtil.sizeRepeatedMessageWithContext( NumberDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java index d8d611c12fb..bcd2306bb13 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.SummaryDataPoint; import io.opentelemetry.sdk.metrics.data.SummaryPointData; import java.io.IOException; @@ -37,7 +37,7 @@ public void writeTo(Serializer output, SummaryPointData point, MarshalerContext output.serializeRepeatedMessageWithContext( SummaryDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -60,7 +60,7 @@ public int getBinarySerializedSize(SummaryPointData point, MarshalerContext cont StatelessMarshalerUtil.sizeRepeatedMessageWithContext( SummaryDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; }