Skip to content

Commit

Permalink
Add fields property
Browse files Browse the repository at this point in the history
Fixes #1104
  • Loading branch information
ocelotl committed Nov 12, 2020
1 parent 26bf23f commit 579af1a
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 3 deletions.
1 change: 1 addition & 0 deletions opentelemetry-api/CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Add `fields` to propagators ([#1374](https://github.com/open-telemetry/opentelemetry-python/pull/1374))
- Add optional parameter to `record_exception` method ([#1314](https://github.com/open-telemetry/opentelemetry-python/pull/1314))

## Version 0.15b0
Expand Down
Expand Up @@ -87,6 +87,15 @@ def inject(
baggage_string = _format_baggage(baggage_entries)
set_in_carrier(carrier, self._BAGGAGE_HEADER_NAME, baggage_string)

@property
def fields(self) -> typing.Set[str]:
"""Returns a set with the fields set in `inject`.
See
`opentelemetry.trace.propagation.textmap.TextMapPropagator.fields`
"""
return {self._BAGGAGE_HEADER_NAME}


def _format_baggage(baggage_entries: typing.Mapping[str, object]) -> str:
return ",".join(
Expand Down
15 changes: 15 additions & 0 deletions opentelemetry-api/src/opentelemetry/propagators/composite.py
Expand Up @@ -65,3 +65,18 @@ def inject(
"""
for propagator in self._propagators:
propagator.inject(set_in_carrier, carrier, context)

@property
def fields(self) -> typing.Set[str]:
"""Returns a set with the fields set in `inject`.
See
`opentelemetry.trace.propagation.textmap.TextMapPropagator.fields`
"""
composite_fields = set()

for propagator in self._propagators:
for field in propagator.fields:
composite_fields.add(field)

return composite_fields
12 changes: 12 additions & 0 deletions opentelemetry-api/src/opentelemetry/trace/propagation/textmap.py
Expand Up @@ -129,3 +129,15 @@ def inject(
context if not set.
"""

@abc.abstractmethod
def fields(self) -> typing.Set[str]:
"""
Gets the fields set in the carrier by the `inject` method.
If the carrier is reused, its fields that correspond with the ones
present in this attribute should be deleted before calling `inject`.
Returns:
A set with the fields set in `inject`.
"""
Expand Up @@ -132,6 +132,17 @@ def inject(
carrier, self._TRACESTATE_HEADER_NAME, tracestate_string
)

@property
def fields(self) -> typing.Set[str]:
"""Returns a set with the fields set in `inject`.
See
`opentelemetry.trace.propagation.textmap.TextMapPropagator.fields`
"""
return {
self._TRACEPARENT_HEADER_NAME, self._TRACESTATE_HEADER_NAME
}


def _parse_tracestate(header_list: typing.List[str]) -> trace.TraceState:
"""Parse one or more w3c tracestate header into a TraceState.
Expand Down
17 changes: 16 additions & 1 deletion opentelemetry-api/tests/baggage/test_baggage_propagation.py
Expand Up @@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
import typing
import unittest
from unittest.mock import patch, Mock

from opentelemetry import baggage
from opentelemetry.baggage.propagation import BaggagePropagator
Expand Down Expand Up @@ -142,3 +142,18 @@ def test_inject_non_string_values(self):
self.assertIn("key1=True", output)
self.assertIn("key2=123", output)
self.assertIn("key3=123.567", output)

@patch("opentelemetry.baggage.propagation.baggage")
@patch("opentelemetry.baggage.propagation._format_baggage")
def test_fields(self, mock_format_baggage, mock_baggage):

mock_set_in_carrier = Mock()

self.propagator.inject(mock_set_in_carrier, {})

inject_fields = set()

for mock_call in mock_set_in_carrier.mock_calls:
inject_fields.add(mock_call.args[1])

self.assertEqual(inject_fields, self.propagator.fields)
37 changes: 35 additions & 2 deletions opentelemetry-api/tests/propagators/test_composite.py
Expand Up @@ -26,6 +26,8 @@ def get_as_list(dict_object, key):
def mock_inject(name, value="data"):
def wrapped(setter, carrier=None, context=None):
carrier[name] = value
setter(None, "inject_field_{}_0".format(name), None)
setter(None, "inject_field_{}_1".format(name), None)

return wrapped

Expand All @@ -39,18 +41,29 @@ def wrapped(getter, carrier=None, context=None):
return wrapped


def mock_fields(name):
return {
"inject_field_{}_0".format(name), "inject_field_{}_1".format(name)
}


class TestCompositePropagator(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.mock_propagator_0 = Mock(
inject=mock_inject("mock-0"), extract=mock_extract("mock-0")
inject=mock_inject("mock-0"),
extract=mock_extract("mock-0"),
fields=mock_fields("mock-0"),
)
cls.mock_propagator_1 = Mock(
inject=mock_inject("mock-1"), extract=mock_extract("mock-1")
inject=mock_inject("mock-1"),
extract=mock_extract("mock-1"),
fields=mock_fields("mock-1"),
)
cls.mock_propagator_2 = Mock(
inject=mock_inject("mock-0", value="data2"),
extract=mock_extract("mock-0", value="context2"),
fields=mock_fields("mock-0"),
)

def test_no_propagators(self):
Expand Down Expand Up @@ -105,3 +118,23 @@ def test_multiple_propagators_same_key(self):
get_as_list, carrier=new_carrier, context={}
)
self.assertEqual(context, {"mock-0": "context2"})

def test_fields(self):
propagator = CompositeHTTPPropagator(
[
self.mock_propagator_0,
self.mock_propagator_1,
self.mock_propagator_2
]
)

mock_set_in_carrier = Mock()

propagator.inject(mock_set_in_carrier, {})

inject_fields = set()

for mock_call in mock_set_in_carrier.mock_calls:
inject_fields.add(mock_call.args[1])

self.assertEqual(inject_fields, propagator.fields)
1 change: 1 addition & 0 deletions opentelemetry-sdk/CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Add `fields` to propagators ([#1374](https://github.com/open-telemetry/opentelemetry-python/pull/1374))
- Add optional parameter to `record_exception` method ([#1314](https://github.com/open-telemetry/opentelemetry-python/pull/1314))

## Version 0.15b0
Expand Down
Expand Up @@ -152,6 +152,15 @@ def inject(
)
set_in_carrier(carrier, self.SAMPLED_KEY, "1" if sampled else "0")

@property
def fields(self) -> typing.Set[str]:
return {
self.TRACE_ID_KEY,
self.SPAN_ID_KEY,
self.PARENT_SPAN_ID_KEY,
self.SAMPLED_KEY,
}


def format_trace_id(trace_id: int) -> str:
"""Format the trace id according to b3 specification."""
Expand Down
19 changes: 19 additions & 0 deletions opentelemetry-sdk/tests/trace/propagation/test_b3_format.py
Expand Up @@ -14,6 +14,7 @@

import unittest
from unittest.mock import patch
from unittest.mock import Mock

import opentelemetry.sdk.trace as trace
import opentelemetry.sdk.trace.propagation.b3_format as b3_format
Expand Down Expand Up @@ -329,3 +330,21 @@ def setter(carrier, key, value):

ctx = FORMAT.extract(CarrierGetter(), {})
FORMAT.inject(setter, {}, ctx)

def test_fields(self):
"""Make sure the fields attribute returns the fields used in inject"""

tracer = trace.TracerProvider().get_tracer("sdk_tracer_provider")

mock_set_in_carrier = Mock()

with tracer.start_as_current_span("parent"):
with tracer.start_as_current_span("child"):
FORMAT.inject(mock_set_in_carrier, {})

inject_fields = set()

for call in mock_set_in_carrier.mock_calls:
inject_fields.add(call.args[1])

self.assertEqual(FORMAT.fields, inject_fields)

0 comments on commit 579af1a

Please sign in to comment.