Skip to content

Commit

Permalink
Add a configuration manager (#466)
Browse files Browse the repository at this point in the history
Fixes #123

This basically removes loader.py (uses entry points instead) and all the calls
for set_preferred_implementation* in order to cleanly separate user code from
configuration. It introduces a configuration manager that can have
configuration set by a configuration file or environment variables that
override the former configuration method.

Co-authored-by: Mauricio Vásquez <mauricio@kinvolk.io>
Co-authored-by: Chris Kleinknecht <libc@google.com>
  • Loading branch information
3 people committed Mar 14, 2020
1 parent 3654a86 commit 68e909b
Show file tree
Hide file tree
Showing 36 changed files with 343 additions and 541 deletions.
1 change: 0 additions & 1 deletion docs/api/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ OpenTelemetry Python API
context
metrics
trace
util.loader
4 changes: 0 additions & 4 deletions docs/api/util.loader.rst

This file was deleted.

7 changes: 2 additions & 5 deletions docs/examples/basic_tracer/tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,16 @@
print("Using ConsoleSpanExporter")
exporter = ConsoleSpanExporter()

# The preferred tracer implementation must be set, as the opentelemetry-api
# defines the interface with a no-op implementation.
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())

trace.set_tracer_provider(TracerProvider())
# 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.get_tracer(__name__)

# SpanExporter receives the spans and send them to the target location.
span_processor = BatchExportSpanProcessor(exporter)
trace.get_tracer_provider().add_span_processor(span_processor)

trace.tracer_provider().add_span_processor(span_processor)
with tracer.start_as_current_span("foo"):
with tracer.start_as_current_span("bar"):
with tracer.start_as_current_span("baz"):
Expand Down
8 changes: 3 additions & 5 deletions docs/examples/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,17 @@
else:
exporter = ConsoleSpanExporter()

# The preferred tracer implementation must be set, as the opentelemetry-api
# defines the interface with a no-op implementation.
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer = trace.get_tracer(__name__)

# SpanExporter receives the spans and send them to the target location.
span_processor = BatchExportSpanProcessor(exporter)
trace.tracer_provider().add_span_processor(span_processor)
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(span_processor)

# Integrations are the glue that binds the OpenTelemetry API and the
# frameworks and libraries that are used together, automatically creating
# Spans and propagating context as appropriate.
http_requests.enable(trace.tracer_provider())
http_requests.enable(trace.get_tracer_provider())
app = flask.Flask(__name__)
app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app)

Expand Down
6 changes: 2 additions & 4 deletions docs/examples/http/tracer_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@
else:
exporter = ConsoleSpanExporter()

# The preferred tracer implementation must be set, as the opentelemetry-api
# defines the interface with a no-op implementation.
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer_provider = trace.tracer_provider()
trace.set_tracer_provider(TracerProvider())
tracer_provider = trace.get_tracer_provider()

# SpanExporter receives the spans and send them to the target location.
span_processor = BatchExportSpanProcessor(exporter)
Expand Down
3 changes: 1 addition & 2 deletions docs/examples/metrics/observer_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@
import psutil

from opentelemetry import metrics
from opentelemetry.sdk.metrics import LabelSet, MeterProvider
from opentelemetry.sdk.metrics import LabelSet
from opentelemetry.sdk.metrics.export import ConsoleMetricsExporter
from opentelemetry.sdk.metrics.export.batcher import UngroupedBatcher
from opentelemetry.sdk.metrics.export.controller import PushController

# Configure a stateful batcher
batcher = UngroupedBatcher(stateful=True)

metrics.set_preferred_meter_provider_implementation(lambda _: MeterProvider())
meter = metrics.get_meter(__name__)

# Exporter to export metrics to the console
Expand Down
3 changes: 1 addition & 2 deletions docs/examples/metrics/prometheus.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@

from opentelemetry import metrics
from opentelemetry.ext.prometheus import PrometheusMetricsExporter
from opentelemetry.sdk.metrics import Counter, MeterProvider
from opentelemetry.sdk.metrics import Counter
from opentelemetry.sdk.metrics.export.controller import PushController

# Start Prometheus client
start_http_server(port=8000, addr="localhost")

# Meter is responsible for creating and recording metrics
metrics.set_preferred_meter_provider_implementation(lambda _: MeterProvider())
meter = metrics.get_meter(__name__)
# exporter to export metrics to Prometheus
prefix = "MyAppPrefix"
Expand Down
5 changes: 1 addition & 4 deletions docs/examples/metrics/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@
import time

from opentelemetry import metrics
from opentelemetry.sdk.metrics import Counter, MeterProvider
from opentelemetry.sdk.metrics import Counter
from opentelemetry.sdk.metrics.export import ConsoleMetricsExporter
from opentelemetry.sdk.metrics.export.controller import PushController

# The preferred tracer implementation must be set, as the opentelemetry-api
# defines the interface with a no-op implementation.
metrics.set_preferred_meter_provider_implementation(lambda _: MeterProvider())
# Meter is responsible for creating and recording metrics
meter = metrics.get_meter(__name__)
# exporter to export metrics to the console
Expand Down
3 changes: 1 addition & 2 deletions docs/examples/metrics/simple_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import time

from opentelemetry import metrics
from opentelemetry.sdk.metrics import Counter, Measure, MeterProvider
from opentelemetry.sdk.metrics import Counter, Measure
from opentelemetry.sdk.metrics.export import ConsoleMetricsExporter
from opentelemetry.sdk.metrics.export.controller import PushController

Expand All @@ -44,7 +44,6 @@ def usage(argv):
sys.exit(1)

# Meter is responsible for creating and recording metrics
metrics.set_preferred_meter_provider_implementation(lambda _: MeterProvider())

# Meter's namespace corresponds to the string passed as the first argument Pass
# in True/False to indicate whether the batcher is stateful. True indicates the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import opentelemetry.ext.http_requests
from opentelemetry import trace
from opentelemetry.ext.flask import instrument_app
from opentelemetry.sdk.trace import TracerProvider


def configure_opentelemetry(flask_app: flask.Flask):
Expand All @@ -42,20 +41,14 @@ def configure_opentelemetry(flask_app: flask.Flask):
"""
# Start by configuring all objects required to ensure
# a complete end to end workflow.
# The preferred implementation of these objects must be set,
# as the opentelemetry-api defines the interface with a no-op
# implementation.
trace.set_preferred_tracer_provider_implementation(
lambda _: TracerProvider()
)

# Next, we need to configure how the values that are used by
# traces and metrics are propagated (such as what specific headers
# carry this value).
# Integrations are the glue that binds the OpenTelemetry API
# and the frameworks and libraries that are used together, automatically
# creating Spans and propagating context as appropriate.
opentelemetry.ext.http_requests.enable(trace.tracer_provider())
opentelemetry.ext.http_requests.enable(trace.get_tracer_provider())
instrument_app(flask_app)


Expand Down
5 changes: 1 addition & 4 deletions docs/examples/opentracing/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
from opentelemetry import trace
from opentelemetry.ext import opentracing_shim
from opentelemetry.ext.jaeger import JaegerSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor
from rediscache import RedisCache

# Configure the tracer using the default implementation
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer_provider = trace.tracer_provider()
tracer_provider = trace.get_tracer_provider()

# Configure the tracer to export traces to Jaeger
jaeger_exporter = JaegerSpanExporter(
Expand Down
3 changes: 1 addition & 2 deletions examples/metrics/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
from opentelemetry.ext.otcollector.metrics_exporter import (
CollectorMetricsExporter,
)
from opentelemetry.sdk.metrics import Counter, MeterProvider
from opentelemetry.sdk.metrics import Counter
from opentelemetry.sdk.metrics.export.controller import PushController

# Meter is responsible for creating and recording metrics
metrics.set_preferred_meter_provider_implementation(lambda _: MeterProvider())
meter = metrics.get_meter(__name__)
# exporter to export metrics to OT Collector
exporter = CollectorMetricsExporter(
Expand Down
1 change: 0 additions & 1 deletion ext/opentelemetry-ext-dbapi/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ Usage
from opentelemetry.trace import tracer_provider
from opentelemetry.ext.dbapi import trace_integration
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer = trace.get_tracer(__name__)
# Ex: mysql.connector
trace_integration(tracer_provider(), mysql.connector, "connect", "mysql", "sql")
Expand Down
2 changes: 0 additions & 2 deletions ext/opentelemetry-ext-jaeger/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ gRPC is still not supported by this implementation.
from opentelemetry import trace
from opentelemetry.ext import jaeger
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer = trace.get_tracer(__name__)
# create a JaegerSpanExporter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

from opentelemetry import trace
from opentelemetry.ext import jaeger
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer = trace.get_tracer(__name__)

# create a JaegerSpanExporter
Expand All @@ -26,7 +24,7 @@
span_processor = BatchExportSpanProcessor(jaeger_exporter)

# add to the tracer factory
trace.tracer_provider().add_span_processor(span_processor)
trace.get_tracer_provider().add_span_processor(span_processor)

# create some spans for testing
with tracer.start_as_current_span("foo") as foo:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,8 @@
import time
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.ext.opentracing_shim import create_tracer
# Tell OpenTelemetry which Tracer implementation to use.
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
# Create an OpenTelemetry Tracer.
otel_tracer = trace.get_tracer(__name__)
Expand Down
12 changes: 2 additions & 10 deletions ext/opentelemetry-ext-opentracing-shim/tests/test_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,11 @@ class TestShim(TestCase):

def setUp(self):
"""Create an OpenTelemetry tracer and a shim before every test case."""

self.shim = opentracingshim.create_tracer(trace.tracer_provider())
trace.set_tracer_provider(TracerProvider())
self.shim = opentracingshim.create_tracer(trace.get_tracer_provider())

@classmethod
def setUpClass(cls):
"""Set preferred tracer implementation only once rather than before
every test method.
"""

trace.set_preferred_tracer_provider_implementation(
lambda T: TracerProvider()
)

# Save current propagator to be restored on teardown.
cls._previous_propagator = propagators.get_global_httptextformat()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,11 @@ class TestCollectorMetricsExporter(unittest.TestCase):
@classmethod
def setUpClass(cls):
# pylint: disable=protected-access
cls._meter_defaults = (
metrics._METER_PROVIDER,
metrics._METER_PROVIDER_FACTORY,
)
metrics.set_preferred_meter_provider_implementation(
lambda _: MeterProvider()
)
metrics.set_meter_provider(MeterProvider())
cls._meter = metrics.get_meter(__name__)
kvp = {"environment": "staging"}
cls._test_label_set = cls._meter.get_label_set(kvp)

@classmethod
def tearDownClass(cls):
# pylint: disable=protected-access
(
metrics._METER_PROVIDER,
metrics._METER_PROVIDER_FACTORY,
) = cls._meter_defaults

def test_constructor(self):
mock_get_node = mock.Mock()
patch = mock.patch(
Expand Down
3 changes: 1 addition & 2 deletions ext/opentelemetry-ext-prometheus/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@ The **OpenTelemetry Prometheus Exporter** allows to export `OpenTelemetry`_ metr
from opentelemetry import metrics
from opentelemetry.ext.prometheus import PrometheusMetricsExporter
from opentelemetry.sdk.metrics import Counter, Meter
from opentelemetry.sdk.metrics import Counter
from opentelemetry.sdk.metrics.export.controller import PushController
from prometheus_client import start_http_server
# Start Prometheus client
start_http_server(port=8000, addr="localhost")
# Meter is responsible for creating and recording metrics
metrics.set_preferred_meter_implementation(lambda _: Meter())
meter = metrics.meter()
# exporter to export metrics to Prometheus
prefix = "MyAppPrefix"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@
CustomCollector,
PrometheusMetricsExporter,
)
from opentelemetry.metrics import get_meter_provider, set_meter_provider
from opentelemetry.sdk import metrics
from opentelemetry.sdk.metrics.export import MetricRecord, MetricsExportResult
from opentelemetry.sdk.metrics.export.aggregate import CounterAggregator


class TestPrometheusMetricExporter(unittest.TestCase):
def setUp(self):
self._meter = metrics.MeterProvider().get_meter(__name__)
set_meter_provider(metrics.MeterProvider())
self._meter = get_meter_provider().get_meter(__name__)
self._test_metric = self._meter.create_metric(
"testname",
"testdesc",
Expand Down Expand Up @@ -74,7 +76,7 @@ def test_export(self):
self.assertIs(result, MetricsExportResult.SUCCESS)

def test_counter_to_prometheus(self):
meter = metrics.MeterProvider().get_meter(__name__)
meter = get_meter_provider().get_meter(__name__)
metric = meter.create_metric(
"test@name",
"testdesc",
Expand Down Expand Up @@ -110,8 +112,7 @@ def test_counter_to_prometheus(self):
# TODO: Add unit test once Measure Aggregators are available

def test_invalid_metric(self):

meter = metrics.MeterProvider().get_meter(__name__)
meter = get_meter_provider().get_meter(__name__)
metric = meter.create_metric(
"tesname", "testdesc", "unit", int, TestMetric
)
Expand Down
2 changes: 0 additions & 2 deletions ext/opentelemetry-ext-psycopg2/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ Usage
import psycopg2
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.trace.ext.psycopg2 import trace_integration
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer = trace.get_tracer(__name__)
trace_integration(tracer)
cnx = psycopg2.connect(database='Database')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ class WsgiTestBase(unittest.TestCase):
@classmethod
def setUpClass(cls):
global _MEMORY_EXPORTER # pylint:disable=global-statement
trace_api.set_preferred_tracer_provider_implementation(
lambda T: TracerProvider()
)
tracer_provider = trace_api.tracer_provider()
trace_api.set_tracer_provider(TracerProvider())
tracer_provider = trace_api.get_tracer_provider()
_MEMORY_EXPORTER = InMemorySpanExporter()
span_processor = export.SimpleExportSpanProcessor(_MEMORY_EXPORTER)
tracer_provider.add_span_processor(span_processor)
Expand Down
2 changes: 0 additions & 2 deletions ext/opentelemetry-ext-zipkin/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ This exporter always send traces to the configured Zipkin collector using HTTP.
from opentelemetry import trace
from opentelemetry.ext import zipkin
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
trace.set_preferred_tracer_provider_implementation(lambda T: TracerProvider())
tracer = trace.get_tracer(__name__)
# create a ZipkinSpanExporter
Expand Down

0 comments on commit 68e909b

Please sign in to comment.