Skip to content
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

Initial support for explicit Span parent support. #33

Merged
merged 7 commits into from
Jul 3, 2019
150 changes: 84 additions & 66 deletions opentelemetry-api/src/opentelemetry/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,71 @@
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.

This class provides methods for manipulating the context, creating spans,
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.

Expand All @@ -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.

Expand All @@ -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.
Expand All @@ -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
Expand Down