Skip to content

Commit

Permalink
Allow multiple instances of OpenTelemetry primary objects
Browse files Browse the repository at this point in the history
Signed-off-by: Pavol Loffay <[email protected]>
  • Loading branch information
pavolloffay committed May 27, 2019
1 parent c026320 commit 7fe173b
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 44 deletions.
71 changes: 54 additions & 17 deletions api/src/main/java/io/opentelemetry/OpenTelemetry.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* This class provides a static global accessor for telemetry objects {@link Tracer}, {@link Meter}
* and {@link Tagger}.
*
* <p>The telemetry objects are lazy-loaded singletons resolved via {@link ServiceLoader} mechanism.
* <p>The telemetry objects are resolved via {@link ServiceLoader} mechanism.
*
* @see TracerProvider
* @see MeterProvider
Expand All @@ -42,41 +42,47 @@ public final class OpenTelemetry {

@Nullable private static volatile OpenTelemetry instance;

private final Tracer tracer;
private final Meter meter;
private final Tagger tagger;
private final TracerProvider tracerProvider;
private final MeterProvider meterProvider;
private final TaggerProvider taggerProvider;

/**
* Returns a singleton {@link Tracer}.
* Returns an instance of {@link Tracer}. In a single deployment runtime a singleton is returned,
* however in an application server with multiple deployments a different instance can be used per
* deployment.
*
* @return registered tracer or default via {@link DefaultTracer#getInstance()}.
* @throws IllegalStateException if a specified tracer (via system properties) could not be found.
* @since 0.1.0
*/
public static Tracer getTracer() {
return getInstance().tracer;
return getInstance().tracerProvider.get();
}

/**
* Returns a singleton {@link Meter}.
* Returns an instance {@link Meter}. In a single deployment runtime a singleton is returned,
* however in an application server with multiple deployments a different instance can be used per
* deployment.
*
* @return registered meter or default via {@link DefaultMeter#getInstance()}.
* @throws IllegalStateException if a specified meter (via system properties) could not be found.
* @since 0.1.0
*/
public static Meter getMeter() {
return getInstance().meter;
return getInstance().meterProvider.get();
}

/**
* Returns a singleton {@link Tagger}.
* Returns an instance of {@link Tagger}. In a single deployment runtime a singleton is returned,
* however in an application server with multiple deployments a different instance can be used per
* deployment.
*
* @return registered meter or default via {@link DefaultTagger#getInstance()}.
* @throws IllegalStateException if a specified meter (via system properties) could not be found.
* @since 0.1.0
*/
public static Tagger getTagger() {
return getInstance().tagger;
return getInstance().taggerProvider.get();
}

/**
Expand All @@ -89,7 +95,11 @@ public static Tagger getTagger() {
* @throws IllegalStateException if a specified provider is not found
*/
@Nullable
private static <T> T loadSpi(Class<T> providerClass) {
private static <T> T loadSpi(Class<T> providerClass, ClassLoader classLoader) {
if (classLoader.getParent() != null) {
return loadSpi(providerClass, classLoader.getParent());
}

String specifiedProvider = System.getProperty(providerClass.getName());
ServiceLoader<T> providers = ServiceLoader.load(providerClass);
for (T provider : providers) {
Expand All @@ -116,12 +126,39 @@ private static OpenTelemetry getInstance() {
}

private OpenTelemetry() {
TracerProvider tracerProvider = loadSpi(TracerProvider.class);
tracer = tracerProvider != null ? tracerProvider.create() : DefaultTracer.getInstance();
MeterProvider meterProvider = loadSpi(MeterProvider.class);
meter = meterProvider != null ? meterProvider.create() : DefaultMeter.getInstance();
TaggerProvider taggerProvider = loadSpi(TaggerProvider.class);
tagger = taggerProvider != null ? taggerProvider.create() : DefaultTagger.getInstance();
TracerProvider tracerProvider =
loadSpi(TracerProvider.class, Thread.currentThread().getContextClassLoader());
this.tracerProvider =
tracerProvider != null
? tracerProvider
: new TracerProvider() {
@Override
public Tracer get() {
return DefaultTracer.getInstance();
}
};
MeterProvider meterProvider =
loadSpi(MeterProvider.class, Thread.currentThread().getContextClassLoader());
this.meterProvider =
meterProvider != null
? meterProvider
: new MeterProvider() {
@Override
public Meter get() {
return DefaultMeter.getInstance();
}
};
TaggerProvider taggerProvider =
loadSpi(TaggerProvider.class, Thread.currentThread().getContextClassLoader());
this.taggerProvider =
taggerProvider != null
? taggerProvider
: new TaggerProvider() {
@Override
public Tagger get() {
return DefaultTagger.getInstance();
}
};
}

// for testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@
public interface MeterProvider {

/**
* Creates a new meter instance.
* Creates a meter instance. In a single deployment runtime a singleton is returned, however in an
* application server with multiple deployments a different instance can be used per deployment.
*
* @return a meter instance.
* @since 0.1.0
*/
Meter create();
Meter get();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
public interface TaggerProvider {

/**
* Creates a new tagger instance.
* Creates a tagger instance. In a single deployment runtime a singleton is returned, however in
* an application server with multiple deployments a different instance can be used per
* deployment.
*
* @return a tagger instance.
* @since 0.1.0
*/
Tagger create();
Tagger get();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
public interface TracerProvider {

/**
* Creates a new tracer instance.
* Returns a tracer instance. In a single deployment runtime a singleton is returned, however in
* an application server with multiple deployments a different instance can be used per
* deployment.
*
* @return a tracer instance.
* @since 0.1.0
*/
Tracer create();
Tracer get();
}
36 changes: 24 additions & 12 deletions api/src/test/java/io/opentelemetry/OpenTelemetryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,20 @@ private static File createService(Class<?> service, Class<?>... impls) throws IO
}

public static class SecondTracer extends FirstTracer {
private static final Tracer INSTANCE = new SecondTracer();

@Override
public Tracer create() {
return new SecondTracer();
public Tracer get() {
return INSTANCE;
}
}

public static class FirstTracer implements Tracer, TracerProvider {
private static final Tracer INSTANCE = new FirstTracer();

@Override
public Tracer create() {
return new FirstTracer();
public Tracer get() {
return INSTANCE;
}

@Override
Expand Down Expand Up @@ -238,16 +242,20 @@ public HttpTextFormat<SpanContext> getHttpTextFormat() {
}

public static class SecondMeter extends FirstMeter {
private static final Meter INSTANCE = new SecondMeter();

@Override
public Meter create() {
return new SecondMeter();
public Meter get() {
return INSTANCE;
}
}

public static class FirstMeter implements Meter, MeterProvider {
private static final Meter INSTANCE = new FirstMeter();

@Override
public Meter create() {
return new FirstMeter();
public Meter get() {
return INSTANCE;
}

@Override
Expand Down Expand Up @@ -286,16 +294,20 @@ public void record(List<Measurement> measurements, TagMap tags, SpanContext span
}

public static class SecondTagger extends FirstTagger {
private static final Tagger INSTANCE = new SecondTagger();

@Override
public Tagger create() {
return new SecondTagger();
public Tagger get() {
return INSTANCE;
}
}

public static class FirstTagger implements Tagger, TaggerProvider {
private static final Tagger INSTANCE = new FirstTagger();

@Override
public Tagger create() {
return new FirstTagger();
public Tagger get() {
return INSTANCE;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
* io.opentelemetry.OpenTelemetry}.
*/
public class MeterSdkProvider implements MeterProvider {
private static final MeterSdk INSTANCE = new MeterSdk();

@Override
public Meter create() {
return new MeterSdk();
public Meter get() {
return INSTANCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
* io.opentelemetry.OpenTelemetry}.
*/
public class TaggerSdkProvider implements TaggerProvider {
private static final TaggerSdk INSTANCE = new TaggerSdk();

@Override
public Tagger create() {
return new TaggerSdk();
public Tagger get() {
return INSTANCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
* io.opentelemetry.OpenTelemetry}.
*/
public class TracerSdkProvider implements io.opentelemetry.trace.spi.TracerProvider {
private static final TracerSdk INSTANCE = new TracerSdk();

@Override
public Tracer create() {
return new TracerSdk();
public Tracer get() {
return INSTANCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class MeterSdkProviderTest {

@Test
public void testDefault() {
assertThat(new MeterSdkProvider().create()).isInstanceOf(MeterSdk.class);
assertThat(new MeterSdkProvider().get()).isInstanceOf(MeterSdk.class);
assertThat(new MeterSdkProvider().get()).isSameInstanceAs(new MeterSdkProvider().get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class TaggerSdkProviderTest {

@Test
public void testDefault() {
assertThat(new TaggerSdkProvider().create()).isInstanceOf(TaggerSdk.class);
assertThat(new TaggerSdkProvider().get()).isInstanceOf(TaggerSdk.class);
assertThat(new TaggerSdkProvider().get()).isSameInstanceAs(new TaggerSdkProvider().get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class TracerSdkProviderTest {

@Test
public void testDefault() {
assertThat(new TracerSdkProvider().create()).isInstanceOf(TracerSdk.class);
assertThat(new TracerSdkProvider().get()).isInstanceOf(TracerSdk.class);
assertThat(new TracerSdkProvider().get()).isSameInstanceAs(new TracerSdkProvider().get());
}
}

0 comments on commit 7fe173b

Please sign in to comment.