Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions opencensus/trace/span.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ def __init__(
self._child_spans = []
self.context_tracer = context_tracer
self.span_kind = span_kind
for callback in Span._on_create_callbacks:
callback(self)

_on_create_callbacks = []

@staticmethod
def on_create(callback):
Span._on_create_callbacks.append(callback)

@property
def children(self):
Expand Down
18 changes: 10 additions & 8 deletions opencensus/trace/span_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def __init__(
trace_id=None,
span_id=None,
trace_options=None,
tracestate=None,
from_header=False):
if trace_id is None:
trace_id = generate_trace_id()
Expand All @@ -69,21 +70,22 @@ def __init__(
self.trace_id = self._check_trace_id(trace_id)
self.span_id = self._check_span_id(span_id)
self.trace_options = trace_options
self.tracestate = tracestate

def __str__(self):
"""Returns a string form of the SpanContext. This is the format of
the Trace Context Header and should be forwarded to downstream
requests as the X-Cloud-Trace-Context header.
def __repr__(self):
"""Returns a string form of the SpanContext.

:rtype: str
:returns: String form of the SpanContext.
"""
enabled = self.trace_options.enabled
header = '{}/{};o={}'.format(
fmt = '{}(trace_id={}, span_id={}, trace_options={}, tracestate={})'
return fmt.format(
type(self).__name__,
self.trace_id,
self.span_id,
int(enabled))
return header
self.trace_options,
self.tracestate,
)

def _check_span_id(self, span_id):
"""Check the format of the span_id to ensure it is 16-character hex
Expand Down
7 changes: 7 additions & 0 deletions opencensus/trace/trace_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ def check_trace_options(self, trace_options_byte):

return trace_options_byte

def __repr__(self):
fmt = '{}(enabled={})'
return fmt.format(
type(self).__name__,
self.get_enabled,
)

@property
def get_enabled(self):
"""Get the last bit from the trace options which is the enabled field.
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/trace/test_span.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,21 @@ def test_finish(self):
span.finish()
self.assertIsNotNone(span.end_time)

def test_on_create(self):
from opencensus.trace.span import Span
self.on_create_called = False
span = self._make_one('span1')
self.assertFalse(self.on_create_called)
try:
@Span.on_create
def callback(span):
self.on_create_called = True
span = self._make_one('span2')
finally:
Span._on_create_callbacks = []
self.assertTrue(self.on_create_called)
del self.on_create_called

def test___iter__(self):
root_span_name = 'root_span_name'
child1_span_name = 'child1_span_name'
Expand Down
16 changes: 10 additions & 6 deletions tests/unit/trace/test_span_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import unittest
from opencensus.trace import span_context as span_context_module
from opencensus.trace.trace_options import TraceOptions
from opencensus.trace.tracestate import Tracestate


class TestSpanContext(unittest.TestCase):
Expand All @@ -38,17 +39,20 @@ def test_constructor(self):
self.assertEqual(span_context.trace_id, self.trace_id)
self.assertEqual(span_context.span_id, self.span_id)

def test__str__(self):
def test__repr__(self):
span_context = self._make_one(
trace_id=self.trace_id,
span_id=self.span_id,
trace_options=TraceOptions('1'))
trace_options=TraceOptions('1'),
tracestate=Tracestate())

header_expected = '6e0c63257de34c92bf9efcd03927272e' \
'/6e0c63257de34c92;o=1'
header = span_context.__str__()
expected_repr = 'SpanContext(' \
'trace_id=6e0c63257de34c92bf9efcd03927272e, ' \
'span_id=6e0c63257de34c92, ' \
'trace_options=TraceOptions(enabled=True), ' \
'tracestate=Tracestate())'

self.assertEqual(header_expected, header)
self.assertEqual(expected_repr, span_context.__repr__())

def test_check_span_id_none(self):
span_context = self._make_one(
Expand Down