Skip to content

Commit

Permalink
Add attributes in method AbstractSpan.link(cls, traceparent) (#10906)
Browse files Browse the repository at this point in the history
* Initial Commit

* test + log + lint

* comments

* oops

* fix test
  • Loading branch information
rakshith91 authored Apr 21, 2020
1 parent a42c806 commit bd99ea5
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 27 deletions.
4 changes: 4 additions & 0 deletions sdk/core/azure-core-tracing-opencensus/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

# Release History

## 1.0.0b6 (Unreleased)

- `link` and `link_from_headers` now accept attributes.

## 1.0.0b5 (2019-01-14)

### Bugfix
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,20 @@
TYPE_CHECKING = False

if TYPE_CHECKING:
from typing import Dict, Optional, Union, Callable
from typing import Dict, Optional, Union, Callable, Sequence

from azure.core.pipeline.transport import HttpRequest, HttpResponse
AttributeValue = Union[
str,
bool,
int,
float,
Sequence[str],
Sequence[bool],
Sequence[int],
Sequence[float],
]
Attributes = Optional[Dict[str, AttributeValue]]


__version__ = VERSION
Expand Down Expand Up @@ -160,8 +171,8 @@ def get_trace_parent(self):
return self.to_header()['traceparent']

@classmethod
def link(cls, traceparent):
# type: (str) -> None
def link(cls, traceparent, attributes=None):
# type: (str, Attributes) -> None
"""
Links the context to the current tracer.
Expand All @@ -170,11 +181,11 @@ def link(cls, traceparent):
"""
cls.link_from_headers({
'traceparent': traceparent
})
}, attributes)

@classmethod
def link_from_headers(cls, headers):
# type: (Dict[str, str]) -> None
def link_from_headers(cls, headers, attributes=None):
# type: (Dict[str, str], Attributes) -> None
"""
Given a dictionary, extracts the context and links the context to the current tracer.
Expand All @@ -183,7 +194,11 @@ def link_from_headers(cls, headers):
"""
ctx = trace_context_http_header_format.TraceContextPropagator().from_headers(headers)
current_span = cls.get_current_span()
current_span.add_link(Link(ctx.trace_id, ctx.span_id))
current_span.add_link(Link(
trace_id=ctx.trace_id,
span_id=ctx.span_id,
attributes=attributes
))

@classmethod
def get_current_span(cls):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from azure.core.tracing.ext.opencensus_span import OpenCensusSpan
from azure.core.tracing import SpanKind
from opencensus.trace import tracer as tracer_module
from opencensus.trace.attributes import Attributes
from opencensus.trace.span import SpanKind as OpenCensusSpanKind
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.base_exporter import Exporter
Expand Down Expand Up @@ -105,6 +106,20 @@ def test_links(self):
assert link.trace_id == "2578531519ed94423ceae67588eff2c9"
assert link.span_id == "231ebdc614cb9ddd"

def test_links_with_attributes(self):
attributes = {"attr1": 1}
with ContextHelper() as ctx:
trace = tracer_module.Tracer(sampler=AlwaysOnSampler())
og_header = {"traceparent": "00-2578531519ed94423ceae67588eff2c9-231ebdc614cb9ddd-02"}
wrapped_class = OpenCensusSpan()
OpenCensusSpan.link_from_headers(og_header, attributes)
assert len(wrapped_class.span_instance.links) == 1
link = wrapped_class.span_instance.links[0]
assert link.trace_id == "2578531519ed94423ceae67588eff2c9"
assert link.span_id == "231ebdc614cb9ddd"
assert link.attributes == attributes
assert "attr1" in link.attributes

def test_add_attribute(self):
with ContextHelper() as ctx:
trace = tracer_module.Tracer(sampler=AlwaysOnSampler())
Expand Down
1 change: 1 addition & 0 deletions sdk/core/azure-core-tracing-opentelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-------------------
## 1.0.0b4 (Unreleased)

- `link` and `link_from_headers` now accepts attributes.

## 1.0.0b3 (2020-04-06)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,20 @@
TYPE_CHECKING = False

if TYPE_CHECKING:
from typing import Dict, Optional, Union, Callable
from typing import Dict, Optional, Union, Callable, Sequence

from azure.core.pipeline.transport import HttpRequest, HttpResponse
AttributeValue = Union[
str,
bool,
int,
float,
Sequence[str],
Sequence[bool],
Sequence[int],
Sequence[float],
]
Attributes = Optional[Dict[str, AttributeValue]]

__version__ = VERSION

Expand Down Expand Up @@ -171,8 +182,8 @@ def get_trace_parent(self):
return self.to_header()['traceparent']

@classmethod
def link(cls, traceparent):
# type: (str) -> None
def link(cls, traceparent, attributes=None):
# type: (str, Attributes) -> None
"""
Links the context to the current tracer.
Expand All @@ -181,11 +192,11 @@ def link(cls, traceparent):
"""
cls.link_from_headers({
'traceparent': traceparent
})
}, attributes)

@classmethod
def link_from_headers(cls, headers):
# type: (Dict[str, str]) -> None
def link_from_headers(cls, headers, attributes=None):
# type: (Dict[str, str], Attributes) -> None
"""
Given a dictionary, extracts the context and links the context to the current tracer.
Expand All @@ -195,7 +206,7 @@ def link_from_headers(cls, headers):
ctx = extract(_get_headers_from_http_request_headers, headers)
span_ctx = get_span_from_context(ctx).get_context()
current_span = cls.get_current_span()
current_span.links.append(Link(span_ctx))
current_span.links.append(Link(span_ctx, attributes))

@classmethod
def get_current_span(cls):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,33 @@ def test_links(self, tracer):
assert link.context.trace_id == int("2578531519ed94423ceae67588eff2c9", 16)
assert link.context.span_id == int("231ebdc614cb9ddd", 16)

def test_links_with_attribute(self, tracer):
with tracer.start_as_current_span("Root") as parent:
attributes = {"attribute1": 1, "attribute2": 2}
og_header = {"traceparent": "00-2578531519ed94423ceae67588eff2c9-231ebdc614cb9ddd-02"}
with OpenTelemetrySpan() as wrapped_class:
OpenTelemetrySpan.link_from_headers(og_header, attributes)

assert len(wrapped_class.span_instance.links) == 1
link = wrapped_class.span_instance.links[0]

assert link.context.trace_id == int("2578531519ed94423ceae67588eff2c9", 16)
assert link.context.span_id == int("231ebdc614cb9ddd", 16)
assert "attribute1" in link.attributes
assert "attribute2" in link.attributes
assert link.attributes == attributes

with OpenTelemetrySpan() as wrapped_class:
OpenTelemetrySpan.link("00-2578531519ed94423ceae67588eff2c9-231ebdc614cb9ddd-02", attributes)

assert len(wrapped_class.span_instance.links) == 1
link = wrapped_class.span_instance.links[0]

assert link.context.trace_id == int("2578531519ed94423ceae67588eff2c9", 16)
assert link.context.span_id == int("231ebdc614cb9ddd", 16)
assert "attribute1" in link.attributes
assert "attribute2" in link.attributes
assert link.attributes == attributes

def test_add_attribute(self, tracer):
with tracer.start_as_current_span("Root") as parent:
Expand Down
1 change: 1 addition & 0 deletions sdk/core/azure-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
### Features

- Support "x-ms-retry-after-ms" in response header #10743
- `link` and `link_from_headers` now accepts attributes #10765

### Bug fixes

Expand Down
21 changes: 16 additions & 5 deletions sdk/core/azure-core/azure/core/tracing/_abstract_span.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,21 @@
TYPE_CHECKING = False

if TYPE_CHECKING:
from typing import Any, Dict, Optional, Union, Callable, ContextManager
from typing import Any, Sequence, Dict, Optional, Union, Callable, ContextManager

from azure.core.pipeline.transport import HttpRequest, HttpResponse, AsyncHttpResponse
HttpResponseType = Union[HttpResponse, AsyncHttpResponse]
AttributeValue = Union[
str,
bool,
int,
float,
Sequence[str],
Sequence[bool],
Sequence[int],
Sequence[float],
]
Attributes = Optional[Dict[str, AttributeValue]]

try:
from typing_extensions import Protocol
Expand Down Expand Up @@ -119,8 +130,8 @@ def span_instance(self):
"""

@classmethod
def link(cls, traceparent):
# type: (Dict[str, str]) -> None
def link(cls, traceparent, attributes=None):
# type: (Dict[str, str], Attributes) -> None
"""
Given a traceparent, extracts the context and links the context to the current tracer.
Expand All @@ -129,8 +140,8 @@ def link(cls, traceparent):
"""

@classmethod
def link_from_headers(cls, headers):
# type: (Dict[str, str]) -> None
def link_from_headers(cls, headers, attributes=None):
# type: (Dict[str, str], Attributes) -> None
"""
Given a dictionary, extracts the context and links the context to the current tracer.
Expand Down
25 changes: 17 additions & 8 deletions sdk/core/azure-core/tests/tracing_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@
"""Fake implementation of AbstractSpan for tests."""
from contextlib import contextmanager
from azure.core.tracing import HttpSpanMixin, SpanKind

from typing import Union, Sequence, Optional, Dict
AttributeValue = Union[
str,
bool,
int,
float,
Sequence[str],
Sequence[bool],
Sequence[int],
Sequence[float],
]
Attributes = Optional[Dict[str, AttributeValue]]

class FakeSpan(HttpSpanMixin, object):
# Keep a fake context of the current one
Expand Down Expand Up @@ -126,8 +137,8 @@ def get_trace_parent(self):
return self.to_header()['traceparent']

@classmethod
def link(cls, traceparent):
# type: (str) -> None
def link(cls, traceparent, attributes=None):
# type: (str, Attributes) -> None
"""
Links the context to the current tracer.
Expand All @@ -139,17 +150,15 @@ def link(cls, traceparent):
})

@classmethod
def link_from_headers(cls, headers):
# type: (Dict[str, str]) -> None
def link_from_headers(cls, headers, attributes=None):
# type: (Dict[str, str], Attributes) -> None
"""
Given a dictionary, extracts the context and links the context to the current tracer.
:param headers: A key value pair dictionary
:type headers: dict
"""
ctx = extract(_get_headers_from_http_request_headers, headers)
current_span = cls.get_current_span()
current_span.add_link(ctx)
raise NotImplementedError("This method needs to be implemented")

@classmethod
def get_current_span(cls):
Expand Down

0 comments on commit bd99ea5

Please sign in to comment.