Skip to content

Commit

Permalink
Merge pull request #17 from appoptics/NH-12018-oboe-reporter-in-confi…
Browse files Browse the repository at this point in the history
…gurator

NH-12018 oboe Reporter init moved to Configurator
  • Loading branch information
tammy-baylis-swi authored May 5, 2022
2 parents 1b830a1 + 01f1e98 commit 7e758df
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 76 deletions.
3 changes: 2 additions & 1 deletion opentelemetry_distro_solarwinds/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
EQUALS_W3C_SANITIZED = "####"
SW_TRACESTATE_KEY = "sw"
OTEL_CONTEXT_SW_OPTIONS_KEY = "sw_xtraceoptions"
OTEL_CONTEXT_SW_SIGNATURE_KEY = "sw_signature"
OTEL_CONTEXT_SW_SIGNATURE_KEY = "sw_signature"
DEFAULT_SW_TRACES_EXPORTER = "solarwinds_exporter"
128 changes: 99 additions & 29 deletions opentelemetry_distro_solarwinds/configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@
from opentelemetry.propagators.composite import CompositePropagator
from opentelemetry.sdk._configuration import _OTelSDKConfigurator
from opentelemetry.sdk.environment_variables import OTEL_TRACES_SAMPLER
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace import (
sampling,
TracerProvider
)
from opentelemetry.sdk.trace.export import BatchSpanProcessor

from opentelemetry_distro_solarwinds import DEFAULT_SW_TRACES_EXPORTER
from opentelemetry_distro_solarwinds.extension.oboe import Reporter
from opentelemetry_distro_solarwinds.response_propagator import SolarWindsTraceResponsePropagator

logger = logging.getLogger(__name__)
Expand All @@ -32,55 +37,120 @@ class SolarWindsConfigurator(_OTelSDKConfigurator):
_DEFAULT_SW_TRACES_SAMPLER = "solarwinds_sampler"

def _configure(self, **kwargs):
environ_sampler = environ.get(
OTEL_TRACES_SAMPLER,
self._DEFAULT_SW_TRACES_SAMPLER,
)
"""Configure OTel sampler, exporter, propagator, response propagator"""
reporter = self._initialize_solarwinds_reporter()
self._configure_sampler()
self._configure_exporter(reporter)
self._configure_propagator()
# Set global HTTP response propagator
set_global_response_propagator(SolarWindsTraceResponsePropagator())

def _configure_sampler(self):
"""Always configure SolarWinds OTel sampler"""
try:
sampler = load_entry_point(
"opentelemetry_distro_solarwinds",
"opentelemetry_traces_sampler",
environ_sampler
self._DEFAULT_SW_TRACES_SAMPLER
)()
except:
logger.exception(
"Failed to load configured sampler `%s`", environ_sampler
"Failed to load configured sampler {}".format(
self._DEFAULT_SW_TRACES_SAMPLER
)
)
raise
trace.set_tracer_provider(
TracerProvider(sampler=sampler))
TracerProvider(sampler=sampler)
)

environ_exporter = environ.get(OTEL_TRACES_EXPORTER)
try:
exporter = load_entry_point(
"opentelemetry_distro_solarwinds",
"opentelemetry_traces_exporter",
environ_exporter
)()
except:
logger.exception(
"Failed to load configured exporter `%s`", environ_exporter
)
raise
span_exporter = BatchSpanProcessor(exporter)
trace.get_tracer_provider().add_span_processor(span_exporter)
def _configure_exporter(self, reporter):
"""Configure SolarWinds or env-specified OTel span exporter.
Initialization of SolarWinds exporter requires a liboboe reporter."""
exporter = None
environ_exporter_name = environ.get(OTEL_TRACES_EXPORTER)

# Init and set CompositePropagator globally, like OTel API
environ_propagators = environ.get(OTEL_PROPAGATORS).split(",")
if environ_exporter_name == DEFAULT_SW_TRACES_EXPORTER:
try:
exporter = load_entry_point(
"opentelemetry_distro_solarwinds",
"opentelemetry_traces_exporter",
environ_exporter_name
)(reporter)
except:
logger.exception(
"Failed to load configured exporter {} with reporter".format(
environ_exporter_name
)
)
raise
else:
try:
exporter = next(
iter_entry_points(
"opentelemetry_traces_exporter",
environ_exporter_name
)
).load()()
except:
logger.exception(
"Failed to load configured exporter {}".format(
environ_exporter_name
)
)
raise
span_processor = BatchSpanProcessor(exporter)
trace.get_tracer_provider().add_span_processor(span_processor)

def _configure_propagator(self):
"""Configure CompositePropagator with SolarWinds and other propagators"""
propagators = []
for propagator in environ_propagators:
environ_propagators_names = environ.get(OTEL_PROPAGATORS).split(",")
for propagator_name in environ_propagators_names:
try:
propagators.append(
next(
iter_entry_points("opentelemetry_propagator", propagator)
iter_entry_points("opentelemetry_propagator", propagator_name)
).load()()
)
except Exception:
logger.exception(
"Failed to load configured propagator `%s`", propagator
"Failed to load configured propagator {}".format(
propagator_name
)
)
raise
set_global_textmap(CompositePropagator(propagators))

# Set global HTTP response propagator
set_global_response_propagator(SolarWindsTraceResponsePropagator())
def _initialize_solarwinds_reporter(self) -> Reporter:
"""Initialize SolarWinds reporter used by sampler and exporter. This establishes collector and sampling settings in a background thread."""
log_level = environ.get('SOLARWINDS_DEBUG_LEVEL', 3)
try:
log_level = int(log_level)
except ValueError:
log_level = 3
# TODO make some of these customizable
return Reporter(
hostname_alias='',
log_level=log_level,
log_file_path='',
max_transactions=-1,
max_flush_wait_time=-1,
events_flush_interval=-1,
max_request_size_bytes=-1,
reporter='ssl',
host=environ.get('SOLARWINDS_COLLECTOR', ''),
service_key=environ.get('SOLARWINDS_SERVICE_KEY', ''),
trusted_path='',
buffer_size=-1,
trace_metrics=-1,
histogram_precision=-1,
token_bucket_capacity=-1,
token_bucket_rate=-1,
file_single=0,
ec2_metadata_timeout=1000,
grpc_proxy='',
stdout_clear_nonblocking=0,
is_grpc_clean_hack_enabled=False,
w3c_trace_format=1,
)
10 changes: 5 additions & 5 deletions opentelemetry_distro_solarwinds/distro.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
OTEL_TRACES_EXPORTER
)
from opentelemetry.instrumentation.distro import BaseDistro
from opentelemetry.sdk.environment_variables import OTEL_TRACES_SAMPLER

from opentelemetry_distro_solarwinds import DEFAULT_SW_TRACES_EXPORTER

logger = logging.getLogger(__name__)

Expand All @@ -22,10 +23,10 @@ class SolarWindsDistro(BaseDistro):
"baggage",
_SW_PROPAGATOR,
]
_DEFAULT_SW_TRACES_EXPORTER = "solarwinds_exporter"

def _configure(self, **kwargs):
environ.setdefault(OTEL_TRACES_EXPORTER, self._DEFAULT_SW_TRACES_EXPORTER)
"""Configure OTel exporter and propagators"""
environ.setdefault(OTEL_TRACES_EXPORTER, DEFAULT_SW_TRACES_EXPORTER)

environ_propagators = environ.get(
OTEL_PROPAGATORS,
Expand All @@ -45,8 +46,7 @@ def _configure(self, **kwargs):
raise ValueError("tracecontext must be before solarwinds_propagator in OTEL_PROPAGATORS to use SolarWinds Observability.")
environ[OTEL_PROPAGATORS] = ",".join(environ_propagators)

logger.debug("Configured SolarWindsDistro: {}, {}, {}".format(
environ.get(OTEL_TRACES_SAMPLER),
logger.debug("Configured SolarWindsDistro: {}, {}".format(
environ.get(OTEL_TRACES_EXPORTER),
environ.get(OTEL_PROPAGATORS)
))
49 changes: 8 additions & 41 deletions opentelemetry_distro_solarwinds/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,25 @@
"""

import logging
import os

from opentelemetry.sdk.trace.export import SpanExporter

from opentelemetry_distro_solarwinds.extension.oboe import (Context, Metadata,
Reporter)
from opentelemetry_distro_solarwinds.extension.oboe import (
Context,
Metadata
)
from opentelemetry_distro_solarwinds.w3c_transformer import W3CTransformer

logger = logging.getLogger(__file__)


class SolarWindsSpanExporter(SpanExporter):
"""SolarWinds span exporter.
Reports instrumentation data to the SolarWinds backend.
"""SolarWinds custom span exporter for the SolarWinds backend.
Initialization requires a liboboe reporter.
"""
def __init__(self, *args, **kw_args):
def __init__(self, reporter, *args, **kw_args):
super().__init__(*args, **kw_args)
self.reporter = None
self._initialize_solarwinds_reporter()
self.reporter = reporter

def export(self, spans):
"""Export to AO events and report via liboboe.
Expand Down Expand Up @@ -88,38 +87,6 @@ def _report_info_event(self, event):
evt.addInfo(k, v)
self.reporter.sendReport(evt, False)

def _initialize_solarwinds_reporter(self):
"""Initialize liboboe."""
log_level = os.environ.get('SOLARWINDS_DEBUG_LEVEL', 3)
try:
log_level = int(log_level)
except ValueError:
log_level = 3
self.reporter = Reporter(
hostname_alias='',
log_level=log_level,
log_file_path='',
max_transactions=-1,
max_flush_wait_time=-1,
events_flush_interval=-1,
max_request_size_bytes=-1,
reporter='ssl',
host=os.environ.get('SOLARWINDS_COLLECTOR', ''),
service_key=os.environ.get('SOLARWINDS_SERVICE_KEY', ''),
trusted_path='',
buffer_size=-1,
trace_metrics=-1,
histogram_precision=-1,
token_bucket_capacity=-1,
token_bucket_rate=-1,
file_single=0,
ec2_metadata_timeout=1000,
grpc_proxy='',
stdout_clear_nonblocking=0,
is_grpc_clean_hack_enabled=False,
w3c_trace_format=1,
)

@staticmethod
def _build_metadata(span_context):
return Metadata.fromString(
Expand Down

0 comments on commit 7e758df

Please sign in to comment.