Add basic proxy configuration to OtlpHttp{Signal}Exporters (#6270)
Co-authored-by: Marc Schumacher <schumi@zalando.de>
This commit is contained in:
parent
f24acbdd7f
commit
e41470be43
|
@ -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",
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -13,6 +13,7 @@ import io.opentelemetry.exporter.internal.TlsConfigHelper;
|
|||
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;
|
||||
|
@ -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;
|
||||
|
@ -131,6 +133,11 @@ public final class HttpExporterBuilder<T extends Marshaler> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public HttpExporterBuilder<T> setProxyOptions(ProxyOptions proxyOptions) {
|
||||
this.proxyOptions = proxyOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpExporterBuilder<T> exportAsJson() {
|
||||
this.exportAsJson = true;
|
||||
return this;
|
||||
|
@ -152,6 +159,7 @@ public final class HttpExporterBuilder<T extends Marshaler> {
|
|||
}
|
||||
copy.meterProviderSupplier = meterProviderSupplier;
|
||||
copy.authenticator = authenticator;
|
||||
copy.proxyOptions = proxyOptions;
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
@ -187,6 +195,7 @@ public final class HttpExporterBuilder<T extends Marshaler> {
|
|||
timeoutNanos,
|
||||
connectTimeoutNanos,
|
||||
headerSupplier,
|
||||
proxyOptions,
|
||||
authenticator,
|
||||
retryPolicy,
|
||||
tlsConfigHelper.getSslContext(),
|
||||
|
@ -205,6 +214,7 @@ public final class HttpExporterBuilder<T extends Marshaler> {
|
|||
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));
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.exporter.internal.http;
|
|||
|
||||
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;
|
||||
|
@ -34,6 +35,7 @@ public interface HttpSenderProvider {
|
|||
long timeoutNanos,
|
||||
long connectTimeout,
|
||||
Supplier<Map<String, List<String>>> headerSupplier,
|
||||
@Nullable ProxyOptions proxyOptions,
|
||||
@Nullable Authenticator authenticator,
|
||||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable SSLContext sslContext,
|
||||
|
|
|
@ -16,6 +16,7 @@ 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.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;
|
||||
|
@ -171,6 +172,13 @@ public final class OtlpHttpLogRecordExporterBuilder {
|
|||
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()}.
|
||||
|
|
|
@ -15,6 +15,7 @@ import io.opentelemetry.exporter.internal.compression.CompressorUtil;
|
|||
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;
|
||||
|
@ -215,6 +216,13 @@ public final class OtlpHttpMetricExporterBuilder {
|
|||
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;
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.opentelemetry.exporter.internal.compression.CompressorUtil;
|
|||
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;
|
||||
|
@ -172,6 +173,13 @@ public final class OtlpHttpSpanExporterBuilder {
|
|||
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()}.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -39,12 +39,14 @@ import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse;
|
|||
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;
|
||||
|
@ -84,6 +86,7 @@ import org.junit.jupiter.params.provider.Arguments;
|
|||
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;
|
||||
|
||||
|
@ -655,6 +658,39 @@ public abstract class AbstractHttpTelemetryExporterTest<T, U extends Message> {
|
|||
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() {
|
||||
|
@ -815,6 +851,7 @@ public abstract class AbstractHttpTelemetryExporterTest<T, U extends Message> {
|
|||
+ "timeoutNanos="
|
||||
+ TimeUnit.SECONDS.toNanos(10)
|
||||
+ ", "
|
||||
+ "proxyOptions=null, "
|
||||
+ "compressorEncoding=null, "
|
||||
+ "connectTimeoutNanos="
|
||||
+ TimeUnit.SECONDS.toNanos(10)
|
||||
|
@ -855,6 +892,7 @@ public abstract class AbstractHttpTelemetryExporterTest<T, U extends Message> {
|
|||
+ "timeoutNanos="
|
||||
+ TimeUnit.SECONDS.toNanos(5)
|
||||
+ ", "
|
||||
+ "proxyOptions=null, "
|
||||
+ "compressorEncoding=gzip, "
|
||||
+ "connectTimeoutNanos="
|
||||
+ TimeUnit.SECONDS.toNanos(4)
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.exporter.otlp.testing.internal;
|
|||
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;
|
||||
|
@ -44,7 +45,8 @@ final class GrpcLogRecordExporterBuilderWrapper implements TelemetryExporterBuil
|
|||
|
||||
@Override
|
||||
public TelemetryExporterBuilder<LogRecordData> setConnectTimeout(long timeout, TimeUnit unit) {
|
||||
throw new UnsupportedOperationException();
|
||||
builder.setConnectTimeout(timeout, unit);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,6 +105,11 @@ final class GrpcLogRecordExporterBuilderWrapper implements TelemetryExporterBuil
|
|||
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) {
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.exporter.otlp.testing.internal;
|
|||
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;
|
||||
|
@ -44,7 +45,8 @@ final class GrpcMetricExporterBuilderWrapper implements TelemetryExporterBuilder
|
|||
|
||||
@Override
|
||||
public TelemetryExporterBuilder<MetricData> setConnectTimeout(long timeout, TimeUnit unit) {
|
||||
throw new UnsupportedOperationException();
|
||||
builder.setConnectTimeout(timeout, unit);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,6 +105,11 @@ final class GrpcMetricExporterBuilderWrapper implements TelemetryExporterBuilder
|
|||
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) {
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.exporter.otlp.testing.internal;
|
|||
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;
|
||||
|
@ -45,7 +46,8 @@ final class GrpcSpanExporterBuilderWrapper implements TelemetryExporterBuilder<S
|
|||
|
||||
@Override
|
||||
public TelemetryExporterBuilder<SpanData> setConnectTimeout(long timeout, TimeUnit unit) {
|
||||
throw new UnsupportedOperationException();
|
||||
builder.setConnectTimeout(timeout, unit);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,6 +106,11 @@ final class GrpcSpanExporterBuilderWrapper implements TelemetryExporterBuilder<S
|
|||
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) {
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.exporter.otlp.testing.internal;
|
|||
|
||||
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;
|
||||
|
@ -106,6 +107,12 @@ public class HttpLogRecordExporterBuilderWrapper
|
|||
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");
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.exporter.otlp.testing.internal;
|
|||
|
||||
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;
|
||||
|
@ -105,6 +106,12 @@ public class HttpMetricExporterBuilderWrapper implements TelemetryExporterBuilde
|
|||
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");
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.exporter.otlp.testing.internal;
|
|||
|
||||
import io.opentelemetry.exporter.internal.auth.Authenticator;
|
||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
|
||||
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;
|
||||
|
@ -105,6 +106,12 @@ public class HttpSpanExporterBuilderWrapper implements TelemetryExporterBuilder<
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TelemetryExporterBuilder<SpanData> setProxyOptions(ProxyOptions proxyOptions) {
|
||||
builder.setProxy(proxyOptions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TelemetryExporterBuilder<SpanData> setChannel(Object channel) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
|
|
|
@ -17,6 +17,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator;
|
|||
import io.opentelemetry.exporter.internal.grpc.ManagedChannelUtil;
|
||||
import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.common.export.ProxyOptions;
|
||||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
|
@ -151,6 +152,12 @@ public final class ManagedChannelTelemetryExporterBuilder<T>
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TelemetryExporterBuilder<T> setProxyOptions(ProxyOptions proxyOptions) {
|
||||
delegate.setProxyOptions(proxyOptions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TelemetryExporterBuilder<T> setChannel(Object channel) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator;
|
|||
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.common.export.ProxyOptions;
|
||||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import io.opentelemetry.sdk.logs.data.LogRecordData;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
|
@ -60,6 +61,8 @@ public interface TelemetryExporterBuilder<T> {
|
|||
|
||||
TelemetryExporterBuilder<T> setRetryPolicy(RetryPolicy retryPolicy);
|
||||
|
||||
TelemetryExporterBuilder<T> setProxyOptions(ProxyOptions proxyOptions);
|
||||
|
||||
TelemetryExporterBuilder<T> setChannel(Object channel);
|
||||
|
||||
TelemetryExporter<T> build();
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.compression.Compressor;
|
|||
import io.opentelemetry.exporter.internal.http.HttpSender;
|
||||
import io.opentelemetry.exporter.internal.marshal.Marshaler;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.common.export.ProxyOptions;
|
||||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -94,9 +95,10 @@ public final class JdkHttpSender implements HttpSender {
|
|||
long connectTimeoutNanos,
|
||||
Supplier<Map<String, List<String>>> headerSupplier,
|
||||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable ProxyOptions proxyOptions,
|
||||
@Nullable SSLContext sslContext) {
|
||||
this(
|
||||
configureClient(sslContext, connectTimeoutNanos),
|
||||
configureClient(sslContext, connectTimeoutNanos, proxyOptions),
|
||||
endpoint,
|
||||
compressor,
|
||||
exportAsJson,
|
||||
|
@ -107,12 +109,17 @@ public final class JdkHttpSender implements HttpSender {
|
|||
}
|
||||
|
||||
private static HttpClient configureClient(
|
||||
@Nullable SSLContext sslContext, long connectionTimeoutNanos) {
|
||||
@Nullable SSLContext sslContext,
|
||||
long connectionTimeoutNanos,
|
||||
@Nullable ProxyOptions proxyOptions) {
|
||||
HttpClient.Builder builder =
|
||||
HttpClient.newBuilder().connectTimeout(Duration.ofNanos(connectionTimeoutNanos));
|
||||
if (sslContext != null) {
|
||||
builder.sslContext(sslContext);
|
||||
}
|
||||
if (proxyOptions != null) {
|
||||
builder.proxy(proxyOptions.getProxySelector());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator;
|
|||
import io.opentelemetry.exporter.internal.compression.Compressor;
|
||||
import io.opentelemetry.exporter.internal.http.HttpSender;
|
||||
import io.opentelemetry.exporter.internal.http.HttpSenderProvider;
|
||||
import io.opentelemetry.sdk.common.export.ProxyOptions;
|
||||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -34,6 +35,7 @@ public final class JdkHttpSenderProvider implements HttpSenderProvider {
|
|||
long timeoutNanos,
|
||||
long connectTimeout,
|
||||
Supplier<Map<String, List<String>>> headerSupplier,
|
||||
@Nullable ProxyOptions proxyOptions,
|
||||
@Nullable Authenticator authenticator,
|
||||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable SSLContext sslContext,
|
||||
|
@ -47,6 +49,7 @@ public final class JdkHttpSenderProvider implements HttpSenderProvider {
|
|||
connectTimeout,
|
||||
headerSupplier,
|
||||
retryPolicy,
|
||||
proxyOptions,
|
||||
sslContext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ class JdkHttpSenderTest {
|
|||
TimeUnit.SECONDS.toNanos(10),
|
||||
Collections::emptyMap,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
|
||||
assertThat(sender)
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.opentelemetry.exporter.internal.compression.Compressor;
|
|||
import io.opentelemetry.exporter.internal.http.HttpSender;
|
||||
import io.opentelemetry.exporter.internal.marshal.Marshaler;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.common.export.ProxyOptions;
|
||||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
|
@ -58,6 +59,7 @@ public final class OkHttpHttpSender implements HttpSender {
|
|||
long timeoutNanos,
|
||||
long connectionTimeoutNanos,
|
||||
Supplier<Map<String, List<String>>> headerSupplier,
|
||||
@Nullable ProxyOptions proxyOptions,
|
||||
@Nullable Authenticator authenticator,
|
||||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable SSLContext sslContext,
|
||||
|
@ -68,6 +70,10 @@ public final class OkHttpHttpSender implements HttpSender {
|
|||
.connectTimeout(Duration.ofNanos(connectionTimeoutNanos))
|
||||
.callTimeout(Duration.ofNanos(timeoutNanos));
|
||||
|
||||
if (proxyOptions != null) {
|
||||
builder.proxySelector(proxyOptions.getProxySelector());
|
||||
}
|
||||
|
||||
if (authenticator != null) {
|
||||
Authenticator finalAuthenticator = authenticator;
|
||||
// Generate and attach OkHttp Authenticator implementation
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator;
|
|||
import io.opentelemetry.exporter.internal.compression.Compressor;
|
||||
import io.opentelemetry.exporter.internal.http.HttpSender;
|
||||
import io.opentelemetry.exporter.internal.http.HttpSenderProvider;
|
||||
import io.opentelemetry.sdk.common.export.ProxyOptions;
|
||||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -34,6 +35,7 @@ public final class OkHttpHttpSenderProvider implements HttpSenderProvider {
|
|||
long timeoutNanos,
|
||||
long connectTimeout,
|
||||
Supplier<Map<String, List<String>>> headerSupplier,
|
||||
@Nullable ProxyOptions proxyOptions,
|
||||
@Nullable Authenticator authenticator,
|
||||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable SSLContext sslContext,
|
||||
|
@ -46,6 +48,7 @@ public final class OkHttpHttpSenderProvider implements HttpSenderProvider {
|
|||
timeoutNanos,
|
||||
connectTimeout,
|
||||
headerSupplier,
|
||||
proxyOptions,
|
||||
authenticator,
|
||||
retryPolicy,
|
||||
sslContext,
|
||||
|
|
|
@ -46,6 +46,7 @@ class OkHttpHttpSuppressionTest extends AbstractOkHttpSuppressionTest<OkHttpHttp
|
|||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.sdk.common.export;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** Configuration for proxy settings. */
|
||||
public final class ProxyOptions {
|
||||
private final ProxySelector proxySelector;
|
||||
|
||||
private ProxyOptions(ProxySelector proxySelector) {
|
||||
this.proxySelector = proxySelector;
|
||||
}
|
||||
|
||||
/** Create proxy options with the {@code proxySelector}. */
|
||||
public static ProxyOptions create(ProxySelector proxySelector) {
|
||||
return new ProxyOptions(proxySelector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create proxy options with a {@link ProxySelector} which always uses an {@link Proxy.Type#HTTP}
|
||||
* proxy with the {@code socketAddress}.
|
||||
*/
|
||||
public static ProxyOptions create(InetSocketAddress socketAddress) {
|
||||
return new ProxyOptions(new SimpleProxySelector(new Proxy(Proxy.Type.HTTP, socketAddress)));
|
||||
}
|
||||
|
||||
/** Return the {@link ProxySelector}. */
|
||||
public ProxySelector getProxySelector() {
|
||||
return proxySelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProxyOptions{proxySelector=" + proxySelector + "}";
|
||||
}
|
||||
|
||||
private static final class SimpleProxySelector extends ProxySelector {
|
||||
|
||||
private final List<Proxy> proxyList;
|
||||
|
||||
private SimpleProxySelector(Proxy proxy) {
|
||||
this.proxyList = Collections.singletonList(proxy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Proxy> select(URI uri) {
|
||||
return proxyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SimpleProxySelector{proxy=" + proxyList.get(0).toString() + "}";
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue