diff --git a/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/OTelTelemetryPlugin.java b/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/OTelTelemetryPlugin.java index e8fc3fe53b1ef..479b0088879cc 100644 --- a/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/OTelTelemetryPlugin.java +++ b/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/OTelTelemetryPlugin.java @@ -68,7 +68,10 @@ public String getName() { private Telemetry telemetry(TelemetrySettings telemetrySettings) { final OpenTelemetrySdk openTelemetry = OTelResourceProvider.get(telemetrySettings, settings); - return new OTelTelemetry(new OTelTracingTelemetry(openTelemetry), new OTelMetricsTelemetry(openTelemetry)); + return new OTelTelemetry( + new OTelTracingTelemetry(openTelemetry, () -> openTelemetry.getSdkTracerProvider().close()), + new OTelMetricsTelemetry(openTelemetry, () -> openTelemetry.getSdkMeterProvider().close()) + ); } } diff --git a/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetry.java b/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetry.java index 5538f5b3625e4..c0260de1489d9 100644 --- a/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetry.java +++ b/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetry.java @@ -12,29 +12,32 @@ import org.apache.logging.log4j.Logger; import org.opensearch.telemetry.OTelTelemetryPlugin; +import java.io.Closeable; import java.security.AccessController; import java.security.PrivilegedAction; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.DoubleUpDownCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.sdk.OpenTelemetrySdk; /** * OTel implementation for {@link MetricsTelemetry} */ public class OTelMetricsTelemetry implements MetricsTelemetry { private static final Logger logger = LogManager.getLogger(OTelMetricsTelemetry.class); - private final OpenTelemetrySdk openTelemetry; + private final OpenTelemetry openTelemetry; private final Meter otelMeter; + private final Closeable metricsProviderClosable; /** * Constructor. * @param openTelemetry telemetry. */ - public OTelMetricsTelemetry(OpenTelemetrySdk openTelemetry) { + public OTelMetricsTelemetry(OpenTelemetry openTelemetry, Closeable metricsProviderClosable) { this.openTelemetry = openTelemetry; this.otelMeter = openTelemetry.getMeter(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME); + this.metricsProviderClosable = metricsProviderClosable; } @Override @@ -63,11 +66,10 @@ public Counter createUpDownCounter(String name, String description, String unit) @Override public void close() { - // There is no harm closing the openTelemetry multiple times. try { - openTelemetry.getSdkMeterProvider().close(); + metricsProviderClosable.close(); } catch (Exception e) { - logger.warn("Error while closing Opentelemetry", e); + logger.warn("Error while closing Opentelemetry MeterProvider", e); } } } diff --git a/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/tracing/OTelTracingTelemetry.java b/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/tracing/OTelTracingTelemetry.java index ea7bce5080e76..00a3736c957ca 100644 --- a/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/tracing/OTelTracingTelemetry.java +++ b/plugins/telemetry-otel/src/main/java/org/opensearch/telemetry/tracing/OTelTracingTelemetry.java @@ -13,8 +13,10 @@ import org.opensearch.telemetry.OTelAttributesConverter; import org.opensearch.telemetry.OTelTelemetryPlugin; +import java.io.Closeable; + +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.OpenTelemetrySdk; /** * OTel based Telemetry provider @@ -22,25 +24,26 @@ public class OTelTracingTelemetry implements TracingTelemetry { private static final Logger logger = LogManager.getLogger(OTelTracingTelemetry.class); - private final OpenTelemetrySdk openTelemetry; + private final OpenTelemetry openTelemetry; + private final Closeable tracerProviderClosable; private final io.opentelemetry.api.trace.Tracer otelTracer; /** * Creates OTel based Telemetry * @param openTelemetry OpenTelemetry instance */ - public OTelTracingTelemetry(OpenTelemetrySdk openTelemetry) { + public OTelTracingTelemetry(OpenTelemetry openTelemetry, Closeable tracerProviderClosable) { this.openTelemetry = openTelemetry; this.otelTracer = openTelemetry.getTracer(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME); - + this.tracerProviderClosable = tracerProviderClosable; } @Override public void close() { try { - openTelemetry.getSdkTracerProvider().close(); + tracerProviderClosable.close(); } catch (Exception e) { - logger.warn("Error while closing Opentelemetry", e); + logger.warn("Error while closing Opentelemetry TracerProvider", e); } } diff --git a/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/OTelTelemetryPluginTests.java b/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/OTelTelemetryPluginTests.java index 2a6b9d687d2d9..967d2e8495d81 100644 --- a/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/OTelTelemetryPluginTests.java +++ b/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/OTelTelemetryPluginTests.java @@ -78,5 +78,6 @@ public void testGetTelemetry() { @After public void cleanup() { tracingTelemetry.close(); + metricsTelemetry.close(); } } diff --git a/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetryTests.java b/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetryTests.java index cf398e3467401..fcdb5f3609c6d 100644 --- a/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetryTests.java +++ b/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/metrics/OTelMetricsTelemetryTests.java @@ -13,6 +13,9 @@ import org.opensearch.telemetry.metrics.tags.Tags; import org.opensearch.test.OpenSearchTestCase; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.DoubleUpDownCounter; @@ -20,7 +23,6 @@ import io.opentelemetry.api.metrics.LongCounterBuilder; import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.sdk.OpenTelemetrySdk; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -32,14 +34,14 @@ public void testCounter() { String counterName = "test-counter"; String description = "test"; String unit = "1"; - OpenTelemetrySdk mockOpenTelemetry = mock(OpenTelemetrySdk.class); + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); Meter mockMeter = mock(Meter.class); DoubleCounter mockOTelDoubleCounter = mock(DoubleCounter.class); LongCounterBuilder mockOTelLongCounterBuilder = mock(LongCounterBuilder.class); DoubleCounterBuilder mockOTelDoubleCounterBuilder = mock(DoubleCounterBuilder.class); when(mockOpenTelemetry.getMeter(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME)).thenReturn(mockMeter); - MetricsTelemetry metricsTelemetry = new OTelMetricsTelemetry(mockOpenTelemetry); + MetricsTelemetry metricsTelemetry = new OTelMetricsTelemetry(mockOpenTelemetry, () -> {}); when(mockMeter.counterBuilder(counterName)).thenReturn(mockOTelLongCounterBuilder); when(mockOTelLongCounterBuilder.setDescription(description)).thenReturn(mockOTelLongCounterBuilder); when(mockOTelLongCounterBuilder.setUnit(unit)).thenReturn(mockOTelLongCounterBuilder); @@ -58,14 +60,14 @@ public void testCounterNegativeValue() { String counterName = "test-counter"; String description = "test"; String unit = "1"; - OpenTelemetrySdk mockOpenTelemetry = mock(OpenTelemetrySdk.class); + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); Meter mockMeter = mock(Meter.class); DoubleCounter mockOTelDoubleCounter = mock(DoubleCounter.class); LongCounterBuilder mockOTelLongCounterBuilder = mock(LongCounterBuilder.class); DoubleCounterBuilder mockOTelDoubleCounterBuilder = mock(DoubleCounterBuilder.class); when(mockOpenTelemetry.getMeter(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME)).thenReturn(mockMeter); - MetricsTelemetry metricsTelemetry = new OTelMetricsTelemetry(mockOpenTelemetry); + MetricsTelemetry metricsTelemetry = new OTelMetricsTelemetry(mockOpenTelemetry, () -> {}); when(mockMeter.counterBuilder(counterName)).thenReturn(mockOTelLongCounterBuilder); when(mockOTelLongCounterBuilder.setDescription(description)).thenReturn(mockOTelLongCounterBuilder); when(mockOTelLongCounterBuilder.setUnit(unit)).thenReturn(mockOTelLongCounterBuilder); @@ -81,14 +83,14 @@ public void testUpDownCounter() { String counterName = "test-counter"; String description = "test"; String unit = "1"; - OpenTelemetrySdk mockOpenTelemetry = mock(OpenTelemetrySdk.class); + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); Meter mockMeter = mock(Meter.class); DoubleUpDownCounter mockOTelUpDownDoubleCounter = mock(DoubleUpDownCounter.class); LongUpDownCounterBuilder mockOTelLongUpDownCounterBuilder = mock(LongUpDownCounterBuilder.class); DoubleUpDownCounterBuilder mockOTelDoubleUpDownCounterBuilder = mock(DoubleUpDownCounterBuilder.class); when(mockOpenTelemetry.getMeter(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME)).thenReturn(mockMeter); - MetricsTelemetry metricsTelemetry = new OTelMetricsTelemetry(mockOpenTelemetry); + MetricsTelemetry metricsTelemetry = new OTelMetricsTelemetry(mockOpenTelemetry, () -> {}); when(mockMeter.upDownCounterBuilder(counterName)).thenReturn(mockOTelLongUpDownCounterBuilder); when(mockOTelLongUpDownCounterBuilder.setDescription(description)).thenReturn(mockOTelLongUpDownCounterBuilder); when(mockOTelLongUpDownCounterBuilder.setUnit(unit)).thenReturn(mockOTelLongUpDownCounterBuilder); @@ -102,4 +104,12 @@ public void testUpDownCounter() { counter.add(-2.0, tags); verify(mockOTelUpDownDoubleCounter).add((-2.0), OTelAttributesConverter.convert(tags)); } + + public void testClose() { + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); + final AtomicBoolean closed = new AtomicBoolean(false); + MetricsTelemetry metricsTelemetry = new OTelMetricsTelemetry(mockOpenTelemetry, () -> closed.set(true)); + metricsTelemetry.close(); + assertTrue(closed.get()); + } } diff --git a/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/tracing/OTelTracingTelemetryTests.java b/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/tracing/OTelTracingTelemetryTests.java index d9d66f4ab4098..8bf1f2d8a1805 100644 --- a/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/tracing/OTelTracingTelemetryTests.java +++ b/plugins/telemetry-otel/src/test/java/org/opensearch/telemetry/tracing/OTelTracingTelemetryTests.java @@ -14,11 +14,12 @@ import java.util.Collections; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.sdk.OpenTelemetrySdk; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -27,9 +28,8 @@ import static org.mockito.Mockito.when; public class OTelTracingTelemetryTests extends OpenSearchTestCase { - public void testCreateSpanWithoutParent() { - OpenTelemetrySdk mockOpenTelemetry = mock(OpenTelemetrySdk.class); + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); Tracer mockTracer = mock(Tracer.class); when(mockOpenTelemetry.getTracer(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME)).thenReturn(mockTracer); SpanBuilder mockSpanBuilder = mock(SpanBuilder.class); @@ -39,7 +39,7 @@ public void testCreateSpanWithoutParent() { when(mockSpanBuilder.setSpanKind(any(io.opentelemetry.api.trace.SpanKind.class))).thenReturn(mockSpanBuilder); Map attributeMap = Collections.singletonMap("name", "value"); Attributes attributes = Attributes.create().addAttribute("name", "value"); - TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry); + TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry, () -> {}); Span span = tracingTelemetry.createSpan(SpanCreationContext.internal().name("span_name").attributes(attributes), null); verify(mockSpanBuilder, never()).setParent(any()); verify(mockSpanBuilder).setAllAttributes(createAttribute(attributes)); @@ -47,7 +47,7 @@ public void testCreateSpanWithoutParent() { } public void testCreateSpanWithParent() { - OpenTelemetrySdk mockOpenTelemetry = mock(OpenTelemetrySdk.class); + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); Tracer mockTracer = mock(Tracer.class); when(mockOpenTelemetry.getTracer(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME)).thenReturn(mockTracer); SpanBuilder mockSpanBuilder = mock(SpanBuilder.class); @@ -59,7 +59,7 @@ public void testCreateSpanWithParent() { Span parentSpan = new OTelSpan("parent_span", mock(io.opentelemetry.api.trace.Span.class), null); - TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry); + TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry, () -> {}); Attributes attributes = Attributes.create().addAttribute("name", 1l); Span span = tracingTelemetry.createSpan(SpanCreationContext.internal().name("span_name").attributes(attributes), parentSpan); @@ -71,7 +71,7 @@ public void testCreateSpanWithParent() { } public void testCreateSpanWithParentWithMultipleAttributes() { - OpenTelemetrySdk mockOpenTelemetry = mock(OpenTelemetrySdk.class); + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); Tracer mockTracer = mock(Tracer.class); when(mockOpenTelemetry.getTracer(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME)).thenReturn(mockTracer); SpanBuilder mockSpanBuilder = mock(SpanBuilder.class); @@ -83,7 +83,7 @@ public void testCreateSpanWithParentWithMultipleAttributes() { Span parentSpan = new OTelSpan("parent_span", mock(io.opentelemetry.api.trace.Span.class), null); - TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry); + TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry, () -> {}); Attributes attributes = Attributes.create() .addAttribute("key1", 1l) .addAttribute("key2", 2.0) @@ -117,13 +117,21 @@ private io.opentelemetry.api.common.Attributes createAttributeLong(Attributes at } public void testGetContextPropagator() { - OpenTelemetrySdk mockOpenTelemetry = mock(OpenTelemetrySdk.class); + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); Tracer mockTracer = mock(Tracer.class); when(mockOpenTelemetry.getTracer(OTelTelemetryPlugin.INSTRUMENTATION_SCOPE_NAME)).thenReturn(mockTracer); - TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry); + TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry, () -> {}); assertTrue(tracingTelemetry.getContextPropagator() instanceof OTelTracingContextPropagator); } + public void testClose() { + OpenTelemetry mockOpenTelemetry = mock(OpenTelemetry.class); + final AtomicBoolean closed = new AtomicBoolean(false); + TracingTelemetry tracingTelemetry = new OTelTracingTelemetry(mockOpenTelemetry, () -> closed.set(true)); + tracingTelemetry.close(); + assertTrue(closed.get()); + } + }