Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Oct 19, 2023. It is now read-only.

[TEST PR only] WIP Span: add attribute, event, link setter to the API #1

Closed
wants to merge 13 commits into from
Closed
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
30 changes: 30 additions & 0 deletions opentelemetry-api/src/opentelemetry/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import typing

from opentelemetry import loader
from opentelemetry import types

# TODO: quarantine
ParentSpan = typing.Optional[typing.Union['Span', 'SpanContext']]
Expand Down Expand Up @@ -102,6 +103,35 @@ def get_context(self) -> 'SpanContext':
A :class:`.SpanContext` with a copy of this span's immutable state.
"""

def set_attribute(self: 'Span',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the type annotation used for self parameters anywhere in the file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They do that in the subclass in:
opentelemetry-sdk/src/opentelemetry/sdk/trace/init.py
Not sure if the inconsistency is on purpose

key: str,
value: types.AttributeValue,
) -> None:
"""Sets an Attribute.

Sets a single Attribute with the key and value passed as arguments.
"""

def add_event(self: 'Span',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

name: str,
attributes: types.Attributes = None,
) -> None:
"""Adds an Event.

Adds a single Event with the name and, optionally, attributes passed
as arguments.
"""

def add_link(self: 'Span',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

link_target_context: 'SpanContext',
attributes: types.Attributes = None,
) -> None:
"""Adds a Link to another span.

Adds a single Link from this Span to another Span identified by the
`SpanContext` passed as argument.
"""


class TraceOptions(int):
"""A bitmask that represents options specific to the trace.
Expand Down
14 changes: 9 additions & 5 deletions opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,27 +230,31 @@ def get_context(self):

def set_attribute(self: 'Span',
key: str,
value: 'types.AttributeValue'
value: types.AttributeValue,
) -> None:
if self.attributes is Span.empty_attributes:
self.attributes = BoundedDict(MAX_NUM_ATTRIBUTES)
self.attributes[key] = value

def add_event(self: 'Span',
name: str,
attributes: 'types.Attributes',
attributes: types.Attributes = None,
) -> None:
if self.events is Span.empty_events:
self.events = BoundedList(MAX_NUM_EVENTS)
if attributes is None:
attributes = Span.empty_attributes
self.events.append(Event(name, attributes))

def add_link(self: 'Span',
context: 'trace_api.SpanContext',
attributes: 'types.Attributes',
link_target_context: 'trace_api.SpanContext',
attributes: types.Attributes = None,
) -> None:
if self.links is Span.empty_links:
self.links = BoundedList(MAX_NUM_LINKS)
self.links.append(Link(context, attributes))
if attributes is None:
attributes = Span.empty_attributes
self.links.append(Link(link_target_context, attributes))

def start(self):
if self.start_time is None:
Expand Down
68 changes: 68 additions & 0 deletions opentelemetry-sdk/tests/trace/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,74 @@ def test_start_span_explicit(self):
self.assertIs(tracer.get_current_span(), root)
self.assertIsNotNone(child.end_time)

def test_span_members(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test check anything? Like if the attribute was overwritten properly?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it does not test. I think it can be added later when the attributes are actually used (when serialising?). I will add a comment in the commitmsg though.

context = contextvars.ContextVar('test_span_members')
tracer = trace.Tracer(context)

other_context1 = trace_api.SpanContext(
trace_id=trace.generate_trace_id(),
span_id=trace.generate_span_id()
)
other_context2 = trace_api.SpanContext(
trace_id=trace.generate_trace_id(),
span_id=trace.generate_span_id()
)

self.assertIsNone(tracer.get_current_span())

with tracer.start_span('root') as root:
root.set_attribute('component', 'http')
root.set_attribute('http.method', 'GET')
root.set_attribute('http.url',
'https://example.com:779/path/12/?q=d#123')
root.set_attribute('http.status_code', 200)
root.set_attribute('http.status_text', 'OK')
root.set_attribute('misc.pi', 3.14)

# Setting an attribute with the same key as an existing attribute
# SHOULD overwrite the existing attribute's value.
root.set_attribute('attr-key', 'attr-value1')
root.set_attribute('attr-key', 'attr-value2')

root.add_event('event0')
root.add_event('event1', {'name': 'birthday'})

root.add_link(other_context1)
root.add_link(other_context2, {'name': 'neighbor'})

# The public API does not expose getters.
# Checks by accessing the span members directly

self.assertEqual(len(root.attributes), 7)
self.assertEqual(root.attributes['component'], 'http')
self.assertEqual(root.attributes['http.method'], 'GET')
self.assertEqual(root.attributes['http.url'],
'https://example.com:779/path/12/?q=d#123')
self.assertEqual(root.attributes['http.status_code'], 200)
self.assertEqual(root.attributes['http.status_text'], 'OK')
self.assertEqual(root.attributes['misc.pi'], 3.14)
self.assertEqual(root.attributes['attr-key'], 'attr-value2')

self.assertEqual(len(root.events), 2)
self.assertEqual(root.events[0],
trace.Event(name='event0',
attributes={}))
self.assertEqual(root.events[1],
trace.Event(name='event1',
attributes={'name': 'birthday'}))

self.assertEqual(len(root.links), 2)
self.assertEqual(root.links[0].context.trace_id,
other_context1.trace_id)
self.assertEqual(root.links[0].context.span_id,
other_context1.span_id)
self.assertEqual(root.links[0].attributes, {})
self.assertEqual(root.links[1].context.trace_id,
other_context2.trace_id)
self.assertEqual(root.links[1].context.span_id,
other_context2.span_id)
self.assertEqual(root.links[1].attributes, {'name': 'neighbor'})


class TestSpan(unittest.TestCase):

Expand Down