Use minimal fallback managed channel when none is specified (#6110)
This commit is contained in:
parent
b4ed53211b
commit
da7796b3b5
|
|
@ -85,6 +85,7 @@ public class OltpExporterBenchmark {
|
|||
"span",
|
||||
new UpstreamGrpcSender<>(
|
||||
MarshalerTraceServiceGrpc.newFutureStub(defaultGrpcChannel, null),
|
||||
/* shutdownChannel= */ false,
|
||||
10,
|
||||
Collections::emptyMap),
|
||||
MeterProvider::noop);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.exporter.otlp.testing.internal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.as;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
|
@ -23,8 +24,10 @@ import com.linecorp.armeria.server.logging.LoggingService;
|
|||
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
|
||||
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
|
||||
import io.github.netmikey.logunit.api.LogCapturer;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.opentelemetry.exporter.internal.TlsUtil;
|
||||
import io.opentelemetry.exporter.internal.grpc.GrpcExporter;
|
||||
import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub;
|
||||
import io.opentelemetry.exporter.internal.marshal.Marshaler;
|
||||
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
|
||||
import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest;
|
||||
|
|
@ -61,6 +64,7 @@ import javax.net.ssl.SSLContext;
|
|||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509KeyManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.assertj.core.api.iterable.ThrowingExtractor;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
|
@ -215,6 +219,23 @@ public abstract class AbstractGrpcTelemetryExporterTest<T, U extends Message> {
|
|||
httpRequests.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
void minimalChannel() {
|
||||
// Test that UpstreamGrpcSender uses minimal fallback managed channel, so skip for
|
||||
// OkHttpGrpcSender
|
||||
assumeThat(exporter.unwrap())
|
||||
.extracting("delegate.grpcSender")
|
||||
.matches(sender -> sender.getClass().getSimpleName().equals("UpstreamGrpcSender"));
|
||||
// When no channel is explicitly set, should fall back to a minimally configured managed channel
|
||||
TelemetryExporter<?> exporter = exporterBuilder().build();
|
||||
assertThat(exporter.shutdown().join(10, TimeUnit.SECONDS).isSuccess()).isTrue();
|
||||
assertThat(exporter.unwrap())
|
||||
.extracting(
|
||||
"delegate.grpcSender.stub",
|
||||
as(InstanceOfAssertFactories.type(MarshalerServiceStub.class)))
|
||||
.satisfies(stub -> assertThat(((ManagedChannel) stub.getChannel()).isShutdown()).isTrue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void export() {
|
||||
List<T> telemetry = Collections.singletonList(generateFakeTelemetry());
|
||||
|
|
|
|||
|
|
@ -158,16 +158,21 @@ public final class ManagedChannelTelemetryExporterBuilder<T>
|
|||
|
||||
@Override
|
||||
public TelemetryExporter<T> build() {
|
||||
requireNonNull(channelBuilder, "channel");
|
||||
Runnable shutdownCallback;
|
||||
if (channelBuilder != null) {
|
||||
try {
|
||||
setSslContext(channelBuilder, tlsConfigHelper);
|
||||
} catch (SSLException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
try {
|
||||
setSslContext(channelBuilder, tlsConfigHelper);
|
||||
} catch (SSLException e) {
|
||||
throw new IllegalStateException(e);
|
||||
ManagedChannel channel = channelBuilder.build();
|
||||
delegate.setChannel(channel);
|
||||
shutdownCallback = channel::shutdownNow;
|
||||
} else {
|
||||
shutdownCallback = () -> {};
|
||||
}
|
||||
|
||||
ManagedChannel channel = channelBuilder.build();
|
||||
delegate.setChannel(channel);
|
||||
TelemetryExporter<T> delegateExporter = delegate.build();
|
||||
return new TelemetryExporter<T>() {
|
||||
@Override
|
||||
|
|
@ -182,7 +187,7 @@ public final class ManagedChannelTelemetryExporterBuilder<T>
|
|||
|
||||
@Override
|
||||
public CompletableResultCode shutdown() {
|
||||
channel.shutdownNow();
|
||||
shutdownCallback.run();
|
||||
return delegateExporter.shutdown();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.exporter.sender.grpc.managedchannel.internal;
|
|||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.stub.MetadataUtils;
|
||||
|
|
@ -32,16 +33,19 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
public final class UpstreamGrpcSender<T extends Marshaler> implements GrpcSender<T> {
|
||||
|
||||
private final MarshalerServiceStub<T, ?, ?> stub;
|
||||
private final boolean shutdownChannel;
|
||||
private final long timeoutNanos;
|
||||
private final Supplier<Map<String, List<String>>> headersSupplier;
|
||||
|
||||
/** Creates a new {@link UpstreamGrpcSender}. */
|
||||
public UpstreamGrpcSender(
|
||||
MarshalerServiceStub<T, ?, ?> stub,
|
||||
boolean shutdownChannel,
|
||||
long timeoutNanos,
|
||||
Supplier<Map<String, List<String>>> headersSupplier) {
|
||||
this.timeoutNanos = timeoutNanos;
|
||||
this.stub = stub;
|
||||
this.shutdownChannel = shutdownChannel;
|
||||
this.timeoutNanos = timeoutNanos;
|
||||
this.headersSupplier = headersSupplier;
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +86,10 @@ public final class UpstreamGrpcSender<T extends Marshaler> implements GrpcSender
|
|||
|
||||
@Override
|
||||
public CompletableResultCode shutdown() {
|
||||
if (shutdownChannel) {
|
||||
ManagedChannel channel = (ManagedChannel) stub.getChannel();
|
||||
channel.shutdownNow();
|
||||
}
|
||||
return CompletableResultCode.ofSuccess();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ package io.opentelemetry.exporter.sender.grpc.managedchannel.internal;
|
|||
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.Codec;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import io.opentelemetry.exporter.internal.grpc.GrpcSender;
|
||||
import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider;
|
||||
import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub;
|
||||
|
|
@ -41,6 +43,13 @@ public class UpstreamGrpcSenderProvider implements GrpcSenderProvider {
|
|||
@Nullable RetryPolicy retryPolicy,
|
||||
@Nullable SSLContext sslContext,
|
||||
@Nullable X509TrustManager trustManager) {
|
||||
boolean shutdownChannel = false;
|
||||
if (managedChannel == null) {
|
||||
// Shutdown the channel as part of the exporter shutdown sequence if
|
||||
shutdownChannel = true;
|
||||
managedChannel = minimalFallbackManagedChannel(endpoint);
|
||||
}
|
||||
|
||||
String authorityOverride = null;
|
||||
Map<String, List<String>> headers = headersSupplier.get();
|
||||
if (headers != null) {
|
||||
|
|
@ -58,6 +67,27 @@ public class UpstreamGrpcSenderProvider implements GrpcSenderProvider {
|
|||
.apply((Channel) managedChannel, authorityOverride)
|
||||
.withCompression(codec.getMessageEncoding());
|
||||
|
||||
return new UpstreamGrpcSender<>(stub, timeoutNanos, headersSupplier);
|
||||
return new UpstreamGrpcSender<>(stub, shutdownChannel, timeoutNanos, headersSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link ManagedChannel} is not explicitly set, provide a minimally configured fallback
|
||||
* channel to avoid failing initialization.
|
||||
*
|
||||
* <p>This is required to accommodate autoconfigure with {@code
|
||||
* opentelemetry-exporter-sender-grpc-managed-channel} which will always fail to initialize
|
||||
* without a fallback channel since there isn't an opportunity to explicitly set the channel.
|
||||
*
|
||||
* <p>This only incorporates the target address, port, and whether to use plain text. All
|
||||
* additional settings are intentionally ignored and must be configured with an explicitly set
|
||||
* {@link ManagedChannel}.
|
||||
*/
|
||||
private static ManagedChannel minimalFallbackManagedChannel(URI endpoint) {
|
||||
ManagedChannelBuilder<?> channelBuilder =
|
||||
ManagedChannelBuilder.forAddress(endpoint.getHost(), endpoint.getPort());
|
||||
if (!endpoint.getScheme().equals("https")) {
|
||||
channelBuilder.usePlaintext();
|
||||
}
|
||||
return channelBuilder.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue