Skip to content

Commit

Permalink
Add named tracers to the API (#584)
Browse files Browse the repository at this point in the history
* A rough idea of how named tracers might look in the API.

* update to require at least a name for the tracer

* Introduce another layer of factory for the provider

* remove convenience tracer methods from the OpenTelemetry class.

* Update api/src/main/java/io/opentelemetry/trace/spi/TracerFactoryProvider.java

Co-Authored-By: Armin Ruech <armin.ruech@gmail.com>

* Update api/src/main/java/io/opentelemetry/trace/TracerFactory.java

Co-Authored-By: Armin Ruech <armin.ruech@gmail.com>

* Add clarifying javadoc, per PR review

* reverse who calls whom
  • Loading branch information
John Watson authored and bogdandrutu committed Oct 22, 2019
1 parent a10e918 commit 60ba3b7
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 82 deletions.
75 changes: 41 additions & 34 deletions api/src/main/java/io/opentelemetry/OpenTelemetry.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
import io.opentelemetry.metrics.DefaultMeter;
import io.opentelemetry.metrics.Meter;
import io.opentelemetry.metrics.spi.MeterProvider;
import io.opentelemetry.trace.DefaultTracer;
import io.opentelemetry.trace.DefaultTracerFactory;
import io.opentelemetry.trace.DefaultTracerFactoryProvider;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.trace.spi.TracerProvider;
import io.opentelemetry.trace.TracerFactory;
import io.opentelemetry.trace.spi.TracerFactoryProvider;
import java.util.ServiceLoader;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
Expand All @@ -35,7 +37,7 @@
*
* <p>The telemetry objects are lazy-loaded singletons resolved via {@link ServiceLoader} mechanism.
*
* @see TracerProvider
* @see TracerFactory
* @see MeterProvider
* @see DistributedContextManagerProvider
*/
Expand All @@ -44,19 +46,20 @@ public final class OpenTelemetry {

@Nullable private static volatile OpenTelemetry instance;

private final Tracer tracer;
private final TracerFactory tracerFactory;
private final Meter meter;
private final DistributedContextManager contextManager;

/**
* Returns a singleton {@link Tracer}.
* Returns a singleton {@link TracerFactory}.
*
* @return registered tracer or default via {@link DefaultTracer#getInstance()}.
* @throws IllegalStateException if a specified tracer (via system properties) could not be found.
* @return registered TracerFactory of default via {@link DefaultTracerFactory#getInstance()}.
* @throws IllegalStateException if a specified TracerFactory (via system properties) could not be
* found.
* @since 0.1.0
*/
public static Tracer getTracer() {
return getInstance().tracer;
public static TracerFactory getTracerFactory() {
return getInstance().tracerFactory;
}

/**
Expand All @@ -83,6 +86,35 @@ public static DistributedContextManager getDistributedContextManager() {
return getInstance().contextManager;
}

/** Lazy loads an instance. */
private static OpenTelemetry getInstance() {
if (instance == null) {
synchronized (OpenTelemetry.class) {
if (instance == null) {
instance = new OpenTelemetry();
}
}
}
return instance;
}

private OpenTelemetry() {
TracerFactoryProvider tracerFactoryProvider = loadSpi(TracerFactoryProvider.class);
this.tracerFactory =
tracerFactoryProvider != null
? tracerFactoryProvider.create()
: DefaultTracerFactoryProvider.getInstance().create();

MeterProvider meterProvider = loadSpi(MeterProvider.class);
meter = meterProvider != null ? meterProvider.create() : DefaultMeter.getInstance();
DistributedContextManagerProvider contextManagerProvider =
loadSpi(DistributedContextManagerProvider.class);
contextManager =
contextManagerProvider != null
? contextManagerProvider.create()
: DefaultDistributedContextManager.getInstance();
}

/**
* Load provider class via {@link ServiceLoader}. A specific provider class can be requested via
* setting a system property with FQCN.
Expand All @@ -108,31 +140,6 @@ private static <T> T loadSpi(Class<T> providerClass) {
return null;
}

/** Lazy loads an instance. */
private static OpenTelemetry getInstance() {
if (instance == null) {
synchronized (OpenTelemetry.class) {
if (instance == null) {
instance = new OpenTelemetry();
}
}
}
return instance;
}

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();
DistributedContextManagerProvider contextManagerProvider =
loadSpi(DistributedContextManagerProvider.class);
contextManager =
contextManagerProvider != null
? contextManagerProvider.create()
: DefaultDistributedContextManager.getInstance();
}

// for testing
static void reset() {
instance = null;
Expand Down
36 changes: 36 additions & 0 deletions api/src/main/java/io/opentelemetry/trace/DefaultTracerFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2019, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.opentelemetry.trace;

public class DefaultTracerFactory implements TracerFactory {

private static final TracerFactory instance = new DefaultTracerFactory();

public static TracerFactory getInstance() {
return instance;
}

@Override
public Tracer get(String instrumentationName) {
return get(instrumentationName, null);
}

@Override
public Tracer get(String instrumentationName, String instrumentationVersion) {
return DefaultTracer.getInstance();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2019, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.opentelemetry.trace;

import io.opentelemetry.trace.spi.TracerFactoryProvider;

public class DefaultTracerFactoryProvider implements TracerFactoryProvider {
private static final TracerFactoryProvider instance = new DefaultTracerFactoryProvider();

public static TracerFactoryProvider getInstance() {
return instance;
}

@Override
public TracerFactory create() {
return DefaultTracerFactory.getInstance();
}
}
51 changes: 51 additions & 0 deletions api/src/main/java/io/opentelemetry/trace/TracerFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2019, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.opentelemetry.trace;

import javax.annotation.concurrent.ThreadSafe;

/**
* A factory for creating named {@link Tracer}s.
*
* @see io.opentelemetry.OpenTelemetry
* @see io.opentelemetry.trace.Tracer
* @since 0.1.0
*/
@ThreadSafe
public interface TracerFactory {

/**
* Gets or creates a named tracer instance.
*
* @param instrumentationName The name of the instrumentation library, not the name of the
* instrument*ed* library.
* @return a tracer instance.
* @since 0.1.0
*/
Tracer get(String instrumentationName);

/**
* Gets or creates a named and versioned tracer instance.
*
* @param instrumentationName The name of the instrumentation library, not the name of the
* instrument*ed* library.
* @param instrumentationVersion The version of the instrumentation library.
* @return a tracer instance.
* @since 0.1.0
*/
Tracer get(String instrumentationName, String instrumentationVersion);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,27 @@

package io.opentelemetry.trace.spi;

import io.opentelemetry.trace.Tracer;
import io.opentelemetry.trace.TracerFactory;
import javax.annotation.concurrent.ThreadSafe;

/**
* TracerProvider is a service provider for {@link Tracer}. Fully qualified class name of the
* implementation should be registered in {@code
* META-INF/services/io.opentelemetry.trace.spi.TracerProvider}. <br>
* TracerFactoryProvider is a service provider for a {@link TracerFactory}. Fully qualified class
* name of the implementation should be registered in {@code
* META-INF/services/io.opentelemetry.trace.spi.TracerFactoryProvider}. <br>
* <br>
* A specific implementation can be selected by a system property {@code
* io.opentelemetry.trace.spi.TracerProvider} with value of fully qualified class name.
* io.opentelemetry.trace.spi.TracerFactoryProvider} with value of fully qualified class name.
*
* @see io.opentelemetry.OpenTelemetry
*/
@ThreadSafe
public interface TracerProvider {
public interface TracerFactoryProvider {

/**
* Creates a new tracer instance.
* Creates a new TracerFactory.
*
* @return a tracer instance.
* @return a new TracerFactory.
* @since 0.1.0
*/
Tracer create();
TracerFactory create();
}
Loading

0 comments on commit 60ba3b7

Please sign in to comment.