diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 6bae25c276a..10f4691f6e8 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -66,6 +66,60 @@ import typing +class Span: + """A span represents a single operation within a trace.""" + + def start(self) -> None: + """Sets the current time as the span's start time. + + Each span represents a single operation. The span's start time is the + wall time at which the operation started. + + Only the first call to ``start`` should modify the span, and + implementations are free to ignore or raise on further calls. + """ + + def end(self) -> None: + """Sets the current time as the span's end time. + + The span's end time is the wall time at which the operation finished. + + Only the first call to ``end`` should modify the span, and + implementations are free to ignore or raise on further calls. + """ + + def get_context(self) -> 'SpanContext': + """Gets the span's SpanContext. + + Get an immutable, serializable identifier for this span that can be + used to create new child spans. + + Returns: + A :class:`.SpanContext` with a copy of this span's immutable state. + """ + + +class SpanContext: + """The state of a Span to propagate between processes. + + This class includes the immutable attributes of a :class:`.Span` that must + be propagated to a span's children and across process boundaries. + + Args: + trace_id: The ID of the trace that this span belongs to. + span_id: This span's ID. + options: Trace options to propagate. + state: Tracing-system-specific info to propagate. + """ + + def __init__(self, + trace_id: str, + span_id: str, + options: 'TraceOptions', + state: 'TraceState') -> None: + pass + + class Tracer: """Handles span creation and in-process context propagation. @@ -73,6 +127,10 @@ class Tracer: and controlling spans' lifecycles. """ + # Constant used to represent the current span being used as a parent. + # This is the default behavior when creating spans. + CURRENT_SPAN = Span() + def get_current_span(self) -> 'Span': """Gets the currently active span from the context. @@ -84,15 +142,21 @@ def get_current_span(self) -> 'Span': invalid :class:`.SpanContext`. """ - @contextmanager # type: ignore - def start_span(self, name: str, parent: 'Span') -> typing.Iterator['Span']: + def start_span(self, + name: str, + parent: typing.Union['Span', 'SpanContext'] = CURRENT_SPAN + ) -> typing.Iterator['Span']: """Context manager for span creation. - Create a new child of the current span, or create a root span if no - current span exists. Start the span and set it as the current span in + Create a new span. Start the span and set it as the current span in this tracer's context. + By default the current span will be used as parent, but an explicit + parent can also be specified, either a ``Span`` or a ``SpanContext``. + If the specified value is ``None``, the created span will be a root + span. + On exiting the context manager stop the span and set its parent as the current span. @@ -115,40 +179,48 @@ def start_span(self, name: str, parent: 'Span') -> typing.Iterator['Span']: is equivalent to:: - span = tracer.create_span(name, parent=tracer.get_current_span()) + span = tracer.create_span(name) with tracer.use_span(span): do_work() Args: name: The name of the span to be created. - parent: The span's parent. + parent: The span's parent. Defaults to the current span. Yields: The newly-created span. """ - def create_span(self, name: str, parent: 'Span') -> 'Span': - """Creates a new child span of the given parent. + def create_span(self, + name: str, + parent: typing.Union['Span', 'SpanContext'] = CURRENT_SPAN + ) -> 'Span': + """Creates a span. Creating the span does not start it, and should not affect the tracer's context. To start the span and update the tracer's context to make it the currently active span, see :meth:`use_span`. - Applications that need to explicitly set spans' parents or create spans - detached from the tracer's context should use this method. + By default the current span will be used as parent, but an explicit + parent can also be specified, either a Span or a SpanContext. + If the specified value is `None`, the created span will be a root + span. + + Applications that need to create spans detached from the tracer's + context should use this method. with tracer.start_span(name) as span: do_work() This is equivalent to:: - span = tracer.create_span(name, parent=tracer.get_current_span()) + span = tracer.create_span(name) with tracer.use_span(span): do_work() Args: name: The name of the span to be created. - parent: The span's parent. + parent: The span's parent. Defaults to the current span. Returns: The newly-created span. @@ -169,60 +241,6 @@ def use_span(self, span: 'Span') -> typing.Iterator[None]: """ -class Span: - """A span represents a single operation within a trace.""" - - def start(self) -> None: - """Sets the current time as the span's start time. - - Each span represents a single operation. The span's start time is the - wall time at which the operation started. - - Only the first call to ``start`` should modify the span, and - implementations are free to ignore or raise on further calls. - """ - - def end(self) -> None: - """Sets the current time as the span's end time. - - The span's end time is the wall time at which the operation finished. - - Only the first call to ``end`` should modify the span, and - implementations are free to ignore or raise on further calls. - """ - - def get_context(self) -> 'SpanContext': - """Gets the span's SpanContext. - - Get an immutable, serializable identifier for this span that can be - used to create new child spans. - - Returns: - A :class:`.SpanContext` with a copy of this span's immutable state. - """ - - -class SpanContext: - """The state of a Span to propagate between processes. - - This class includes the immutable attributes of a :class:`.Span` that must - be propagated to a span's children and across process boundaries. - - Args: - trace_id: The ID of the trace that this span belongs to. - span_id: This span's ID. - options: Trace options to propagate. - state: Tracing-system-specific info to propagate. - """ - - def __init__(self, - trace_id: str, - span_id: str, - options: 'TraceOptions', - state: 'TraceState') -> None: - pass - - # TODO class TraceOptions(int): pass