Skip to content

Commit

Permalink
Add wrapped tracer implementation
Browse files Browse the repository at this point in the history
Signed-off-by: suranjay <surajkumar.tu@gmail.com>
  • Loading branch information
suranjay committed Jul 10, 2023
1 parent 9fd1ddb commit 394404a
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/**
* TracerManager represents a single global class that is used to access tracers.
*
* <p>
* The Tracer singleton object can be retrieved using tracerManager.getTracer(). The TracerManager object
* is created during class initialization and cannot subsequently be changed.
*/
Expand All @@ -30,21 +30,20 @@ public class TracerFactory implements Closeable {
private static final Logger logger = LogManager.getLogger(TracerFactory.class);

private final TelemetrySettings telemetrySettings;
private final Tracer defaultTracer;
private final Tracer tracer;

public TracerFactory(TelemetrySettings telemetrySettings, Optional<Telemetry> telemetry, ThreadContext threadContext) {
this.telemetrySettings = telemetrySettings;
this.defaultTracer = telemetry.map(Telemetry::getTracingTelemetry)
.map(tracingTelemetry -> createDefaultTracer(tracingTelemetry, threadContext))
.orElse(NoopTracer.INSTANCE);
this.tracer = tracer(telemetry, threadContext);
}

/**
* Returns the tracer instance
*
* @return tracer instance
*/
public Tracer getTracer() {
return telemetrySettings.isTracingEnabled() ? defaultTracer : NoopTracer.INSTANCE;
return tracer;
}

/**
Expand All @@ -53,12 +52,19 @@ public Tracer getTracer() {
@Override
public void close() {
try {
defaultTracer.close();
tracer.close();
} catch (IOException e) {
logger.warn("Error closing tracer", e);
}
}

private Tracer tracer(Optional<Telemetry> telemetry, ThreadContext threadContext) {
return telemetry.map(Telemetry::getTracingTelemetry)
.map(tracingTelemetry -> createDefaultTracer(tracingTelemetry, threadContext))
.map(defaultTracer -> createWrappedTracer(defaultTracer))
.orElse(NoopTracer.INSTANCE);
}

private Tracer createDefaultTracer(TracingTelemetry tracingTelemetry, ThreadContext threadContext) {
TracerContextStorage<String, Span> tracerContextStorage = new ThreadContextBasedTracerContextStorage(
threadContext,
Expand All @@ -67,4 +73,8 @@ private Tracer createDefaultTracer(TracingTelemetry tracingTelemetry, ThreadCont
return new DefaultTracer(tracingTelemetry, tracerContextStorage);
}

private Tracer createWrappedTracer(Tracer defaultTracer) {
return new WrappedTracer(telemetrySettings, defaultTracer);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.tracing;

import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.telemetry.tracing.noop.NoopTracer;

import java.io.IOException;

/**
* Wrapper implementation of Tracer. This delegates call to right tracer based on the tracer settings
*/
public class WrappedTracer implements Tracer {

private final Tracer defaultTracer;
private final TelemetrySettings telemetrySettings;

/**
* Creates WrappedTracer instance
*
* @param telemetrySettings telemetry settings
* @param defaultTracer default tracer instance
*/
public WrappedTracer(TelemetrySettings telemetrySettings, Tracer defaultTracer) {
this.defaultTracer = defaultTracer;
this.telemetrySettings = telemetrySettings;
}

@Override
public SpanScope startSpan(String spanName) {
Tracer delegateTracer = getDelegateTracer();
return delegateTracer.startSpan(spanName);
}

@Override
public void close() throws IOException {
defaultTracer.close();
}

// visible for testing
Tracer getDelegateTracer() {
return telemetrySettings.isTracingEnabled() ? defaultTracer : NoopTracer.INSTANCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,28 @@ public void close() {
tracerFactory.close();
}

public void testGetTracerWithTracingDisabledReturnsNoopTracer() {
public void testGetTracerWithUnavailableTracingTelemetryReturnsNoopTracer() {
Settings settings = Settings.builder().put(TelemetrySettings.TRACER_ENABLED_SETTING.getKey(), false).build();
TelemetrySettings telemetrySettings = new TelemetrySettings(settings, new ClusterSettings(settings, getClusterSettings()));
Telemetry mockTelemetry = mock(Telemetry.class);
when(mockTelemetry.getTracingTelemetry()).thenReturn(mock(TracingTelemetry.class));
tracerFactory = new TracerFactory(telemetrySettings, Optional.of(mockTelemetry), new ThreadContext(Settings.EMPTY));
tracerFactory = new TracerFactory(telemetrySettings, Optional.empty(), new ThreadContext(Settings.EMPTY));

Tracer tracer = tracerFactory.getTracer();

assertTrue(tracer instanceof NoopTracer);
assertTrue(tracer.startSpan("foo") == SpanScope.NO_OP);
}

public void testGetTracerWithTracingEnabledReturnsDefaultTracer() {
public void testGetTracerWithAvailableTracingTelemetryReturnsWrappedTracer() {
Settings settings = Settings.builder().put(TelemetrySettings.TRACER_ENABLED_SETTING.getKey(), true).build();
TelemetrySettings telemetrySettings = new TelemetrySettings(settings, new ClusterSettings(settings, getClusterSettings()));
Telemetry mockTelemetry = mock(Telemetry.class);
when(mockTelemetry.getTracingTelemetry()).thenReturn(mock(TracingTelemetry.class));
tracerFactory = new TracerFactory(telemetrySettings, Optional.of(mockTelemetry), new ThreadContext(Settings.EMPTY));

Tracer tracer = tracerFactory.getTracer();
assertTrue(tracer instanceof DefaultTracer);
assertTrue(tracer instanceof WrappedTracer);

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.tracing;

import org.opensearch.common.settings.ClusterSettings;
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.util.FeatureFlags;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.telemetry.tracing.noop.NoopTracer;
import org.opensearch.test.OpenSearchTestCase;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

public class WrappedTracerTests extends OpenSearchTestCase {

public void testStartSpanWithTracingDisabledInvokesNoopTracer() {
Settings settings = Settings.builder().put(TelemetrySettings.TRACER_ENABLED_SETTING.getKey(), false).build();
TelemetrySettings telemetrySettings = new TelemetrySettings(settings, new ClusterSettings(settings, getClusterSettings()));
DefaultTracer mockDefaultTracer = mock(DefaultTracer.class);

WrappedTracer wrappedTracer = spy(new WrappedTracer(telemetrySettings, mockDefaultTracer));

wrappedTracer.startSpan("foo");

assertTrue(wrappedTracer.getDelegateTracer() instanceof NoopTracer);
verify(mockDefaultTracer, never()).startSpan("foo");
}

public void testStartSpanWithTracingEnabledInvokesDefaultTracer() {
Settings settings = Settings.builder().put(TelemetrySettings.TRACER_ENABLED_SETTING.getKey(), true).build();
TelemetrySettings telemetrySettings = new TelemetrySettings(settings, new ClusterSettings(settings, getClusterSettings()));
DefaultTracer mockDefaultTracer = mock(DefaultTracer.class);

WrappedTracer wrappedTracer = spy(new WrappedTracer(telemetrySettings, mockDefaultTracer));

wrappedTracer.startSpan("foo");

assertTrue(wrappedTracer.getDelegateTracer() instanceof DefaultTracer);
verify(mockDefaultTracer).startSpan("foo");
}

public void testClose() throws IOException {
DefaultTracer mockDefaultTracer = mock(DefaultTracer.class);
WrappedTracer wrappedTracer = spy(new WrappedTracer(null, mockDefaultTracer));

wrappedTracer.close();

verify(mockDefaultTracer).close();
}

private Set<Setting<?>> getClusterSettings() {
Set<Setting<?>> allTracerSettings = new HashSet<>();
ClusterSettings.FEATURE_FLAGGED_CLUSTER_SETTINGS.get(List.of(FeatureFlags.TELEMETRY)).stream().forEach((allTracerSettings::add));
return allTracerSettings;
}
}

0 comments on commit 394404a

Please sign in to comment.