Skip to content

Commit

Permalink
Adding trace.get_tracer (#430)
Browse files Browse the repository at this point in the history
It's fairly common to need to retrieve tracers, and as such adding the
additional tracer_source() call to every retrieval of a tracer can add to
a lot of extra boilerplate at minimal semantic value. It would be uncommon
for one to use multiple tracer_source objects, as typically one would want
all tracers to be created and behave in a similar way (e.g. passed to the
same span processor).

Co-Authored-By: Chris Kleinknecht <[email protected]>
  • Loading branch information
toumorokoshi and c24t authored Feb 19, 2020
1 parent 5a0dae9 commit 972e2ab
Show file tree
Hide file tree
Showing 15 changed files with 75 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
trace.tracer_source().add_span_processor(
SimpleExportSpanProcessor(ConsoleSpanExporter())
)
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span('foo'):
with tracer.start_as_current_span('bar'):
with tracer.start_as_current_span('baz'):
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_tracer/tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
# We tell OpenTelemetry who it is that is creating spans. In this case, we have
# no real name (no setup.py), so we make one up. If we had a version, we would
# also specify it here.
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)

# SpanExporter receives the spans and send them to the target location.
span_processor = BatchExportSpanProcessor(exporter)
Expand Down
2 changes: 1 addition & 1 deletion examples/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
# The preferred tracer implementation must be set, as the opentelemetry-api
# defines the interface with a no-op implementation.
trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)

# SpanExporter receives the spans and send them to the target location.
span_processor = BatchExportSpanProcessor(exporter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def hello():
version = pkg_resources.get_distribution(
"opentelemetry-example-app"
).version
tracer = trace.tracer_source().get_tracer(__name__, version)
tracer = trace.get_tracer(__name__, version)
with tracer.start_as_current_span("example-request"):
requests.get("http://www.example.com")
return "hello"
Expand Down
2 changes: 1 addition & 1 deletion examples/opentracing/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
redis_cache = RedisCache(opentracing_tracer)

# Appication code uses an OpenTelemetry Tracer as usual.
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)


@redis_cache
Expand Down
2 changes: 1 addition & 1 deletion ext/opentelemetry-ext-dbapi/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Usage
from opentelemetry.ext.dbapi import trace_integration
trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)
# Ex: mysql.connector
trace_integration(tracer_source(), mysql.connector, "connect", "mysql")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def _before_flask_request():
otel_wsgi.get_header_from_environ, environ
)

tracer = trace.tracer_source().get_tracer(__name__, __version__)
tracer = trace.get_tracer(__name__, __version__)

attributes = otel_wsgi.collect_request_attributes(environ)
if flask_request.url_rule:
Expand Down
2 changes: 1 addition & 1 deletion ext/opentelemetry-ext-jaeger/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ gRPC is still not supported by this implementation.
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)
# create a JaegerSpanExporter
jaeger_exporter = jaeger.JaegerSpanExporter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)

# create a JaegerSpanExporter
jaeger_exporter = jaeger.JaegerSpanExporter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
# Create an OpenTelemetry Tracer.
otel_tracer = trace.tracer_source().get_tracer(__name__)
otel_tracer = trace.get_tracer(__name__)
# Create an OpenTracing shim.
shim = create_tracer(otel_tracer)
Expand Down
2 changes: 1 addition & 1 deletion ext/opentelemetry-ext-psycopg2/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Usage
from opentelemetry.trace.ext.psycopg2 import trace_integration
trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)
trace_integration(tracer)
cnx = psycopg2.connect(database='Database')
cursor = cnx.cursor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class OpenTelemetryMiddleware:

def __init__(self, wsgi):
self.wsgi = wsgi
self.tracer = trace.tracer_source().get_tracer(__name__, __version__)
self.tracer = trace.get_tracer(__name__, __version__)

@staticmethod
def _create_start_response(span, start_response):
Expand Down
2 changes: 1 addition & 1 deletion ext/opentelemetry-ext-zipkin/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This exporter always send traces to the configured Zipkin collector using HTTP.
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
trace.set_preferred_tracer_source_implementation(lambda T: TracerSource())
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)
# create a ZipkinSpanExporter
zipkin_exporter = zipkin.ZipkinSpanExporter(
Expand Down
22 changes: 21 additions & 1 deletion opentelemetry-api/src/opentelemetry/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from opentelemetry import trace
tracer = trace.tracer_source().get_tracer(__name__)
tracer = trace.get_tracer(__name__)
# Create a new root span, set it as the current span in context
with tracer.start_as_current_span("parent"):
Expand Down Expand Up @@ -68,13 +68,16 @@

import abc
import enum
import logging
import types as python_types
import typing
from contextlib import contextmanager

from opentelemetry.trace.status import Status
from opentelemetry.util import loader, types

logger = logging.getLogger(__name__)

# TODO: quarantine
ParentSpan = typing.Optional[typing.Union["Span", "SpanContext"]]

Expand Down Expand Up @@ -647,6 +650,19 @@ def use_span(
_TRACER_SOURCE_FACTORY = None # type: typing.Optional[ImplementationFactory]


def get_tracer(
instrumenting_module_name: str, instrumenting_library_version: str = ""
) -> "Tracer":
"""Returns a `Tracer` for use by the given instrumentation library.
This function is a convenience wrapper for
opentelemetry.trace.tracer_source().get_tracer
"""
return tracer_source().get_tracer(
instrumenting_module_name, instrumenting_library_version
)


def tracer_source() -> TracerSource:
"""Gets the current global :class:`~.TracerSource` object.
Expand All @@ -663,6 +679,10 @@ def tracer_source() -> TracerSource:
except TypeError:
# if we raised an exception trying to instantiate an
# abstract class, default to no-op tracer impl
logger.warning(
"Unable to instantiate TracerSource from tracer source factory.",
exc_info=True,
)
_TRACER_SOURCE = DefaultTracerSource()
del _TRACER_SOURCE_FACTORY

Expand Down
41 changes: 41 additions & 0 deletions opentelemetry-api/tests/trace/test_globals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import importlib
import unittest

from opentelemetry import trace


class TestGlobals(unittest.TestCase):
def setUp(self):
importlib.reload(trace)

# this class has to be declared after the importlib
# reload, or else it will inherit from an old
# TracerSource, rather than the new TraceSource ABC.
# created from reload.

static_tracer = trace.DefaultTracer()

class DummyTracerSource(trace.TracerSource):
"""TraceSource used for testing"""

def get_tracer(
self,
instrumenting_module_name: str,
instrumenting_library_version: str = "",
) -> trace.Tracer:
# pylint:disable=no-self-use,unused-argument
return static_tracer

trace.set_preferred_tracer_source_implementation(
lambda _: DummyTracerSource()
)

@staticmethod
def tearDown() -> None:
importlib.reload(trace)

def test_get_tracer(self):
"""trace.get_tracer should proxy to the global tracer source."""
from_global_api = trace.get_tracer("foo")
from_tracer_api = trace.tracer_source().get_tracer("foo")
self.assertIs(from_global_api, from_tracer_api)

0 comments on commit 972e2ab

Please sign in to comment.