Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add named tracers to the API #584

Merged
merged 8 commits into from
Oct 22, 2019
Merged
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
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 {
jkwatson marked this conversation as resolved.
Show resolved Hide resolved

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