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