Skip to content

Commit 1b830a1

Browse files
Merge pull request #14 from appoptics/NH-12018-distro-and-configurator-setup
NH-12018 Separate Distro vs Configurator
2 parents 54a0e7d + 1241e7a commit 1b830a1

File tree

3 files changed

+124
-69
lines changed

3 files changed

+124
-69
lines changed

Diff for: opentelemetry_distro_solarwinds/configurator.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
"""Module to initialize OpenTelemetry SDK components to work with SolarWinds backend"""
2+
3+
import logging
4+
from os import environ
5+
from pkg_resources import (
6+
iter_entry_points,
7+
load_entry_point
8+
)
9+
10+
from opentelemetry import trace
11+
from opentelemetry.environment_variables import (
12+
OTEL_PROPAGATORS,
13+
OTEL_TRACES_EXPORTER
14+
)
15+
from opentelemetry.instrumentation.propagators import set_global_response_propagator
16+
from opentelemetry.propagate import set_global_textmap
17+
from opentelemetry.propagators.composite import CompositePropagator
18+
from opentelemetry.sdk._configuration import _OTelSDKConfigurator
19+
from opentelemetry.sdk.environment_variables import OTEL_TRACES_SAMPLER
20+
from opentelemetry.sdk.trace import TracerProvider
21+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
22+
23+
from opentelemetry_distro_solarwinds.response_propagator import SolarWindsTraceResponsePropagator
24+
25+
logger = logging.getLogger(__name__)
26+
27+
class SolarWindsConfigurator(_OTelSDKConfigurator):
28+
"""OpenTelemetry Configurator for initializing SolarWinds-reporting SDK components"""
29+
30+
# Cannot set as env default because not part of OTel Python _KNOWN_SAMPLERS
31+
# https://github.com/open-telemetry/opentelemetry-python/blob/main/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py#L364-L380
32+
_DEFAULT_SW_TRACES_SAMPLER = "solarwinds_sampler"
33+
34+
def _configure(self, **kwargs):
35+
environ_sampler = environ.get(
36+
OTEL_TRACES_SAMPLER,
37+
self._DEFAULT_SW_TRACES_SAMPLER,
38+
)
39+
try:
40+
sampler = load_entry_point(
41+
"opentelemetry_distro_solarwinds",
42+
"opentelemetry_traces_sampler",
43+
environ_sampler
44+
)()
45+
except:
46+
logger.exception(
47+
"Failed to load configured sampler `%s`", environ_sampler
48+
)
49+
raise
50+
trace.set_tracer_provider(
51+
TracerProvider(sampler=sampler))
52+
53+
environ_exporter = environ.get(OTEL_TRACES_EXPORTER)
54+
try:
55+
exporter = load_entry_point(
56+
"opentelemetry_distro_solarwinds",
57+
"opentelemetry_traces_exporter",
58+
environ_exporter
59+
)()
60+
except:
61+
logger.exception(
62+
"Failed to load configured exporter `%s`", environ_exporter
63+
)
64+
raise
65+
span_exporter = BatchSpanProcessor(exporter)
66+
trace.get_tracer_provider().add_span_processor(span_exporter)
67+
68+
# Init and set CompositePropagator globally, like OTel API
69+
environ_propagators = environ.get(OTEL_PROPAGATORS).split(",")
70+
propagators = []
71+
for propagator in environ_propagators:
72+
try:
73+
propagators.append(
74+
next(
75+
iter_entry_points("opentelemetry_propagator", propagator)
76+
).load()()
77+
)
78+
except Exception:
79+
logger.exception(
80+
"Failed to load configured propagator `%s`", propagator
81+
)
82+
raise
83+
set_global_textmap(CompositePropagator(propagators))
84+
85+
# Set global HTTP response propagator
86+
set_global_response_propagator(SolarWindsTraceResponsePropagator())

Diff for: opentelemetry_distro_solarwinds/distro.py

+33-68
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,52 @@
1-
"""Module to configure OpenTelemetry agent to work with SolarWinds backend"""
1+
"""Module to configure OpenTelemetry to work with SolarWinds backend"""
22

33
import logging
44
from os import environ
5-
from pkg_resources import iter_entry_points
65

7-
from opentelemetry import trace
8-
from opentelemetry.environment_variables import OTEL_PROPAGATORS, OTEL_TRACES_EXPORTER
6+
from opentelemetry.environment_variables import (
7+
OTEL_PROPAGATORS,
8+
OTEL_TRACES_EXPORTER
9+
)
910
from opentelemetry.instrumentation.distro import BaseDistro
10-
from opentelemetry.instrumentation.propagators import set_global_response_propagator
11-
from opentelemetry.propagate import set_global_textmap
12-
from opentelemetry.propagators.composite import CompositePropagator
13-
from opentelemetry.sdk.trace import TracerProvider
14-
from opentelemetry.sdk.trace.export import BatchSpanProcessor
15-
16-
from opentelemetry_distro_solarwinds.response_propagator import SolarWindsTraceResponsePropagator
17-
from opentelemetry_distro_solarwinds.sampler import ParentBasedSwSampler
11+
from opentelemetry.sdk.environment_variables import OTEL_TRACES_SAMPLER
1812

1913
logger = logging.getLogger(__name__)
2014

2115
class SolarWindsDistro(BaseDistro):
22-
"""SolarWinds custom distro for OpenTelemetry agents."""
16+
"""OpenTelemetry Distro for SolarWinds reporting environment"""
2317

24-
_DEFAULT_OTEL_EXPORTER = "solarwinds_exporter"
25-
_DEFAULT_OTEL_PROPAGATORS = [
26-
"tracecontext",
18+
_TRACECONTEXT_PROPAGATOR = "tracecontext"
19+
_SW_PROPAGATOR = "solarwinds_propagator"
20+
_DEFAULT_SW_PROPAGATORS = [
21+
_TRACECONTEXT_PROPAGATOR,
2722
"baggage",
28-
"solarwinds_propagator",
23+
_SW_PROPAGATOR,
2924
]
25+
_DEFAULT_SW_TRACES_EXPORTER = "solarwinds_exporter"
3026

3127
def _configure(self, **kwargs):
32-
# Automatically use custom SolarWinds sampler
33-
trace.set_tracer_provider(
34-
TracerProvider(sampler=ParentBasedSwSampler()))
35-
36-
# Customize Exporter else default to SolarWindsSpanExporter
37-
environ_exporter = environ.get(
38-
OTEL_TRACES_EXPORTER,
39-
self._DEFAULT_OTEL_EXPORTER
40-
)
41-
try:
42-
exporter = next(
43-
iter_entry_points(
44-
"opentelemetry_traces_exporter",
45-
environ_exporter
46-
)).load()()
47-
except:
48-
logger.exception(
49-
"Failed to load configured exporter `%s`", environ_exporter
50-
)
51-
raise
52-
53-
span_exporter = BatchSpanProcessor(exporter)
54-
trace.get_tracer_provider().add_span_processor(span_exporter)
55-
56-
# Configure context propagators to always include
57-
# tracecontext,baggage,solarwinds -- first and in that order
58-
# -- plus any others specified by env var
28+
environ.setdefault(OTEL_TRACES_EXPORTER, self._DEFAULT_SW_TRACES_EXPORTER)
29+
5930
environ_propagators = environ.get(
6031
OTEL_PROPAGATORS,
61-
",".join(self._DEFAULT_OTEL_PROPAGATORS)
32+
",".join(self._DEFAULT_SW_PROPAGATORS)
6233
).split(",")
63-
if environ_propagators != self._DEFAULT_OTEL_PROPAGATORS:
64-
for default in self._DEFAULT_OTEL_PROPAGATORS:
65-
while default in environ_propagators:
66-
environ_propagators.remove(default)
67-
environ_propagators = self._DEFAULT_OTEL_PROPAGATORS + environ_propagators
34+
# If not using the default propagators,
35+
# can any arbitrary list BUT
36+
# (1) must include tracecontext and solarwinds_propagator
37+
# (2) tracecontext must be before solarwinds_propagator
38+
if environ_propagators != self._DEFAULT_SW_PROPAGATORS:
39+
if not self._TRACECONTEXT_PROPAGATOR in environ_propagators or \
40+
not self._SW_PROPAGATOR in environ_propagators:
41+
raise ValueError("Must include tracecontext and solarwinds_propagator in OTEL_PROPAGATORS to use SolarWinds Observability.")
42+
43+
if environ_propagators.index(self._SW_PROPAGATOR) \
44+
< environ_propagators.index(self._TRACECONTEXT_PROPAGATOR):
45+
raise ValueError("tracecontext must be before solarwinds_propagator in OTEL_PROPAGATORS to use SolarWinds Observability.")
6846
environ[OTEL_PROPAGATORS] = ",".join(environ_propagators)
6947

70-
# Init and set CompositePropagator globally, like OTel API
71-
propagators = []
72-
for propagator in environ_propagators:
73-
try:
74-
propagators.append(
75-
next(
76-
iter_entry_points("opentelemetry_propagator", propagator)
77-
).load()()
78-
)
79-
except Exception:
80-
logger.exception(
81-
"Failed to load configured propagator `%s`", propagator
82-
)
83-
raise
84-
set_global_textmap(CompositePropagator(propagators))
85-
86-
# Set global HTTP response propagator
87-
set_global_response_propagator(SolarWindsTraceResponsePropagator())
48+
logger.debug("Configured SolarWindsDistro: {}, {}, {}".format(
49+
environ.get(OTEL_TRACES_SAMPLER),
50+
environ.get(OTEL_TRACES_EXPORTER),
51+
environ.get(OTEL_PROPAGATORS)
52+
))

Diff for: setup.cfg

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ install_requires =
2525
[options.entry_points]
2626
opentelemetry_distro =
2727
solarwinds_distro = opentelemetry_distro_solarwinds.distro:SolarWindsDistro
28+
opentelemetry_configurator =
29+
solarwinds_configurator = opentelemetry_distro_solarwinds.configurator:SolarWindsConfigurator
2830
opentelemetry_propagator =
2931
solarwinds_propagator = opentelemetry_distro_solarwinds.propagator:SolarWindsPropagator
3032
opentelemetry_traces_exporter =
31-
solarwinds_exporter = opentelemetry_distro_solarwinds.exporter:SolarWindsSpanExporter
33+
solarwinds_exporter = opentelemetry_distro_solarwinds.exporter:SolarWindsSpanExporter
34+
opentelemetry_traces_sampler =
35+
solarwinds_sampler = opentelemetry_distro_solarwinds.sampler:ParentBasedSwSampler

0 commit comments

Comments
 (0)