-
Notifications
You must be signed in to change notification settings - Fork 717
Add default invalid SpanContext #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
461f9fa
9e9f0c9
4addd0a
5777e47
8759f24
33aa734
ce95320
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,7 @@ | |
import typing | ||
from opentelemetry import loader | ||
|
||
|
||
class Span: | ||
"""A span represents a single operation within a trace.""" | ||
|
||
|
@@ -99,6 +100,47 @@ def get_context(self) -> 'SpanContext': | |
""" | ||
|
||
|
||
class TraceOptions(int): | ||
"""A bitmask that represents options specific to the trace. | ||
|
||
The only supported option is the "recorded" flag (``0x01``). If set, this | ||
flag indicates that the trace may have been recorded upstream. | ||
|
||
See the `W3C Trace Context - Traceparent`_ spec for details. | ||
|
||
.. _W3C Trace Context - Traceparent: | ||
https://www.w3.org/TR/trace-context/#trace-flags | ||
""" | ||
DEFAULT = 0x00 | ||
RECORDED = 0x01 | ||
|
||
@classmethod | ||
def get_default(cls) -> 'TraceOptions': | ||
return cls(cls.DEFAULT) | ||
|
||
|
||
DEFAULT_TRACEOPTIONS = TraceOptions.get_default() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing we need to decide is whether we want these as module or class level members. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have a strong preference, but we'd have to do the assignment (e.g. |
||
|
||
|
||
class TraceState(typing.Dict[str, str]): | ||
"""A list of key-value pairs representing vendor-specific trace info. | ||
|
||
Keys and values are strings of up to 256 printable US-ASCII characters. | ||
Implementations should conform to the the `W3C Trace Context - Tracestate`_ | ||
spec, which describes additional restrictions on valid field values. | ||
|
||
.. _W3C Trace Context - Tracestate: | ||
https://www.w3.org/TR/trace-context/#tracestate-field | ||
""" | ||
|
||
@classmethod | ||
def get_default(cls) -> 'TraceState': | ||
return cls() | ||
|
||
|
||
DEFAULT_TRACESTATE = TraceState.get_default() | ||
|
||
|
||
class SpanContext: | ||
"""The state of a Span to propagate between processes. | ||
|
||
|
@@ -113,11 +155,31 @@ class SpanContext: | |
""" | ||
|
||
def __init__(self, | ||
trace_id: str, | ||
span_id: str, | ||
trace_id: int, | ||
span_id: int, | ||
options: 'TraceOptions', | ||
state: 'TraceState') -> None: | ||
pass | ||
self.trace_id = trace_id | ||
self.span_id = span_id | ||
self.options = options | ||
self.state = state | ||
|
||
def is_valid(self) -> bool: | ||
"""Get whether this `SpanContext` is valid. | ||
|
||
A `SpanContext` is said to be invalid if its trace ID or span ID is | ||
invalid (i.e. ``0``). | ||
|
||
Returns: | ||
True if the `SpanContext` is valid, false otherwise. | ||
""" | ||
|
||
|
||
INVALID_SPAN_ID = 0 | ||
INVALID_TRACE_ID = 0 | ||
INVALID_SPAN_CONTEXT = SpanContext(INVALID_TRACE_ID, INVALID_SPAN_ID, | ||
DEFAULT_TRACEOPTIONS, DEFAULT_TRACESTATE) | ||
|
||
|
||
class Tracer: | ||
"""Handles span creation and in-process context propagation. | ||
|
@@ -239,39 +301,31 @@ def use_span(self, span: 'Span') -> typing.Iterator[None]: | |
""" | ||
|
||
|
||
# TODO | ||
class TraceOptions(int): | ||
pass | ||
|
||
|
||
# TODO | ||
class TraceState(typing.Dict[str, str]): | ||
pass | ||
|
||
|
||
_TRACER: typing.Optional[Tracer] = None | ||
_TRACER_FACTORY: typing.Optional[ | ||
typing.Callable[[typing.Type[Tracer]], typing.Optional[Tracer]]] = None | ||
|
||
|
||
def tracer() -> Tracer: | ||
"""Gets the current global :class:`~.Tracer` object. | ||
If there isn't one set yet, a default will be loaded.""" | ||
|
||
global _TRACER, _TRACER_FACTORY #pylint:disable=global-statement | ||
If there isn't one set yet, a default will be loaded. | ||
""" | ||
global _TRACER, _TRACER_FACTORY # pylint:disable=global-statement | ||
|
||
if _TRACER is None: | ||
#pylint:disable=protected-access | ||
# pylint:disable=protected-access | ||
_TRACER = loader._load_impl(Tracer, _TRACER_FACTORY) | ||
del _TRACER_FACTORY | ||
|
||
return _TRACER | ||
|
||
|
||
def set_preferred_tracer_implementation( | ||
factory: typing.Callable[ | ||
[typing.Type[Tracer]], typing.Optional[Tracer]] | ||
) -> None: | ||
"""Sets a factory function which may be used to create the tracer | ||
implementation. | ||
"""Set the factory to be used to create the tracer. | ||
|
||
See :mod:`opentelemetry.loader` for details. | ||
|
||
|
@@ -280,8 +334,7 @@ def set_preferred_tracer_implementation( | |
Args: | ||
factory: Callback that should create a new :class:`Tracer` instance. | ||
""" | ||
|
||
global _TRACER_FACTORY #pylint:disable=global-statement | ||
global _TRACER_FACTORY # pylint:disable=global-statement | ||
|
||
if _TRACER: | ||
raise RuntimeError("Tracer already loaded.") | ||
|
Uh oh!
There was an error while loading. Please reload this page.