Skip to content

Commit

Permalink
Add basic proxy configuration to OtlpHttp{Signal}Exporters (#6270)
Browse files Browse the repository at this point in the history
Co-authored-by: Marc Schumacher <schumi@zalando.de>
  • Loading branch information
jack-berg and marcschumacher committed Mar 7, 2024
1 parent f24acbd commit e41470b
Show file tree
Hide file tree
Showing 25 changed files with 241 additions and 6 deletions.
1 change: 1 addition & 0 deletions dependencyManagement/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ val DEPENDENCIES = listOf(
"org.codehaus.mojo:animal-sniffer-annotations:1.23",
"org.jctools:jctools-core:4.0.3",
"org.junit-pioneer:junit-pioneer:1.9.1",
"org.mock-server:mockserver-netty:5.15.0:shaded",
"org.skyscreamer:jsonassert:1.5.1",
"com.android.tools:desugar_jdk_libs:2.0.4",
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
Comparing source compatibility of against
*** 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 setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions)
*** 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 setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions)
*** 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 setProxy(io.opentelemetry.sdk.common.export.ProxyOptions)
*** 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 setConnectTimeout(long, java.util.concurrent.TimeUnit)
Expand Down
8 changes: 7 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
Comparing source compatibility of against
No changes.
+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.export.ProxyOptions (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.ProxySelector)
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.InetSocketAddress)
+++ NEW METHOD: PUBLIC(+) java.net.ProxySelector getProxySelector()
+++ NEW METHOD: PUBLIC(+) java.lang.String toString()
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.opentelemetry.exporter.internal.auth.Authenticator;
import io.opentelemetry.exporter.internal.compression.Compressor;
import io.opentelemetry.exporter.internal.marshal.Marshaler;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import java.net.URI;
import java.util.ArrayList;
Expand Down Expand Up @@ -52,6 +53,7 @@ public final class HttpExporterBuilder<T extends Marshaler> {
private long timeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS);
@Nullable private Compressor compressor;
private long connectTimeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_CONNECT_TIMEOUT_SECS);
@Nullable private ProxyOptions proxyOptions;
private boolean exportAsJson = false;
private final Map<String, String> constantHeaders = new HashMap<>();
private Supplier<Map<String, String>> headerSupplier = Collections::emptyMap;
Expand Down Expand Up @@ -131,6 +133,11 @@ public HttpExporterBuilder<T> setRetryPolicy(RetryPolicy retryPolicy) {
return this;
}

public HttpExporterBuilder<T> setProxyOptions(ProxyOptions proxyOptions) {
this.proxyOptions = proxyOptions;
return this;
}

public HttpExporterBuilder<T> exportAsJson() {
this.exportAsJson = true;
return this;
Expand All @@ -152,6 +159,7 @@ public HttpExporterBuilder<T> copy() {
}
copy.meterProviderSupplier = meterProviderSupplier;
copy.authenticator = authenticator;
copy.proxyOptions = proxyOptions;
return copy;
}

Expand Down Expand Up @@ -187,6 +195,7 @@ public HttpExporter<T> build() {
timeoutNanos,
connectTimeoutNanos,
headerSupplier,
proxyOptions,
authenticator,
retryPolicy,
tlsConfigHelper.getSslContext(),
Expand All @@ -205,6 +214,7 @@ public String toString(boolean includePrefixAndSuffix) {
joiner.add("type=" + type);
joiner.add("endpoint=" + endpoint);
joiner.add("timeoutNanos=" + timeoutNanos);
joiner.add("proxyOptions=" + proxyOptions);
joiner.add(
"compressorEncoding="
+ Optional.ofNullable(compressor).map(Compressor::getEncoding).orElse(null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import io.opentelemetry.exporter.internal.auth.Authenticator;
import io.opentelemetry.exporter.internal.compression.Compressor;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -34,6 +35,7 @@ HttpSender createSender(
long timeoutNanos,
long connectTimeout,
Supplier<Map<String, List<String>>> headerSupplier,
@Nullable ProxyOptions proxyOptions,
@Nullable Authenticator authenticator,
@Nullable RetryPolicy retryPolicy,
@Nullable SSLContext sslContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.opentelemetry.exporter.internal.http.HttpExporterBuilder;
import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler;
import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import java.time.Duration;
import java.util.Map;
Expand Down Expand Up @@ -171,6 +172,13 @@ public OtlpHttpLogRecordExporterBuilder setRetryPolicy(RetryPolicy retryPolicy)
return this;
}

/** Sets the proxy options. Proxying is disabled by default. */
public OtlpHttpLogRecordExporterBuilder setProxyOptions(ProxyOptions proxyOptions) {
requireNonNull(proxyOptions, "proxyOptions");
delegate.setProxyOptions(proxyOptions);
return this;
}

/**
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses
* {@link GlobalOpenTelemetry#getMeterProvider()}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.opentelemetry.exporter.internal.http.HttpExporterBuilder;
import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler;
import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import io.opentelemetry.sdk.metrics.InstrumentType;
import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector;
Expand Down Expand Up @@ -215,6 +216,13 @@ public OtlpHttpMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) {
return this;
}

/** Sets the proxy options. Proxying is disabled by default. */
public OtlpHttpMetricExporterBuilder setProxyOptions(ProxyOptions proxyOptions) {
requireNonNull(proxyOptions, "proxyOptions");
delegate.setProxyOptions(proxyOptions);
return this;
}

OtlpHttpMetricExporterBuilder exportAsJson() {
delegate.exportAsJson();
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.opentelemetry.exporter.internal.http.HttpExporterBuilder;
import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler;
import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import java.time.Duration;
import java.util.Map;
Expand Down Expand Up @@ -172,6 +173,13 @@ public OtlpHttpSpanExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) {
return this;
}

/** Sets the proxy options. Proxying is disabled by default. */
public OtlpHttpSpanExporterBuilder setProxy(ProxyOptions proxyOptions) {
requireNonNull(proxyOptions, "proxyOptions");
delegate.setProxyOptions(proxyOptions);
return this;
}

/**
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses
* {@link GlobalOpenTelemetry#getMeterProvider()}.
Expand Down
1 change: 1 addition & 0 deletions exporters/otlp/testing-internal/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dependencies {
implementation("com.linecorp.armeria:armeria-junit5")
implementation("io.github.netmikey.logunit:logunit-jul")
implementation("org.assertj:assertj-core")
implementation("org.mock-server:mockserver-netty")
}

// Skip OWASP dependencyCheck task on test module
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.cert.CertificateEncodingException;
Expand Down Expand Up @@ -84,6 +86,7 @@
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockserver.integration.ClientAndServer;
import org.slf4j.event.Level;
import org.slf4j.event.LoggingEvent;

Expand Down Expand Up @@ -655,6 +658,39 @@ void nonRetryableError(int code) {
assertThat(attempts).hasValue(1);
}

@Test
void proxy() {
// configure mockserver to proxy to the local OTLP server
InetSocketAddress serverSocketAddress = server.httpSocketAddress();
try (ClientAndServer clientAndServer =
ClientAndServer.startClientAndServer(
serverSocketAddress.getHostName(), serverSocketAddress.getPort())) {
TelemetryExporter<T> exporter =
exporterBuilder()
// Configure exporter with server endpoint, and proxy options to route through
// mockserver proxy
.setEndpoint(server.httpUri() + path)
.setProxyOptions(
ProxyOptions.create(
InetSocketAddress.createUnresolved("localhost", clientAndServer.getPort())))
.build();

try {
List<T> telemetry = Collections.singletonList(generateFakeTelemetry());

assertThat(exporter.export(telemetry).join(10, TimeUnit.SECONDS).isSuccess()).isTrue();
// assert that mock server received request
assertThat(clientAndServer.retrieveRecordedRequests(new org.mockserver.model.HttpRequest()))
.hasSize(1);
// assert that server received telemetry from proxy, and is as expected
List<U> expectedResourceTelemetry = toProto(telemetry);
assertThat(exportedResourceTelemetry).containsExactlyElementsOf(expectedResourceTelemetry);
} finally {
exporter.shutdown();
}
}
}

@Test
@SuppressWarnings("PreferJavaTimeOverload")
void validConfig() {
Expand Down Expand Up @@ -815,6 +851,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException {
+ "timeoutNanos="
+ TimeUnit.SECONDS.toNanos(10)
+ ", "
+ "proxyOptions=null, "
+ "compressorEncoding=null, "
+ "connectTimeoutNanos="
+ TimeUnit.SECONDS.toNanos(10)
Expand Down Expand Up @@ -855,6 +892,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException {
+ "timeoutNanos="
+ TimeUnit.SECONDS.toNanos(5)
+ ", "
+ "proxyOptions=null, "
+ "compressorEncoding=gzip, "
+ "connectTimeoutNanos="
+ TimeUnit.SECONDS.toNanos(4)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.grpc.ManagedChannel;
import io.opentelemetry.exporter.internal.auth.Authenticator;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import java.time.Duration;
Expand Down Expand Up @@ -44,7 +45,8 @@ public TelemetryExporterBuilder<LogRecordData> setTimeout(Duration timeout) {

@Override
public TelemetryExporterBuilder<LogRecordData> setConnectTimeout(long timeout, TimeUnit unit) {
throw new UnsupportedOperationException();
builder.setConnectTimeout(timeout, unit);
return this;
}

@Override
Expand Down Expand Up @@ -103,6 +105,11 @@ public TelemetryExporterBuilder<LogRecordData> setRetryPolicy(RetryPolicy retryP
return this;
}

@Override
public TelemetryExporterBuilder<LogRecordData> setProxyOptions(ProxyOptions proxyOptions) {
throw new UnsupportedOperationException("ProxyOptions are not supported for gRPC");
}

@Override
@SuppressWarnings("deprecation") // testing deprecated functionality
public TelemetryExporterBuilder<LogRecordData> setChannel(Object channel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.grpc.ManagedChannel;
import io.opentelemetry.exporter.internal.auth.Authenticator;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import io.opentelemetry.sdk.metrics.data.MetricData;
import java.time.Duration;
Expand Down Expand Up @@ -44,7 +45,8 @@ public TelemetryExporterBuilder<MetricData> setTimeout(Duration timeout) {

@Override
public TelemetryExporterBuilder<MetricData> setConnectTimeout(long timeout, TimeUnit unit) {
throw new UnsupportedOperationException();
builder.setConnectTimeout(timeout, unit);
return this;
}

@Override
Expand Down Expand Up @@ -103,6 +105,11 @@ public TelemetryExporterBuilder<MetricData> setRetryPolicy(RetryPolicy retryPoli
return this;
}

@Override
public TelemetryExporterBuilder<MetricData> setProxyOptions(ProxyOptions proxyOptions) {
throw new UnsupportedOperationException("ProxyOptions are not supported for gRPC");
}

@Override
@SuppressWarnings("deprecation") // testing deprecated functionality
public TelemetryExporterBuilder<MetricData> setChannel(Object channel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.grpc.ManagedChannel;
import io.opentelemetry.exporter.internal.auth.Authenticator;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.time.Duration;
Expand Down Expand Up @@ -45,7 +46,8 @@ public TelemetryExporterBuilder<SpanData> setTimeout(Duration timeout) {

@Override
public TelemetryExporterBuilder<SpanData> setConnectTimeout(long timeout, TimeUnit unit) {
throw new UnsupportedOperationException();
builder.setConnectTimeout(timeout, unit);
return this;
}

@Override
Expand Down Expand Up @@ -104,6 +106,11 @@ public TelemetryExporterBuilder<SpanData> setRetryPolicy(RetryPolicy retryPolicy
return this;
}

@Override
public TelemetryExporterBuilder<SpanData> setProxyOptions(ProxyOptions proxyOptions) {
throw new UnsupportedOperationException("ProxyOptions are not supported for gRPC");
}

@Override
@SuppressWarnings("deprecation") // testing deprecated functionality
public TelemetryExporterBuilder<SpanData> setChannel(Object channel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import io.opentelemetry.exporter.internal.auth.Authenticator;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import java.time.Duration;
Expand Down Expand Up @@ -106,6 +107,12 @@ public TelemetryExporterBuilder<LogRecordData> setRetryPolicy(RetryPolicy retryP
return this;
}

@Override
public TelemetryExporterBuilder<LogRecordData> setProxyOptions(ProxyOptions proxyOptions) {
builder.setProxyOptions(proxyOptions);
return this;
}

@Override
public TelemetryExporterBuilder<LogRecordData> setChannel(Object channel) {
throw new UnsupportedOperationException("Not implemented");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import io.opentelemetry.exporter.internal.auth.Authenticator;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.common.export.RetryPolicy;
import io.opentelemetry.sdk.metrics.data.MetricData;
import java.time.Duration;
Expand Down Expand Up @@ -105,6 +106,12 @@ public TelemetryExporterBuilder<MetricData> setRetryPolicy(RetryPolicy retryPoli
return this;
}

@Override
public TelemetryExporterBuilder<MetricData> setProxyOptions(ProxyOptions proxyOptions) {
builder.setProxyOptions(proxyOptions);
return this;
}

@Override
public TelemetryExporterBuilder<MetricData> setChannel(Object channel) {
throw new UnsupportedOperationException("Not implemented");
Expand Down
Loading

0 comments on commit e41470b

Please sign in to comment.