Skip to content

Commit

Permalink
Use _Span and _Tracer classes in tracing sdk
Browse files Browse the repository at this point in the history
Having intermediary interfaces between Span() and Trace() classes allows
us to implement new features without violating the Span and Trace public
APIs.
This commit leverages that interface to implement span
attribute/event/link limits which are not part of the default Span API
  • Loading branch information
LetzNico committed Nov 29, 2020
1 parent ca13c3a commit 110011f
Showing 1 changed file with 80 additions and 19 deletions.
99 changes: 80 additions & 19 deletions opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
logger = logging.getLogger(__name__)

VALID_ATTR_VALUE_TYPES = (bool, str, int, float)
DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT = 1000
DEFAULT_SPAN_EVENT_COUNT_LIMIT = 1000
DEFAULT_SPAN_LINK_COUNT_LIMIT = 1000


class SpanProcessor:
Expand Down Expand Up @@ -423,9 +426,6 @@ def __init__(
instrumentation_info: InstrumentationInfo = None,
record_exception: bool = True,
set_status_on_exception: bool = True,
attribute_count_limit: int = 1000,
event_count_limit: int = 1000,
link_count_limit: int = 1000,
) -> None:
self.name = name
self.context = context
Expand All @@ -436,9 +436,6 @@ def __init__(
self.kind = kind
self._record_exception = record_exception
self._set_status_on_exception = set_status_on_exception
self.attribute_count_limit = attribute_count_limit
self.event_count_limit = event_count_limit
self.link_count_limit = link_count_limit
self.span_processor = span_processor
self.status = Status(StatusCode.UNSET)
self._lock = threading.Lock()
Expand Down Expand Up @@ -717,6 +714,44 @@ class _Span(Span):
This constructor should only be used internally.
"""

def __init__(
self,
name: str,
context: trace_api.SpanContext,
parent: Optional[trace_api.SpanContext] = None,
sampler: Optional[sampling.Sampler] = None,
trace_config: None = None, # TODO
resource: Resource = Resource.create({}),
attributes: types.Attributes = None, # TODO
events: Sequence[Event] = None, # TODO
links: Sequence[trace_api.Link] = (),
kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL,
span_processor: SpanProcessor = SpanProcessor(),
instrumentation_info: InstrumentationInfo = None,
record_exception: bool = True,
set_status_on_exception: bool = True,
attribute_count_limit: int = DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT,
event_count_limit: int = DEFAULT_SPAN_EVENT_COUNT_LIMIT,
link_count_limit: int = DEFAULT_SPAN_LINK_COUNT_LIMIT,
) -> None:
self.attribute_count_limit = attribute_count_limit
self.event_count_limit = event_count_limit
self.link_count_limit = link_count_limit
super().__init__(
name=name,
context=context,
parent=parent,
sampler=sampler,
resource=resource,
attributes=attributes,
span_processor=span_processor,
kind=kind,
links=links,
instrumentation_info=instrumentation_info,
record_exception=record_exception,
set_status_on_exception=set_status_on_exception,
)


class Tracer(trace_api.Tracer):
"""See `opentelemetry.trace.Tracer`.
Expand All @@ -731,18 +766,12 @@ def __init__(
],
ids_generator: trace_api.IdsGenerator,
instrumentation_info: InstrumentationInfo,
span_attribute_count_limit: int,
span_event_count_limit: int,
span_link_count_limit: int,
) -> None:
self.sampler = sampler
self.resource = resource
self.span_processor = span_processor
self.ids_generator = ids_generator
self.instrumentation_info = instrumentation_info
self.span_attribute_count_limit = span_attribute_count_limit
self.span_event_count_limit = span_event_count_limit
self.span_link_count_limit = span_link_count_limit

def start_as_current_span(
self,
Expand Down Expand Up @@ -846,6 +875,7 @@ def start_span( # pylint: disable=too-many-locals
span.start(start_time=start_time, parent_context=context)
else:
span = trace_api.DefaultSpan(context=span_context)

return span

@contextmanager
Expand Down Expand Up @@ -887,6 +917,37 @@ def use_span(
span.end()


class _Tracer(Tracer):
"""Protected implementation of `opentelemetry.trace.Tracer`.
This constructor should only be used internally.
"""

def __init__(
self,
sampler: sampling.Sampler,
resource: Resource,
span_processor: Union[
SynchronousMultiSpanProcessor, ConcurrentMultiSpanProcessor
],
ids_generator: trace_api.IdsGenerator,
instrumentation_info: InstrumentationInfo,
span_attribute_count_limit: int = DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT,
span_event_count_limit: int = DEFAULT_SPAN_EVENT_COUNT_LIMIT,
span_link_count_limit: int = DEFAULT_SPAN_LINK_COUNT_LIMIT,
) -> None:
self.span_attribute_count_limit = span_attribute_count_limit
self.span_event_count_limit = span_event_count_limit
self.span_link_count_limit = span_link_count_limit
super().__init__(
sampler=sampler,
resource=resource,
span_processor=span_processor,
ids_generator=ids_generator,
instrumentation_info=instrumentation_info,
)


class TracerProvider(trace_api.TracerProvider):
def __init__(
self,
Expand All @@ -912,13 +973,13 @@ def __init__(
self._atexit_handler = atexit.register(self.shutdown)

self.span_attribute_count_limit = Configuration().get(
"SPAN_ATTRIBUTE_COUNT_LIMIT", 1000
"SPAN_ATTRIBUTE_COUNT_LIMIT", DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT
)
self.span_event_count_limit = Configuration().get(
"SPAN_EVENT_COUNT_LIMIT", 1000
"SPAN_EVENT_COUNT_LIMIT", DEFAULT_SPAN_EVENT_COUNT_LIMIT
)
self.span_link_count_limit = Configuration().get(
"SPAN_LINK_COUNT_LIMIT", 1000
"SPAN_LINK_COUNT_LIMIT", DEFAULT_SPAN_LINK_COUNT_LIMIT
)

def get_tracer(
Expand All @@ -929,17 +990,17 @@ def get_tracer(
if not instrumenting_module_name: # Reject empty strings too.
instrumenting_module_name = "ERROR:MISSING MODULE NAME"
logger.error("get_tracer called with missing module name.")
return Tracer(
return _Tracer(
self.sampler,
self.resource,
self._active_span_processor,
self.ids_generator,
InstrumentationInfo(
instrumenting_module_name, instrumenting_library_version
),
self.span_attribute_count_limit,
self.span_event_count_limit,
self.span_link_count_limit,
span_attribute_count_limit=self.span_attribute_count_limit,
span_event_count_limit=self.span_event_count_limit,
span_link_count_limit=self.span_link_count_limit,
)

def add_span_processor(self, span_processor: SpanProcessor) -> None:
Expand Down

0 comments on commit 110011f

Please sign in to comment.