Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Add shutdown lifecycle method to `Sampler` to allow resource cleanup for stateful samplers.
([#8574](https://github.com/open-telemetry/opentelemetry-java/pull/8574))

## Version 1.63.0 (2026-06-05)

### API
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.64.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.63.0.jar
No changes.
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.CompletableResultCode shutdown()
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Comparing source compatibility of opentelemetry-sdk-trace-1.64.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.63.0.jar
No changes.
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.trace.samplers.Sampler (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.CompletableResultCode shutdown()
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.common.export.GrpcResponse;
import io.opentelemetry.sdk.common.export.GrpcSender;
import io.opentelemetry.sdk.common.export.GrpcStatusCode;
Expand Down Expand Up @@ -175,11 +176,16 @@ public static JaegerRemoteSamplerBuilder builder() {
return new JaegerRemoteSamplerBuilder();
}

@Override
public CompletableResultCode shutdown() {
pollFuture.cancel(false);
pollExecutor.shutdownNow();
return grpcSender.shutdown();
}

@Override
@SuppressWarnings("Interruption")
public void close() {
pollFuture.cancel(true);
pollExecutor.shutdownNow();
grpcSender.shutdown().join(10, TimeUnit.SECONDS);
shutdown().join(10, TimeUnit.SECONDS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,20 @@ void connectionWorks() {
}
}

@Test
void shutdown() {
JaegerRemoteSampler sampler =
JaegerRemoteSampler.builder()
.setEndpoint(server.httpUri().toString())
.setPollingInterval(1, TimeUnit.SECONDS)
.setServiceName(SERVICE_NAME)
.build();

assertThat(sampler).extracting("grpcSender").isInstanceOf(OkHttpGrpcSender.class);

assertThat(sampler.shutdown().join(10, TimeUnit.SECONDS).isSuccess()).isTrue();
}

@Test
void tlsConnectionWorks() throws IOException {
try (JaegerRemoteSampler sampler =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.opentelemetry.sdk.common.internal.ExceptionAttributeResolver;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -106,18 +107,28 @@ SdkTracerInstrumentation getTracerInstrumentation() {
}

/**
* Stops tracing, including shutting down processors and set to {@code true} {@link
* Stops tracing, including shutting down processors and sampler and set to {@code true} {@link
* #hasBeenShutdown()}.
*
* @return a {@link CompletableResultCode} that will be completed when the span processor is shut
* down.
* @return a {@link CompletableResultCode} that will be completed when the span processor and
* sampler are shut down.
*/
CompletableResultCode shutdown() {
synchronized (lock) {
if (shutdownResult != null) {
return shutdownResult;
}
shutdownResult = activeSpanProcessor.shutdown();

CompletableResultCode samplerShutdownResult = sampler.shutdown();

shutdownResult =
CompletableResultCode.ofAll(
Arrays.asList(
activeSpanProcessor.shutdown(),
samplerShutdownResult == null
? CompletableResultCode.ofSuccess()
: samplerShutdownResult));

return shutdownResult;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.data.LinkData;
import java.util.List;
import javax.annotation.concurrent.ThreadSafe;
Expand Down Expand Up @@ -119,4 +120,15 @@ SamplingResult shouldSample(
* @return the description of this {@code Sampler}.
*/
String getDescription();

/**
* Shuts down the sampler, releasing any resources held by it.
*
* <p>This method is called when the {@code SdkTracerProvider} is shut down.
*
* @return a {@link CompletableResultCode} which is completed when shutdown is finished.
*/
default CompletableResultCode shutdown() {
return CompletableResultCode.ofSuccess();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,19 @@ void shutdown() {
Mockito.verify(spanProcessor, Mockito.times(1)).shutdown();
}

@Test
void shutdown_ShutsDownSampler() {
Sampler sampler = mock(Sampler.class);

when(sampler.shutdown()).thenReturn(CompletableResultCode.ofSuccess());

SdkTracerProvider tracerProvider = SdkTracerProvider.builder().setSampler(sampler).build();

tracerProvider.shutdown();

verify(sampler).shutdown();
}

@Test
void close() {
tracerProvider.close();
Expand Down
Loading