From 6ca05d6d1b4402e506c8c373d9c8de3f0860a360 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 3 Jun 2021 15:03:33 -0700 Subject: [PATCH 01/22] adding support for dropped attributes/events/links to jaeger exporters --- .../jaeger/proto/grpc/translate/__init__.py | 16 ++++++ .../tests/test_jaeger_exporter_protobuf.py | 48 ++++++++++++++++-- .../jaeger/thrift/translate/__init__.py | 17 +++++++ .../tests/test_jaeger_exporter_thrift.py | 49 ++++++++++++++++++- .../opentelemetry/sdk/resources/__init__.py | 6 +++ .../src/opentelemetry/sdk/trace/__init__.py | 24 +++++++++ tox.ini | 16 ++++++ 7 files changed, 170 insertions(+), 6 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py index e644e21360..0fb9bfc7ff 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py @@ -240,6 +240,9 @@ def _translate_span(self, span: ReadableSpan) -> model_pb2.Span: tags = self._extract_tags(span) refs = self._extract_refs(span) logs = self._extract_logs(span) + dropped_tags = self._dropped_tags(span) + if dropped_tags: + tags.extend(dropped_tags) flags = int(ctx.trace_flags) @@ -368,3 +371,16 @@ def _extract_logs( logs.append(model_pb2.Log(timestamp=event_ts, fields=fields)) return logs + + def _dropped_tags( + self, span: ReadableSpan + ) -> Sequence[model_pb2.KeyValue]: + tags = [] + if span.dropped_attributes: + tags.append(_get_long_key_value("otel.dropped_attributes_count", span.dropped_attributes)) + if span.dropped_events: + tags.append(_get_long_key_value("otel.dropped_events_count", span.dropped_events)) + if span.dropped_links: + tags.append(_get_long_key_value("otel.dropped_links_count", span.dropped_links)) + + return tags diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py index 383e33d0f1..7419f09688 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py @@ -471,9 +471,49 @@ def test_export_span_service_name(self): exporter._grpc_client = client_mock exporter.export([span]) self.assertEqual(exporter.service_name, "test") + + def test_dropped_values(self): + links = [] + for i in range(129): + links.append(trace._Span(name="span{}".format(i),context=trace_api.INVALID_SPAN_CONTEXT)) + span = trace._Span( + limits=trace.SpanLimits(), + name="span", + resource=Resource( + attributes={ + "key_resource": "some_resource some_resource some_more_resource" + } + ), + context=trace_api.SpanContext( + trace_id=0x000000000000000000000000DEADBEEF, + span_id=0x00000000DEADBEF0, + is_remote=False, + ), + links=links + ) + + span.start() + for i in range(130): + span.set_attribute("key{}".format(i), "value{}".format(i)) + for i in range(131): + span.add_event("event{}".format(i)) + span.end() + translate = Translate([span]) + + # pylint: disable=protected-access + spans = translate._translate(pb_translator.ProtobufTranslator("svc")) + tags_by_keys = { + tag.key: tag.v_str or tag.v_int64 + for tag in spans[0].tags + } + self.assertEqual( + 1, tags_by_keys["otel.dropped_links_count"] + ) + self.assertEqual( + 2, tags_by_keys["otel.dropped_attributes_count"] + ) + self.assertEqual( + 3, tags_by_keys["otel.dropped_events_count"] + ) -class MockResponse: - def __init__(self, status_code): - self.status_code = status_code - self.text = status_code diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py index c48c8bde8f..ffe2a8b8ef 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py @@ -162,6 +162,9 @@ def _translate_span(self, span: ReadableSpan) -> TCollector.Span: tags = self._extract_tags(span) refs = self._extract_refs(span) logs = self._extract_logs(span) + dropped_tags = self._dropped_tags(span) + if dropped_tags: + tags.extend(dropped_tags) flags = int(ctx.trace_flags) @@ -285,3 +288,17 @@ def _extract_logs( ) return logs + + def _dropped_tags( + self, span: ReadableSpan + ) -> Sequence[TCollector.Tag]: + tags = [] + print(span.dropped_attributes) + if span.dropped_attributes: + tags.append(_get_long_tag("otel.dropped_attributes_count", span.dropped_attributes)) + if span.dropped_events: + tags.append(_get_long_tag("otel.dropped_events_count", span.dropped_events)) + if span.dropped_links: + tags.append(_get_long_tag("otel.dropped_links_count", span.dropped_links)) + + return tags \ No newline at end of file diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py index 9c1773d4fa..eacfc57d25 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py @@ -559,7 +559,7 @@ def test_max_tag_value_length(self): # pylint: disable=protected-access spans = translate._translate(ThriftTranslator()) tags_by_keys = { - tag.key: tag.vStr for tag in spans[0].tags if tag.vType == 0 + tag.key: tag.vStr for tag in spans[0].tags if tag.vType == jaeger.TagType.STRING } self.assertEqual( "hello_world hello_world hello_world", tags_by_keys["key_string"] @@ -576,11 +576,56 @@ def test_max_tag_value_length(self): # pylint: disable=protected-access spans = translate._translate(ThriftTranslator(max_tag_value_length=5)) tags_by_keys = { - tag.key: tag.vStr for tag in spans[0].tags if tag.vType == 0 + tag.key: tag.vStr for tag in spans[0].tags if tag.vType == jaeger.TagType.STRING } self.assertEqual("hello", tags_by_keys["key_string"]) self.assertEqual("('tup", tags_by_keys["key_tuple"]) self.assertEqual("some_", tags_by_keys["key_resource"]) + + def test_dropped_values(self): + links = [] + for i in range(129): + links.append(trace._Span(name="span{}".format(i),context=trace_api.INVALID_SPAN_CONTEXT)) + span = trace._Span( + limits=trace.SpanLimits(), + name="span", + resource=Resource( + attributes={ + "key_resource": "some_resource some_resource some_more_resource" + } + ), + context=trace_api.SpanContext( + trace_id=0x000000000000000000000000DEADBEEF, + span_id=0x00000000DEADBEF0, + is_remote=False, + ), + links=links + ) + + span.start() + for i in range(130): + span.set_attribute("key{}".format(i), "value{}".format(i)) + for i in range(131): + span.add_event("event{}".format(i)) + + span.end() + translate = Translate([span]) + + # pylint: disable=protected-access + spans = translate._translate(ThriftTranslator(max_tag_value_length=5)) + tags_by_keys = { + tag.key: tag.vLong for tag in spans[0].tags if tag.vType == jaeger.TagType.LONG + } + + self.assertEqual( + 1, tags_by_keys["otel.dropped_links_count"] + ) + self.assertEqual( + 2, tags_by_keys["otel.dropped_attributes_count"] + ) + self.assertEqual( + 3, tags_by_keys["otel.dropped_events_count"] + ) def test_agent_client_split(self): agent_client = jaeger_exporter.AgentClientUDP( diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index 24e5321ce9..ae96b5e3f3 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -193,6 +193,12 @@ def attributes(self) -> Attributes: def schema_url(self) -> str: return self._schema_url + @property + def dropped_attributes(self) -> int: + if self._attributes: + return self._attributes.dropped + return 0 + def merge(self, other: "Resource") -> "Resource": """Merges this resource and an updating resource into a new `Resource`. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 66b4b38390..7499e194ba 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -317,6 +317,12 @@ def __init__( @property def attributes(self) -> types.Attributes: return self._attributes + + @property + def dropped_attributes(self) -> int: + if self._attributes: + return self._attributes.dropped + return 0 def _check_span_ended(func): @@ -365,6 +371,24 @@ def __init__( self._resource = resource self._status = status + @property + def dropped_attributes(self) -> int: + if self._attributes: + return self._attributes.dropped + return 0 + + @property + def dropped_events(self) -> int: + if self._events: + return self._events.dropped + return 0 + + @property + def dropped_links(self) -> int: + if self._links: + return self._links.dropped + return 0 + @property def name(self) -> str: return self._name diff --git a/tox.ini b/tox.ini index 635c3c2df9..fe2ff8482b 100644 --- a/tox.ini +++ b/tox.ini @@ -279,3 +279,19 @@ deps = GitPython commands = python {toxinidir}/scripts/public_symbols_checker.py + +[generate:jaeger] +basepython: python3.9 +recreate = True +setenv = + PROTO_INCLUDES=" + -I proto/api_v2 \ + -I vendor/github.com/grpc-ecosystem/grpc-gateway \ + -I vendor/github.com/gogo/googleapis \ + -I vendor/github.com/gogo/protobuf/protobuf \ + -I vendor/github.com/gogo/protobuf" +deps = + grpcio-tools + protoc-gen-swagger +commands = + python -m grpc_tools.protoc ${PROTO_INCLUDES} --grpc_python_out=./python_out --python_out=./python_out model/proto/api_v2/query.proto \ No newline at end of file From 48193ca7ca60ee8e3b441ee8c48b12f3488e8f96 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 3 Jun 2021 15:05:14 -0700 Subject: [PATCH 02/22] cleanup --- .../exporter/jaeger/thrift/translate/__init__.py | 1 - tox.ini | 16 ---------------- 2 files changed, 17 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py index ffe2a8b8ef..63fc93021b 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py @@ -293,7 +293,6 @@ def _dropped_tags( self, span: ReadableSpan ) -> Sequence[TCollector.Tag]: tags = [] - print(span.dropped_attributes) if span.dropped_attributes: tags.append(_get_long_tag("otel.dropped_attributes_count", span.dropped_attributes)) if span.dropped_events: diff --git a/tox.ini b/tox.ini index fe2ff8482b..635c3c2df9 100644 --- a/tox.ini +++ b/tox.ini @@ -279,19 +279,3 @@ deps = GitPython commands = python {toxinidir}/scripts/public_symbols_checker.py - -[generate:jaeger] -basepython: python3.9 -recreate = True -setenv = - PROTO_INCLUDES=" - -I proto/api_v2 \ - -I vendor/github.com/grpc-ecosystem/grpc-gateway \ - -I vendor/github.com/gogo/googleapis \ - -I vendor/github.com/gogo/protobuf/protobuf \ - -I vendor/github.com/gogo/protobuf" -deps = - grpcio-tools - protoc-gen-swagger -commands = - python -m grpc_tools.protoc ${PROTO_INCLUDES} --grpc_python_out=./python_out --python_out=./python_out model/proto/api_v2/query.proto \ No newline at end of file From db8ef5cc7f4d274ce0b4ae7dec0f35ac13e41214 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 3 Jun 2021 15:06:06 -0700 Subject: [PATCH 03/22] lint --- .../jaeger/thrift/translate/__init__.py | 22 +++++++----- .../tests/test_jaeger_exporter_thrift.py | 35 +++++++++++-------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py index 63fc93021b..ad99936505 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py @@ -289,15 +289,21 @@ def _extract_logs( return logs - def _dropped_tags( - self, span: ReadableSpan - ) -> Sequence[TCollector.Tag]: + def _dropped_tags(self, span: ReadableSpan) -> Sequence[TCollector.Tag]: tags = [] if span.dropped_attributes: - tags.append(_get_long_tag("otel.dropped_attributes_count", span.dropped_attributes)) + tags.append( + _get_long_tag( + "otel.dropped_attributes_count", span.dropped_attributes + ) + ) if span.dropped_events: - tags.append(_get_long_tag("otel.dropped_events_count", span.dropped_events)) + tags.append( + _get_long_tag("otel.dropped_events_count", span.dropped_events) + ) if span.dropped_links: - tags.append(_get_long_tag("otel.dropped_links_count", span.dropped_links)) - - return tags \ No newline at end of file + tags.append( + _get_long_tag("otel.dropped_links_count", span.dropped_links) + ) + + return tags diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py index eacfc57d25..0cbc7c408f 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py @@ -559,7 +559,9 @@ def test_max_tag_value_length(self): # pylint: disable=protected-access spans = translate._translate(ThriftTranslator()) tags_by_keys = { - tag.key: tag.vStr for tag in spans[0].tags if tag.vType == jaeger.TagType.STRING + tag.key: tag.vStr + for tag in spans[0].tags + if tag.vType == jaeger.TagType.STRING } self.assertEqual( "hello_world hello_world hello_world", tags_by_keys["key_string"] @@ -576,16 +578,23 @@ def test_max_tag_value_length(self): # pylint: disable=protected-access spans = translate._translate(ThriftTranslator(max_tag_value_length=5)) tags_by_keys = { - tag.key: tag.vStr for tag in spans[0].tags if tag.vType == jaeger.TagType.STRING + tag.key: tag.vStr + for tag in spans[0].tags + if tag.vType == jaeger.TagType.STRING } self.assertEqual("hello", tags_by_keys["key_string"]) self.assertEqual("('tup", tags_by_keys["key_tuple"]) self.assertEqual("some_", tags_by_keys["key_resource"]) - + def test_dropped_values(self): links = [] for i in range(129): - links.append(trace._Span(name="span{}".format(i),context=trace_api.INVALID_SPAN_CONTEXT)) + links.append( + trace._Span( + name="span{}".format(i), + context=trace_api.INVALID_SPAN_CONTEXT, + ) + ) span = trace._Span( limits=trace.SpanLimits(), name="span", @@ -599,7 +608,7 @@ def test_dropped_values(self): span_id=0x00000000DEADBEF0, is_remote=False, ), - links=links + links=links, ) span.start() @@ -614,18 +623,14 @@ def test_dropped_values(self): # pylint: disable=protected-access spans = translate._translate(ThriftTranslator(max_tag_value_length=5)) tags_by_keys = { - tag.key: tag.vLong for tag in spans[0].tags if tag.vType == jaeger.TagType.LONG + tag.key: tag.vLong + for tag in spans[0].tags + if tag.vType == jaeger.TagType.LONG } - self.assertEqual( - 1, tags_by_keys["otel.dropped_links_count"] - ) - self.assertEqual( - 2, tags_by_keys["otel.dropped_attributes_count"] - ) - self.assertEqual( - 3, tags_by_keys["otel.dropped_events_count"] - ) + self.assertEqual(1, tags_by_keys["otel.dropped_links_count"]) + self.assertEqual(2, tags_by_keys["otel.dropped_attributes_count"]) + self.assertEqual(3, tags_by_keys["otel.dropped_events_count"]) def test_agent_client_split(self): agent_client = jaeger_exporter.AgentClientUDP( From 4ef469c00c96664cf77c6be051384fde8566d2d1 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 3 Jun 2021 16:56:15 -0700 Subject: [PATCH 04/22] adding support for dropped attributes/events/links to zipkin exporters --- .../tests/test_jaeger_exporter_protobuf.py | 28 +------------- .../tests/test_jaeger_exporter_thrift.py | 33 +---------------- .../exporter/zipkin/encoder/__init__.py | 14 +++++++ .../tests/encoder/test_v1_json.py | 22 +++++++++++ .../tests/encoder/test_v2_json.py | 11 ++++++ .../tests/encoder/test_v2_protobuf.py | 10 +++++ .../src/opentelemetry/test/spantestutil.py | 37 ++++++++++++++++++- 7 files changed, 97 insertions(+), 58 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py index 7419f09688..9a5f146096 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py @@ -38,6 +38,7 @@ from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SpanExportResult from opentelemetry.sdk.util.instrumentation import InstrumentationInfo +from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links from opentelemetry.trace.status import Status, StatusCode @@ -473,32 +474,7 @@ def test_export_span_service_name(self): self.assertEqual(exporter.service_name, "test") def test_dropped_values(self): - links = [] - for i in range(129): - links.append(trace._Span(name="span{}".format(i),context=trace_api.INVALID_SPAN_CONTEXT)) - span = trace._Span( - limits=trace.SpanLimits(), - name="span", - resource=Resource( - attributes={ - "key_resource": "some_resource some_resource some_more_resource" - } - ), - context=trace_api.SpanContext( - trace_id=0x000000000000000000000000DEADBEEF, - span_id=0x00000000DEADBEF0, - is_remote=False, - ), - links=links - ) - - span.start() - for i in range(130): - span.set_attribute("key{}".format(i), "value{}".format(i)) - for i in range(131): - span.add_event("event{}".format(i)) - - span.end() + span = get_span_with_dropped_attributes_events_links() translate = Translate([span]) # pylint: disable=protected-access diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py index 0cbc7c408f..2f4d20f29e 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py @@ -39,6 +39,7 @@ from opentelemetry.sdk.util.instrumentation import InstrumentationInfo from opentelemetry.trace import SpanKind from opentelemetry.trace.status import Status, StatusCode +from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links class TestJaegerExporter(unittest.TestCase): @@ -587,37 +588,7 @@ def test_max_tag_value_length(self): self.assertEqual("some_", tags_by_keys["key_resource"]) def test_dropped_values(self): - links = [] - for i in range(129): - links.append( - trace._Span( - name="span{}".format(i), - context=trace_api.INVALID_SPAN_CONTEXT, - ) - ) - span = trace._Span( - limits=trace.SpanLimits(), - name="span", - resource=Resource( - attributes={ - "key_resource": "some_resource some_resource some_more_resource" - } - ), - context=trace_api.SpanContext( - trace_id=0x000000000000000000000000DEADBEEF, - span_id=0x00000000DEADBEF0, - is_remote=False, - ), - links=links, - ) - - span.start() - for i in range(130): - span.set_attribute("key{}".format(i), "value{}".format(i)) - for i in range(131): - span.add_event("event{}".format(i)) - - span.end() + span = get_span_with_dropped_attributes_events_links() translate = Translate([span]) # pylint: disable=protected-access diff --git a/exporter/opentelemetry-exporter-zipkin-json/src/opentelemetry/exporter/zipkin/encoder/__init__.py b/exporter/opentelemetry-exporter-zipkin-json/src/opentelemetry/exporter/zipkin/encoder/__init__.py index 3390c19a46..07ad735ece 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/src/opentelemetry/exporter/zipkin/encoder/__init__.py +++ b/exporter/opentelemetry-exporter-zipkin-json/src/opentelemetry/exporter/zipkin/encoder/__init__.py @@ -207,6 +207,20 @@ def _extract_tags_from_span(self, span: Span) -> Dict[str, str]: tags.update({"otel.status_code": span.status.status_code.name}) if span.status.status_code is StatusCode.ERROR: tags.update({"error": span.status.description or ""}) + + if span.dropped_attributes: + tags.update( + {"otel.dropped_attributes_count": str(span.dropped_attributes)} + ) + + if span.dropped_events: + tags.update( + {"otel.dropped_events_count": str(span.dropped_events)} + ) + + if span.dropped_links: + tags.update({"otel.dropped_links_count": str(span.dropped_links)}) + return tags def _extract_annotations_from_events( diff --git a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py index c1956500bc..42bfc090a0 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py +++ b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py @@ -18,6 +18,9 @@ from opentelemetry.exporter.zipkin.json.v1 import JsonV1Encoder from opentelemetry.exporter.zipkin.node_endpoint import NodeEndpoint from opentelemetry.sdk import trace +from opentelemetry.test.spantestutil import ( + get_span_with_dropped_attributes_events_links, +) from opentelemetry.trace import TraceFlags, format_span_id, format_trace_id from .common_tests import TEST_SERVICE_NAME, CommonEncoderTestCases @@ -249,3 +252,22 @@ def _test_encode_max_tag_length(self, max_tag_value_length: int): [otel_span], NodeEndpoint() ), ) + + def test_dropped(self): + otel_span = get_span_with_dropped_attributes_events_links() + annotations = JsonV1Encoder()._encode_span(otel_span, "test")[ + "binaryAnnotations" + ] + asserts = 0 + for annotation in annotations: + if annotation.get("key") == "otel.dropped_links_count": + self.assertEqual("1", annotation.get("value")) + asserts += 1 + if annotation.get("key") == "otel.dropped_attributes_count": + self.assertEqual("2", annotation.get("value")) + asserts += 1 + if annotation.get("key") == "otel.dropped_events_count": + self.assertEqual("3", annotation.get("value")) + asserts += 1 + + self.assertEqual(3, asserts) diff --git a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py index eb0ad6000a..67d4b255bd 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py +++ b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py @@ -18,6 +18,9 @@ from opentelemetry.exporter.zipkin.json.v2 import JsonV2Encoder from opentelemetry.exporter.zipkin.node_endpoint import NodeEndpoint from opentelemetry.sdk import trace +from opentelemetry.test.spantestutil import ( + get_span_with_dropped_attributes_events_links, +) from opentelemetry.trace import SpanKind, TraceFlags from .common_tests import TEST_SERVICE_NAME, CommonEncoderTestCases @@ -203,3 +206,11 @@ def _test_encode_max_tag_length(self, max_tag_value_length: int): [otel_span], NodeEndpoint() ), ) + + def test_dropped(self): + otel_span = get_span_with_dropped_attributes_events_links() + tags = JsonV2Encoder()._encode_span(otel_span, "test")["tags"] + + self.assertEqual("1", tags.get("otel.dropped_links_count")) + self.assertEqual("2", tags.get("otel.dropped_attributes_count")) + self.assertEqual("3", tags.get("otel.dropped_events_count")) diff --git a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py index 8cf9f6abf5..cd70e2c4fd 100644 --- a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py +++ b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py @@ -18,6 +18,7 @@ from opentelemetry.exporter.zipkin.node_endpoint import NodeEndpoint from opentelemetry.exporter.zipkin.proto.http.v2 import ProtobufEncoder from opentelemetry.exporter.zipkin.proto.http.v2.gen import zipkin_pb2 +from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links from opentelemetry.trace import SpanKind from .common_tests import TEST_SERVICE_NAME, CommonEncoderTestCases @@ -232,3 +233,12 @@ def _test_encode_max_tag_length(self, max_tag_value_length: int): ) self.assertEqual(actual_output, expected_output) + + def test_dropped(self): + otel_span = get_span_with_dropped_attributes_events_links() + # pylint: disable=no-member + tags = ProtobufEncoder()._encode_span(otel_span, zipkin_pb2.Endpoint()).tags + + self.assertEqual('1', tags.get("otel.dropped_links_count")) + self.assertEqual('2', tags.get("otel.dropped_attributes_count")) + self.assertEqual('3', tags.get("otel.dropped_events_count")) \ No newline at end of file diff --git a/tests/util/src/opentelemetry/test/spantestutil.py b/tests/util/src/opentelemetry/test/spantestutil.py index 3e7de79158..69b4c43d90 100644 --- a/tests/util/src/opentelemetry/test/spantestutil.py +++ b/tests/util/src/opentelemetry/test/spantestutil.py @@ -16,7 +16,8 @@ from importlib import reload from opentelemetry import trace as trace_api -from opentelemetry.sdk.trace import TracerProvider, export +from opentelemetry.sdk import trace as trace_sdk +from opentelemetry.sdk.trace import Resource, TracerProvider, export from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( InMemorySpanExporter, ) @@ -41,3 +42,37 @@ def tearDownClass(cls): def setUp(self): self.memory_exporter = _MEMORY_EXPORTER self.memory_exporter.clear() + + +def get_span_with_dropped_attributes_events_links(): + links = [] + for i in range(129): + links.append( + trace_sdk._Span( + name="span{}".format(i), + context=trace_api.INVALID_SPAN_CONTEXT, + ) + ) + span = trace_sdk._Span( + limits=trace_sdk.SpanLimits(), + name="span", + resource=Resource( + attributes={ + "key_resource": "some_resource some_resource some_more_resource" + } + ), + context=trace_api.SpanContext( + trace_id=0x000000000000000000000000DEADBEEF, + span_id=0x00000000DEADBEF0, + is_remote=False, + ), + links=links, + ) + + span.start() + for i in range(130): + span.set_attribute("key{}".format(i), "value{}".format(i)) + for i in range(131): + span.add_event("event{}".format(i)) + span.end() + return span \ No newline at end of file From 734471e366181f69daf52531a2d7e9cdc085cd12 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 3 Jun 2021 17:10:01 -0700 Subject: [PATCH 05/22] add tests for sdk --- opentelemetry-sdk/tests/trace/test_trace.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 0781042a33..5f9b75856e 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -36,6 +36,7 @@ from opentelemetry.sdk.trace.id_generator import RandomIdGenerator from opentelemetry.sdk.util import ns_to_iso_str from opentelemetry.sdk.util.instrumentation import InstrumentationInfo +from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links from opentelemetry.trace import StatusCode from opentelemetry.util._time import _time_ns @@ -1444,3 +1445,10 @@ def test_span_no_limits_code(self): ) ) ) + + def test_dropped_attributes(self): + # nothing dropped + span = get_span_with_dropped_attributes_events_links() + self.assertEqual(1, span.dropped_links) + self.assertEqual(2, span.dropped_attributes) + self.assertEqual(3, span.dropped_events) \ No newline at end of file From dbe3e32f00af48cd4ed3d3f8f724f33a0512dd9e Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 4 Jun 2021 12:04:45 -0700 Subject: [PATCH 06/22] add tests for trace sdk --- opentelemetry-sdk/tests/trace/test_trace.py | 1 - tests/util/src/opentelemetry/test/spantestutil.py | 13 +++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 5f9b75856e..576f2a854c 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -1447,7 +1447,6 @@ def test_span_no_limits_code(self): ) def test_dropped_attributes(self): - # nothing dropped span = get_span_with_dropped_attributes_events_links() self.assertEqual(1, span.dropped_links) self.assertEqual(2, span.dropped_attributes) diff --git a/tests/util/src/opentelemetry/test/spantestutil.py b/tests/util/src/opentelemetry/test/spantestutil.py index 69b4c43d90..d8a58fe4fd 100644 --- a/tests/util/src/opentelemetry/test/spantestutil.py +++ b/tests/util/src/opentelemetry/test/spantestutil.py @@ -45,21 +45,23 @@ def setUp(self): def get_span_with_dropped_attributes_events_links(): + attributes = {} + for i in range(130): + attributes["key{}".format(i)] = ["value{}".format(i)] links = [] for i in range(129): links.append( trace_sdk._Span( name="span{}".format(i), context=trace_api.INVALID_SPAN_CONTEXT, + attributes=attributes, ) ) span = trace_sdk._Span( limits=trace_sdk.SpanLimits(), name="span", resource=Resource( - attributes={ - "key_resource": "some_resource some_resource some_more_resource" - } + attributes=attributes, ), context=trace_api.SpanContext( trace_id=0x000000000000000000000000DEADBEEF, @@ -67,12 +69,11 @@ def get_span_with_dropped_attributes_events_links(): is_remote=False, ), links=links, + attributes=attributes, ) span.start() - for i in range(130): - span.set_attribute("key{}".format(i), "value{}".format(i)) for i in range(131): - span.add_event("event{}".format(i)) + span.add_event("event{}".format(i), attributes=attributes) span.end() return span \ No newline at end of file From 69704f720d2eb64fc8bb2be84d0c79d3514963b0 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 4 Jun 2021 13:01:02 -0700 Subject: [PATCH 07/22] fix lint --- opentelemetry-sdk/tests/trace/test_trace.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 576f2a854c..f53ab7e9f5 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -36,7 +36,9 @@ from opentelemetry.sdk.trace.id_generator import RandomIdGenerator from opentelemetry.sdk.util import ns_to_iso_str from opentelemetry.sdk.util.instrumentation import InstrumentationInfo -from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links +from opentelemetry.test.spantestutil import ( + get_span_with_dropped_attributes_events_links, +) from opentelemetry.trace import StatusCode from opentelemetry.util._time import _time_ns @@ -1445,9 +1447,9 @@ def test_span_no_limits_code(self): ) ) ) - + def test_dropped_attributes(self): span = get_span_with_dropped_attributes_events_links() self.assertEqual(1, span.dropped_links) self.assertEqual(2, span.dropped_attributes) - self.assertEqual(3, span.dropped_events) \ No newline at end of file + self.assertEqual(3, span.dropped_events) From 8fe4266a78abdbae7e47a0761a057d37cf4274a8 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 4 Jun 2021 13:21:24 -0700 Subject: [PATCH 08/22] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2808ecf80..7277aee71f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.3.0-0.22b0...HEAD) +### Added +- Dropped attributes/events/links count available exposed on ReadableSpans. + ([#1893](https://github.com/open-telemetry/opentelemetry-python/pull/1893)) +- Added dropped count to jaeger and zipkin exporters. + ([#1893](https://github.com/open-telemetry/opentelemetry-python/pull/1893)) + ## [1.3.0-0.22b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.3.0-0.22b0) - 2021-06-01 ### Added From b7094ae7f910263603b93c20c4dd7cbc08a233ea Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 4 Jun 2021 13:42:37 -0700 Subject: [PATCH 09/22] adding dropped counts for otlp --- CHANGELOG.md | 2 +- .../otlp/proto/grpc/trace_exporter/__init__.py | 6 ++++++ .../tests/test_otlp_trace_exporter.py | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3616f53dd..7b280edd04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Dropped attributes/events/links count available exposed on ReadableSpans. ([#1893](https://github.com/open-telemetry/opentelemetry-python/pull/1893)) -- Added dropped count to jaeger and zipkin exporters. +- Added dropped count to otlp, jaeger and zipkin exporters. ([#1893](https://github.com/open-telemetry/opentelemetry-python/pull/1893)) ## [1.3.0-0.22b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.3.0-0.22b0) - 2021-06-01 diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py index e7f54c1ac3..d300cbe30b 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py @@ -272,6 +272,12 @@ def _translate_data( self._translate_events(sdk_span) self._translate_links(sdk_span) self._translate_status(sdk_span) + if sdk_span.dropped_attributes: + self._collector_span_kwargs["dropped_attributes_count"] = sdk_span.dropped_attributes + if sdk_span.dropped_events: + self._collector_span_kwargs["dropped_events_count"] = sdk_span.dropped_events + if sdk_span.dropped_links: + self._collector_span_kwargs["dropped_links_count"] = sdk_span.dropped_links self._collector_span_kwargs["kind"] = getattr( CollectorSpan.SpanKind, diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 521c9e6e82..170f8f66b5 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -68,6 +68,7 @@ SpanExportResult, ) from opentelemetry.sdk.util.instrumentation import InstrumentationInfo +from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links THIS_DIR = os.path.dirname(__file__) @@ -601,6 +602,20 @@ def test_translate_key_values(self): # self.assertEqual(kvlist_value.values[0].key, "asd") # self.assertEqual(kvlist_value.values[0].value.string_value, "123") + def test_dropped_values(self): + span = get_span_with_dropped_attributes_events_links() + # pylint:disable=protected-access + translated = self.exporter._translate_data([span]) + self.assertEqual(1, translated.resource_spans[0] + .instrumentation_library_spans[0] + .spans[0].dropped_links_count) + self.assertEqual(2, translated.resource_spans[0] + .instrumentation_library_spans[0] + .spans[0].dropped_attributes_count) + self.assertEqual(3, translated.resource_spans[0] + .instrumentation_library_spans[0] + .spans[0].dropped_events_count) + def _create_span_with_status(status: SDKStatus): span = _Span( From 967c1fdf0d4f98d0a2714d8f70b0a5b2159efcef Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 4 Jun 2021 13:51:02 -0700 Subject: [PATCH 10/22] fix lint --- .../proto/grpc/trace_exporter/__init__.py | 12 ++++++-- .../tests/test_otlp_trace_exporter.py | 28 ++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py index d300cbe30b..41e45ba8f9 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py @@ -273,11 +273,17 @@ def _translate_data( self._translate_links(sdk_span) self._translate_status(sdk_span) if sdk_span.dropped_attributes: - self._collector_span_kwargs["dropped_attributes_count"] = sdk_span.dropped_attributes + self._collector_span_kwargs[ + "dropped_attributes_count" + ] = sdk_span.dropped_attributes if sdk_span.dropped_events: - self._collector_span_kwargs["dropped_events_count"] = sdk_span.dropped_events + self._collector_span_kwargs[ + "dropped_events_count" + ] = sdk_span.dropped_events if sdk_span.dropped_links: - self._collector_span_kwargs["dropped_links_count"] = sdk_span.dropped_links + self._collector_span_kwargs[ + "dropped_links_count" + ] = sdk_span.dropped_links self._collector_span_kwargs["kind"] = getattr( CollectorSpan.SpanKind, diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 170f8f66b5..599796ca9f 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -68,7 +68,9 @@ SpanExportResult, ) from opentelemetry.sdk.util.instrumentation import InstrumentationInfo -from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links +from opentelemetry.test.spantestutil import ( + get_span_with_dropped_attributes_events_links, +) THIS_DIR = os.path.dirname(__file__) @@ -606,15 +608,27 @@ def test_dropped_values(self): span = get_span_with_dropped_attributes_events_links() # pylint:disable=protected-access translated = self.exporter._translate_data([span]) - self.assertEqual(1, translated.resource_spans[0] + self.assertEqual( + 1, + translated.resource_spans[0] .instrumentation_library_spans[0] - .spans[0].dropped_links_count) - self.assertEqual(2, translated.resource_spans[0] + .spans[0] + .dropped_links_count, + ) + self.assertEqual( + 2, + translated.resource_spans[0] .instrumentation_library_spans[0] - .spans[0].dropped_attributes_count) - self.assertEqual(3, translated.resource_spans[0] + .spans[0] + .dropped_attributes_count, + ) + self.assertEqual( + 3, + translated.resource_spans[0] .instrumentation_library_spans[0] - .spans[0].dropped_events_count) + .spans[0] + .dropped_events_count, + ) def _create_span_with_status(status: SDKStatus): From 809ee601773c0427aacef1a5ffa90ad8f78cb294 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 4 Jun 2021 14:16:41 -0700 Subject: [PATCH 11/22] fix lint --- .../jaeger/proto/grpc/translate/__init__.py | 22 ++++++++++++++----- .../tests/test_jaeger_exporter_protobuf.py | 22 +++++++------------ .../tests/test_jaeger_exporter_thrift.py | 4 +++- .../tests/encoder/test_v2_protobuf.py | 16 +++++++++----- .../src/opentelemetry/sdk/trace/__init__.py | 2 +- .../src/opentelemetry/test/spantestutil.py | 2 +- 6 files changed, 41 insertions(+), 27 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py index 0fb9bfc7ff..7caa4df007 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py @@ -371,16 +371,28 @@ def _extract_logs( logs.append(model_pb2.Log(timestamp=event_ts, fields=fields)) return logs - + def _dropped_tags( self, span: ReadableSpan ) -> Sequence[model_pb2.KeyValue]: tags = [] if span.dropped_attributes: - tags.append(_get_long_key_value("otel.dropped_attributes_count", span.dropped_attributes)) + tags.append( + _get_long_key_value( + "otel.dropped_attributes_count", span.dropped_attributes + ) + ) if span.dropped_events: - tags.append(_get_long_key_value("otel.dropped_events_count", span.dropped_events)) + tags.append( + _get_long_key_value( + "otel.dropped_events_count", span.dropped_events + ) + ) if span.dropped_links: - tags.append(_get_long_key_value("otel.dropped_links_count", span.dropped_links)) - + tags.append( + _get_long_key_value( + "otel.dropped_links_count", span.dropped_links + ) + ) + return tags diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py index be0e3ef508..e929148c73 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py @@ -39,7 +39,9 @@ from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SpanExportResult from opentelemetry.sdk.util.instrumentation import InstrumentationInfo -from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links +from opentelemetry.test.spantestutil import ( + get_span_with_dropped_attributes_events_links, +) from opentelemetry.trace.status import Status, StatusCode @@ -475,7 +477,7 @@ def test_export_span_service_name(self): exporter._grpc_client = client_mock exporter.export([span]) self.assertEqual(exporter.service_name, "test") - + def test_dropped_values(self): span = get_span_with_dropped_attributes_events_links() translate = Translate([span]) @@ -483,16 +485,8 @@ def test_dropped_values(self): # pylint: disable=protected-access spans = translate._translate(pb_translator.ProtobufTranslator("svc")) tags_by_keys = { - tag.key: tag.v_str or tag.v_int64 - for tag in spans[0].tags + tag.key: tag.v_str or tag.v_int64 for tag in spans[0].tags } - self.assertEqual( - 1, tags_by_keys["otel.dropped_links_count"] - ) - self.assertEqual( - 2, tags_by_keys["otel.dropped_attributes_count"] - ) - self.assertEqual( - 3, tags_by_keys["otel.dropped_events_count"] - ) - + self.assertEqual(1, tags_by_keys["otel.dropped_links_count"]) + self.assertEqual(2, tags_by_keys["otel.dropped_attributes_count"]) + self.assertEqual(3, tags_by_keys["otel.dropped_events_count"]) diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py index 254470722d..7915797842 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py @@ -40,7 +40,9 @@ from opentelemetry.sdk.util.instrumentation import InstrumentationInfo from opentelemetry.trace import SpanKind from opentelemetry.trace.status import Status, StatusCode -from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links +from opentelemetry.test.spantestutil import ( + get_span_with_dropped_attributes_events_links, +) class TestJaegerExporter(unittest.TestCase): diff --git a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py index cd70e2c4fd..d35c1112ea 100644 --- a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py +++ b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py @@ -18,7 +18,9 @@ from opentelemetry.exporter.zipkin.node_endpoint import NodeEndpoint from opentelemetry.exporter.zipkin.proto.http.v2 import ProtobufEncoder from opentelemetry.exporter.zipkin.proto.http.v2.gen import zipkin_pb2 -from opentelemetry.test.spantestutil import get_span_with_dropped_attributes_events_links +from opentelemetry.test.spantestutil import ( + get_span_with_dropped_attributes_events_links, +) from opentelemetry.trace import SpanKind from .common_tests import TEST_SERVICE_NAME, CommonEncoderTestCases @@ -237,8 +239,12 @@ def _test_encode_max_tag_length(self, max_tag_value_length: int): def test_dropped(self): otel_span = get_span_with_dropped_attributes_events_links() # pylint: disable=no-member - tags = ProtobufEncoder()._encode_span(otel_span, zipkin_pb2.Endpoint()).tags + tags = ( + ProtobufEncoder() + ._encode_span(otel_span, zipkin_pb2.Endpoint()) + .tags + ) - self.assertEqual('1', tags.get("otel.dropped_links_count")) - self.assertEqual('2', tags.get("otel.dropped_attributes_count")) - self.assertEqual('3', tags.get("otel.dropped_events_count")) \ No newline at end of file + self.assertEqual("1", tags.get("otel.dropped_links_count")) + self.assertEqual("2", tags.get("otel.dropped_attributes_count")) + self.assertEqual("3", tags.get("otel.dropped_events_count")) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 7499e194ba..d295b09096 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -317,7 +317,7 @@ def __init__( @property def attributes(self) -> types.Attributes: return self._attributes - + @property def dropped_attributes(self) -> int: if self._attributes: diff --git a/tests/util/src/opentelemetry/test/spantestutil.py b/tests/util/src/opentelemetry/test/spantestutil.py index d8a58fe4fd..bf5578c4ff 100644 --- a/tests/util/src/opentelemetry/test/spantestutil.py +++ b/tests/util/src/opentelemetry/test/spantestutil.py @@ -76,4 +76,4 @@ def get_span_with_dropped_attributes_events_links(): for i in range(131): span.add_event("event{}".format(i), attributes=attributes) span.end() - return span \ No newline at end of file + return span From a782291e208ba30bc3ad2a6deb3eeba06ef3aa46 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Mon, 7 Jun 2021 11:51:11 -0700 Subject: [PATCH 12/22] remove single use method --- .../jaeger/proto/grpc/translate/__init__.py | 46 ++++++++----------- .../jaeger/thrift/translate/__init__.py | 37 ++++++--------- 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py index 7caa4df007..56cb7eb23d 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py @@ -240,9 +240,6 @@ def _translate_span(self, span: ReadableSpan) -> model_pb2.Span: tags = self._extract_tags(span) refs = self._extract_refs(span) logs = self._extract_logs(span) - dropped_tags = self._dropped_tags(span) - if dropped_tags: - tags.extend(dropped_tags) flags = int(ctx.trace_flags) @@ -316,6 +313,24 @@ def _extract_tags( if not span.status.is_ok: translated.append(_get_bool_key_value("error", True)) + if span.dropped_attributes: + translated.append( + _get_long_key_value( + "otel.dropped_attributes_count", span.dropped_attributes + ) + ) + if span.dropped_events: + translated.append( + _get_long_key_value( + "otel.dropped_events_count", span.dropped_events + ) + ) + if span.dropped_links: + translated.append( + _get_long_key_value( + "otel.dropped_links_count", span.dropped_links + ) + ) return translated def _extract_refs( @@ -371,28 +386,3 @@ def _extract_logs( logs.append(model_pb2.Log(timestamp=event_ts, fields=fields)) return logs - - def _dropped_tags( - self, span: ReadableSpan - ) -> Sequence[model_pb2.KeyValue]: - tags = [] - if span.dropped_attributes: - tags.append( - _get_long_key_value( - "otel.dropped_attributes_count", span.dropped_attributes - ) - ) - if span.dropped_events: - tags.append( - _get_long_key_value( - "otel.dropped_events_count", span.dropped_events - ) - ) - if span.dropped_links: - tags.append( - _get_long_key_value( - "otel.dropped_links_count", span.dropped_links - ) - ) - - return tags diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py index ad99936505..efc5e010fd 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py @@ -162,9 +162,6 @@ def _translate_span(self, span: ReadableSpan) -> TCollector.Span: tags = self._extract_tags(span) refs = self._extract_refs(span) logs = self._extract_logs(span) - dropped_tags = self._dropped_tags(span) - if dropped_tags: - tags.extend(dropped_tags) flags = int(ctx.trace_flags) @@ -228,6 +225,21 @@ def _extract_tags(self, span: ReadableSpan) -> Sequence[TCollector.Tag]: # Make sure to add "error" tag if span status is not OK if not span.status.is_ok: translated.append(_get_bool_tag("error", True)) + + if span.dropped_attributes: + translated.append( + _get_long_tag( + "otel.dropped_attributes_count", span.dropped_attributes + ) + ) + if span.dropped_events: + translated.append( + _get_long_tag("otel.dropped_events_count", span.dropped_events) + ) + if span.dropped_links: + translated.append( + _get_long_tag("otel.dropped_links_count", span.dropped_links) + ) return translated @@ -288,22 +300,3 @@ def _extract_logs( ) return logs - - def _dropped_tags(self, span: ReadableSpan) -> Sequence[TCollector.Tag]: - tags = [] - if span.dropped_attributes: - tags.append( - _get_long_tag( - "otel.dropped_attributes_count", span.dropped_attributes - ) - ) - if span.dropped_events: - tags.append( - _get_long_tag("otel.dropped_events_count", span.dropped_events) - ) - if span.dropped_links: - tags.append( - _get_long_tag("otel.dropped_links_count", span.dropped_links) - ) - - return tags From ec3a28ef84391456c3f66a509a9a38eaf60e25ec Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Mon, 7 Jun 2021 11:56:30 -0700 Subject: [PATCH 13/22] cleanup test --- .../jaeger/thrift/translate/__init__.py | 2 +- .../tests/encoder/test_v1_json.py | 20 +++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py index efc5e010fd..70654b979d 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py @@ -225,7 +225,7 @@ def _extract_tags(self, span: ReadableSpan) -> Sequence[TCollector.Tag]: # Make sure to add "error" tag if span status is not OK if not span.status.is_ok: translated.append(_get_bool_tag("error", True)) - + if span.dropped_attributes: translated.append( _get_long_tag( diff --git a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py index 42bfc090a0..a017c56f2d 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py +++ b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py @@ -258,16 +258,10 @@ def test_dropped(self): annotations = JsonV1Encoder()._encode_span(otel_span, "test")[ "binaryAnnotations" ] - asserts = 0 - for annotation in annotations: - if annotation.get("key") == "otel.dropped_links_count": - self.assertEqual("1", annotation.get("value")) - asserts += 1 - if annotation.get("key") == "otel.dropped_attributes_count": - self.assertEqual("2", annotation.get("value")) - asserts += 1 - if annotation.get("key") == "otel.dropped_events_count": - self.assertEqual("3", annotation.get("value")) - asserts += 1 - - self.assertEqual(3, asserts) + annotations = { + annotation["key"]: annotation["value"] + for annotation in annotations + } + self.assertEqual("1", annotations["otel.dropped_links_count"]) + self.assertEqual("2", annotations["otel.dropped_attributes_count"]) + self.assertEqual("3", annotations["otel.dropped_events_count"]) From b8da9990e3e5d205d96bd9cdd333ca9db00f20c3 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Mon, 7 Jun 2021 12:02:18 -0700 Subject: [PATCH 14/22] update tests --- .../tests/encoder/test_v2_json.py | 6 +++--- .../tests/encoder/test_v2_protobuf.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py index 67d4b255bd..8911c48bed 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py +++ b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py @@ -211,6 +211,6 @@ def test_dropped(self): otel_span = get_span_with_dropped_attributes_events_links() tags = JsonV2Encoder()._encode_span(otel_span, "test")["tags"] - self.assertEqual("1", tags.get("otel.dropped_links_count")) - self.assertEqual("2", tags.get("otel.dropped_attributes_count")) - self.assertEqual("3", tags.get("otel.dropped_events_count")) + self.assertEqual("1", tags["otel.dropped_links_count"]) + self.assertEqual("2", tags["otel.dropped_attributes_count"]) + self.assertEqual("3", tags["otel.dropped_events_count"]) diff --git a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py index d35c1112ea..6e9600d52d 100644 --- a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py +++ b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py @@ -245,6 +245,6 @@ def test_dropped(self): .tags ) - self.assertEqual("1", tags.get("otel.dropped_links_count")) - self.assertEqual("2", tags.get("otel.dropped_attributes_count")) - self.assertEqual("3", tags.get("otel.dropped_events_count")) + self.assertEqual("1", tags["otel.dropped_links_count"]) + self.assertEqual("2", tags["otel.dropped_attributes_count"]) + self.assertEqual("3", tags["otel.dropped_events_count"]) From 9785866d9bd274b718ce216d876f342746b79bca Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Mon, 7 Jun 2021 12:56:57 -0700 Subject: [PATCH 15/22] fix lint --- .../tests/test_jaeger_exporter_thrift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py index 7915797842..8594e6e1d9 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py @@ -38,11 +38,11 @@ from opentelemetry.sdk.resources import SERVICE_NAME from opentelemetry.sdk.trace import Resource, TracerProvider from opentelemetry.sdk.util.instrumentation import InstrumentationInfo -from opentelemetry.trace import SpanKind -from opentelemetry.trace.status import Status, StatusCode from opentelemetry.test.spantestutil import ( get_span_with_dropped_attributes_events_links, ) +from opentelemetry.trace import SpanKind +from opentelemetry.trace.status import Status, StatusCode class TestJaegerExporter(unittest.TestCase): From 3e1ed3e4d513e17aa150498a8adb27f1f3e774bc Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Wed, 9 Jun 2021 09:06:51 -0700 Subject: [PATCH 16/22] adding Attributed class --- .../src/opentelemetry/attributes/__init__.py | 107 +++++++++++++++++- .../src/opentelemetry/trace/__init__.py | 16 +-- .../opentelemetry/sdk/resources/__init__.py | 13 +-- .../src/opentelemetry/sdk/trace/__init__.py | 61 +++------- opentelemetry-sdk/tests/trace/test_trace.py | 5 +- .../src/opentelemetry/test/spantestutil.py | 19 ++-- 6 files changed, 143 insertions(+), 78 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index 6875f56631..09e9cd066c 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -14,8 +14,11 @@ # type: ignore import logging +import threading +from collections import OrderedDict +from collections.abc import MutableMapping from types import MappingProxyType -from typing import MutableSequence, Sequence +from typing import MutableSequence, Optional, Sequence from opentelemetry.util import types @@ -107,4 +110,106 @@ def _filter_attributes(attributes: types.Attributes) -> None: def _create_immutable_attributes( attributes: types.Attributes, ) -> types.Attributes: + _filter_attributes(attributes) return MappingProxyType(attributes.copy() if attributes else {}) + + +class _BoundedDict(MutableMapping): + """An ordered dict with a fixed max capacity. + + Oldest elements are dropped when the dict is full and a new element is + added. + """ + + def __init__( + self, maxlen: Optional[int], immutable: Optional[bool] = False + ): + if maxlen is not None: + if not isinstance(maxlen, int): + raise ValueError + if maxlen < 0: + raise ValueError + self.maxlen = maxlen + self._immutable = immutable + self.dropped = 0 + self._dict = OrderedDict() # type: OrderedDict + self._lock = threading.Lock() # type: threading.Lock + + def __repr__(self): + return "{}({}, maxlen={})".format( + type(self).__name__, dict(self._dict), self.maxlen + ) + + def __getitem__(self, key): + return self._dict[key] + + def __setitem__(self, key, value): + if self._immutable: + raise TypeError() + with self._lock: + if self.maxlen is not None and self.maxlen == 0: + self.dropped += 1 + return + + if key in self._dict: + del self._dict[key] + elif self.maxlen is not None and len(self._dict) == self.maxlen: + del self._dict[next(iter(self._dict.keys()))] + self.dropped += 1 + self._dict[key] = value + + def __delitem__(self, key): + if self._immutable: + raise TypeError() + del self._dict[key] + + def __iter__(self): + with self._lock: + return iter(self._dict.copy()) + + def __len__(self): + return len(self._dict) + + def copy(self): + return self._dict.copy() + + @classmethod + def from_map(cls, maxlen, immutable, mapping): + mapping = OrderedDict(mapping) + bounded_dict = cls(maxlen) + for key, value in mapping.items(): + bounded_dict[key] = value + bounded_dict._immutable = immutable # pylint: disable=protected-access + return bounded_dict + + +class Attributed: + """The Attributed class is extended by all components + that provide attributes as part of their data models. + """ + + def __init__( + self, + attributes: types.Attributes = None, + filtered: bool = False, + limit: int = 128, # TODO: this should not be hardcoded here + immutable: bool = False, + ) -> None: + if filtered: + _filter_attributes(attributes) + if attributes is None: + self._attributes = _BoundedDict(limit, immutable) + else: + self._attributes = _BoundedDict.from_map( + limit, immutable, attributes + ) + + @property + def attributes(self) -> types.Attributes: + return self._attributes + + @property + def dropped_attributes(self) -> int: + if self._attributes: + return self._attributes.dropped + return 0 diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index cae50a5b47..e22e85557a 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -82,6 +82,7 @@ from typing import Iterator, Optional, Sequence, cast from opentelemetry import context as context_api +from opentelemetry.attributes import Attributed from opentelemetry.context.context import Context from opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER from opentelemetry.trace.propagation import ( @@ -119,13 +120,8 @@ def __init__(self, context: "SpanContext") -> None: def context(self) -> "SpanContext": return self._context - @property - @abstractmethod - def attributes(self) -> types.Attributes: - pass - -class Link(_LinkBase): +class Link(_LinkBase, Attributed): """A link to a `Span`. Args: @@ -138,12 +134,8 @@ def __init__( context: "SpanContext", attributes: types.Attributes = None, ) -> None: - super().__init__(context) - self._attributes = attributes - - @property - def attributes(self) -> types.Attributes: - return self._attributes + _LinkBase.__init__(self, context) + Attributed.__init__(self, attributes) _Links = Optional[Sequence[Link]] diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index ae96b5e3f3..aef8673fa9 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -64,7 +64,7 @@ import pkg_resources -from opentelemetry.attributes import _filter_attributes +from opentelemetry.attributes import Attributed from opentelemetry.sdk.environment_variables import ( OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME, @@ -138,14 +138,13 @@ ).version -class Resource: +class Resource(Attributed): """A Resource is an immutable representation of the entity producing telemetry as Attributes.""" def __init__( self, attributes: Attributes, schema_url: typing.Optional[str] = None ): - _filter_attributes(attributes) - self._attributes = attributes.copy() + super().__init__(attributes, filtered=True) if schema_url is None: schema_url = "" self._schema_url = schema_url @@ -193,12 +192,6 @@ def attributes(self) -> Attributes: def schema_url(self) -> str: return self._schema_url - @property - def dropped_attributes(self) -> int: - if self._attributes: - return self._attributes.dropped - return 0 - def merge(self, other: "Resource") -> "Resource": """Merges this resource and an updating resource into a new `Resource`. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index d295b09096..d0d1d24ffc 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -40,8 +40,8 @@ from opentelemetry import context as context_api from opentelemetry import trace as trace_api from opentelemetry.attributes import ( - _create_immutable_attributes, - _filter_attributes, + Attributed, + _BoundedDict, _is_valid_attribute_value, ) from opentelemetry.sdk import util @@ -289,13 +289,8 @@ def name(self) -> str: def timestamp(self) -> int: return self._timestamp - @property - @abc.abstractmethod - def attributes(self) -> types.Attributes: - pass - -class Event(EventBase): +class Event(EventBase, Attributed): """A text annotation with a set of attributes. Args: @@ -310,19 +305,12 @@ def __init__( name: str, attributes: types.Attributes = None, timestamp: Optional[int] = None, + limit: Optional[int] = _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, ) -> None: - super().__init__(name, timestamp) - self._attributes = attributes - - @property - def attributes(self) -> types.Attributes: - return self._attributes - - @property - def dropped_attributes(self) -> int: - if self._attributes: - return self._attributes.dropped - return 0 + EventBase.__init__(self, name, timestamp) + Attributed.__init__( + self, attributes, limit=limit, immutable=True, filtered=True + ) def _check_span_ended(func): @@ -340,7 +328,7 @@ def wrapper(self, *args, **kwargs): return wrapper -class ReadableSpan: +class ReadableSpan(Attributed): """Provides read-only access to span attributes""" def __init__( @@ -358,6 +346,7 @@ def __init__( start_time: Optional[int] = None, end_time: Optional[int] = None, ) -> None: + super().__init__(attributes) self._name = name self._context = context self._kind = kind @@ -365,18 +354,11 @@ def __init__( self._parent = parent self._start_time = start_time self._end_time = end_time - self._attributes = attributes self._events = events self._links = links self._resource = resource self._status = status - @property - def dropped_attributes(self) -> int: - if self._attributes: - return self._attributes.dropped - return 0 - @property def dropped_events(self) -> int: if self._events: @@ -498,7 +480,7 @@ def _format_context(context): @staticmethod def _format_attributes(attributes): - if isinstance(attributes, BoundedDict): + if isinstance(attributes, _BoundedDict): return attributes._dict # pylint: disable=protected-access if isinstance(attributes, MappingProxyType): return attributes.copy() @@ -685,22 +667,13 @@ def __init__( self._limits = limits self._lock = threading.Lock() - _filter_attributes(attributes) - if not attributes: - self._attributes = self._new_attributes() - else: - self._attributes = BoundedDict.from_map( - self._limits.max_attributes, attributes - ) + Attributed.__init__( + self, attributes, limit=self._limits.max_attributes, filtered=True + ) self._events = self._new_events() if events: for event in events: - _filter_attributes(event.attributes) - # pylint: disable=protected-access - event._attributes = _create_immutable_attributes( - event.attributes - ) self._events.append(event) if links is None: @@ -713,9 +686,6 @@ def __repr__(self): type(self).__name__, self._name, self._context ) - def _new_attributes(self): - return BoundedDict(self._limits.max_attributes) - def _new_events(self): return BoundedList(self._limits.max_events) @@ -768,13 +738,12 @@ def add_event( attributes: types.Attributes = None, timestamp: Optional[int] = None, ) -> None: - _filter_attributes(attributes) - attributes = _create_immutable_attributes(attributes) self._add_event( Event( name=name, attributes=attributes, timestamp=_time_ns() if timestamp is None else timestamp, + limit=self._limits.max_attributes, ) ) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index f53ab7e9f5..440ef99cbd 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -808,7 +808,7 @@ def test_links(self): self.assertEqual( root.links[0].context.span_id, other_context1.span_id ) - self.assertEqual(root.links[0].attributes, None) + self.assertEqual(0, len(root.links[0].attributes)) self.assertEqual( root.links[1].context.trace_id, other_context2.trace_id ) @@ -1453,3 +1453,6 @@ def test_dropped_attributes(self): self.assertEqual(1, span.dropped_links) self.assertEqual(2, span.dropped_attributes) self.assertEqual(3, span.dropped_events) + self.assertEqual(2, span.events[0].dropped_attributes) + self.assertEqual(2, span.links[0].dropped_attributes) + self.assertEqual(2, span.resource.dropped_attributes) diff --git a/tests/util/src/opentelemetry/test/spantestutil.py b/tests/util/src/opentelemetry/test/spantestutil.py index bf5578c4ff..faf135f2ae 100644 --- a/tests/util/src/opentelemetry/test/spantestutil.py +++ b/tests/util/src/opentelemetry/test/spantestutil.py @@ -46,14 +46,17 @@ def setUp(self): def get_span_with_dropped_attributes_events_links(): attributes = {} - for i in range(130): - attributes["key{}".format(i)] = ["value{}".format(i)] + for index in range(130): + attributes["key{}".format(index)] = ["value{}".format(index)] links = [] - for i in range(129): + for index in range(129): links.append( - trace_sdk._Span( - name="span{}".format(i), - context=trace_api.INVALID_SPAN_CONTEXT, + trace_api.Link( + trace_sdk._Span( + name="span{}".format(index), + context=trace_api.INVALID_SPAN_CONTEXT, + attributes=attributes, + ).get_span_context(), attributes=attributes, ) ) @@ -73,7 +76,7 @@ def get_span_with_dropped_attributes_events_links(): ) span.start() - for i in range(131): - span.add_event("event{}".format(i), attributes=attributes) + for index in range(131): + span.add_event("event{}".format(index), attributes=attributes) span.end() return span From 7ae76bd7aa70bc9f611e8916c9dd4cc1fa811057 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 10 Jun 2021 09:32:07 -0700 Subject: [PATCH 17/22] remove unused import --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index d0d1d24ffc..9208787ae5 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -53,7 +53,7 @@ from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import sampling from opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator -from opentelemetry.sdk.util import BoundedDict, BoundedList +from opentelemetry.sdk.util import BoundedList from opentelemetry.sdk.util.instrumentation import InstrumentationInfo from opentelemetry.trace import SpanContext from opentelemetry.trace.status import Status, StatusCode From 22fb2f61293a55aa4d9c597105b3e7eeaf0014d0 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 25 Jun 2021 10:05:59 -0700 Subject: [PATCH 18/22] update code w/ latest changes in main --- .../src/opentelemetry/trace/__init__.py | 5 ++++ .../opentelemetry/sdk/resources/__init__.py | 2 +- .../src/opentelemetry/sdk/trace/__init__.py | 24 ++++++++++++++----- opentelemetry-sdk/tests/trace/test_trace.py | 6 ++--- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index ca97accb13..487592f60d 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -120,6 +120,11 @@ def __init__(self, context: "SpanContext") -> None: def context(self) -> "SpanContext": return self._context + @property + @abstractmethod + def attributes(self) -> types.Attributes: + pass + class Link(_LinkBase): """A link to a `Span`. The attributes of a Link are immutable. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index 9719202dc4..3ad01b0aec 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -138,7 +138,7 @@ ).version -class Resource(Attributed): +class Resource: """A Resource is an immutable representation of the entity producing telemetry as Attributes.""" def __init__( diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index b6bfa420a9..19531a75a5 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -290,6 +290,10 @@ def name(self) -> str: def timestamp(self) -> int: return self._timestamp + @property + @abc.abstractmethod + def attributes(self) -> types.Attributes: + pass class Event(EventBase): @@ -310,10 +314,12 @@ def __init__( timestamp: Optional[int] = None, limit: Optional[int] = _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, ) -> None: - EventBase.__init__(self, name, timestamp) - Attributed.__init__( - self, attributes, limit=limit, immutable=True, filtered=True - ) + super().__init__(name, timestamp) + self._attributes = attributes + + @property + def attributes(self) -> types.Attributes: + return self._attributes def _check_span_ended(func): @@ -331,7 +337,7 @@ def wrapper(self, *args, **kwargs): return wrapper -class ReadableSpan(Attributed): +class ReadableSpan: """Provides read-only access to span attributes""" def __init__( @@ -349,7 +355,6 @@ def __init__( start_time: Optional[int] = None, end_time: Optional[int] = None, ) -> None: - super().__init__(attributes) self._name = name self._context = context self._kind = kind @@ -357,11 +362,18 @@ def __init__( self._parent = parent self._start_time = start_time self._end_time = end_time + self._attributes = attributes self._events = events self._links = links self._resource = resource self._status = status + @property + def dropped_attributes(self) -> int: + if self._attributes: + return self._attributes.dropped + return 0 + @property def dropped_events(self) -> int: if self._events: diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 0f6f330fe2..e331642e44 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -1490,6 +1490,6 @@ def test_dropped_attributes(self): self.assertEqual(1, span.dropped_links) self.assertEqual(2, span.dropped_attributes) self.assertEqual(3, span.dropped_events) - self.assertEqual(2, span.events[0].dropped_attributes) - self.assertEqual(2, span.links[0].dropped_attributes) - self.assertEqual(2, span.resource.dropped_attributes) + self.assertEqual(2, span.events[0].attributes.dropped) + self.assertEqual(2, span.links[0].attributes.dropped) + self.assertEqual(2, span.resource.attributes.dropped) From 4d3666af53973b2a3ad9471da9011e86d2e9bd92 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Mon, 28 Jun 2021 15:49:29 -0700 Subject: [PATCH 19/22] add link/event attribute drop counters for otlp --- .../proto/grpc/trace_exporter/__init__.py | 2 ++ .../tests/test_otlp_trace_exporter.py | 23 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py index 41e45ba8f9..cbaec907e5 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py @@ -175,6 +175,7 @@ def _translate_events(self, sdk_span: ReadableSpan) -> None: collector_span_event = CollectorSpan.Event( name=sdk_span_event.name, time_unix_nano=sdk_span_event.timestamp, + dropped_attributes_count=sdk_span_event.attributes.dropped, ) for key, value in sdk_span_event.attributes.items(): @@ -201,6 +202,7 @@ def _translate_links(self, sdk_span: ReadableSpan) -> None: sdk_span_link.context.trace_id.to_bytes(16, "big") ), span_id=(sdk_span_link.context.span_id.to_bytes(8, "big")), + dropped_attributes_count=sdk_span_link.attributes.dropped, ) for key, value in sdk_span_link.attributes.items(): diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 599796ca9f..3385fbc89b 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -22,6 +22,7 @@ from google.rpc.error_details_pb2 import RetryInfo from grpc import ChannelCredentials, Compression, StatusCode, server +from opentelemetry.attributes import BoundedAttributes from opentelemetry.exporter.otlp.proto.grpc.exporter import ( _translate_key_values, ) @@ -137,7 +138,7 @@ def setUp(self): event_mock = Mock( **{ "timestamp": 1591240820506462784, - "attributes": OrderedDict([("a", 1), ("b", False)]), + "attributes": BoundedAttributes(attributes={"a": 1, "b": False}), } ) @@ -154,14 +155,14 @@ def setUp(self): ), resource=SDKResource(OrderedDict([("a", 1), ("b", False)])), parent=Mock(**{"span_id": 12345}), - attributes=OrderedDict([("a", 1), ("b", True)]), + attributes=BoundedAttributes(attributes={"a": 1, "b": True}), events=[event_mock], links=[ Mock( **{ "context.trace_id": 1, "context.span_id": 2, - "attributes": OrderedDict([("a", 1), ("b", False)]), + "attributes": BoundedAttributes(attributes={"a":1, "b":False}), "kind": OTLPSpan.SpanKind.SPAN_KIND_INTERNAL, # pylint: disable=no-member } ) @@ -629,6 +630,22 @@ def test_dropped_values(self): .spans[0] .dropped_events_count, ) + self.assertEqual( + 2, + translated.resource_spans[0] + .instrumentation_library_spans[0] + .spans[0] + .links[0] + .dropped_attributes_count, + ) + self.assertEqual( + 2, + translated.resource_spans[0] + .instrumentation_library_spans[0] + .spans[0] + .events[0] + .dropped_attributes_count, + ) def _create_span_with_status(status: SDKStatus): From 5013d0975dad8c2a81722adfb0ec2b032052ee0c Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Tue, 29 Jun 2021 10:02:53 -0700 Subject: [PATCH 20/22] adding dropped attributes for events to jaeger --- .../jaeger/proto/grpc/translate/__init__.py | 9 ++++++ .../tests/test_jaeger_exporter_protobuf.py | 28 +++++++++++++++---- .../jaeger/thrift/translate/__init__.py | 9 ++++++ .../tests/test_jaeger_exporter_thrift.py | 28 +++++++++++++++---- .../tests/test_otlp_trace_exporter.py | 8 ++++-- 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py index 56cb7eb23d..65eef76d0f 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/src/opentelemetry/exporter/jaeger/proto/grpc/translate/__init__.py @@ -376,6 +376,15 @@ def _extract_logs( if tag: fields.append(tag) + if event.attributes.dropped: + fields.append( + _translate_attribute( + "otel.dropped_attributes_count", + event.attributes.dropped, + self._max_tag_value_length, + ) + ) + fields.append( _get_string_key_value( key="message", diff --git a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py index e929148c73..1123f9b28f 100644 --- a/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py +++ b/exporter/opentelemetry-exporter-jaeger-proto-grpc/tests/test_jaeger_exporter_protobuf.py @@ -45,6 +45,14 @@ from opentelemetry.trace.status import Status, StatusCode +def _translate_spans_with_dropped_attributes(): + span = get_span_with_dropped_attributes_events_links() + translate = Translate([span]) + + # pylint: disable=protected-access + return translate._translate(pb_translator.ProtobufTranslator("svc")) + + # pylint:disable=no-member class TestJaegerExporter(unittest.TestCase): def setUp(self): @@ -478,15 +486,23 @@ def test_export_span_service_name(self): exporter.export([span]) self.assertEqual(exporter.service_name, "test") - def test_dropped_values(self): - span = get_span_with_dropped_attributes_events_links() - translate = Translate([span]) - - # pylint: disable=protected-access - spans = translate._translate(pb_translator.ProtobufTranslator("svc")) + def test_dropped_span_attributes(self): + spans = _translate_spans_with_dropped_attributes() tags_by_keys = { tag.key: tag.v_str or tag.v_int64 for tag in spans[0].tags } self.assertEqual(1, tags_by_keys["otel.dropped_links_count"]) self.assertEqual(2, tags_by_keys["otel.dropped_attributes_count"]) self.assertEqual(3, tags_by_keys["otel.dropped_events_count"]) + + def test_dropped_event_attributes(self): + spans = _translate_spans_with_dropped_attributes() + fields_by_keys = { + tag.key: tag.v_str or tag.v_int64 + for tag in spans[0].logs[0].fields + } + # get events + self.assertEqual( + 2, + fields_by_keys["otel.dropped_attributes_count"], + ) diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py index 70654b979d..7a4d047191 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py @@ -284,6 +284,15 @@ def _extract_logs( if tag: fields.append(tag) + if event.attributes.dropped: + fields.append( + _translate_attribute( + "otel.dropped_attributes_count", + event.attributes.dropped, + self._max_tag_value_length, + ) + ) + fields.append( TCollector.Tag( key="message", diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py index 8594e6e1d9..0da65d0477 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py @@ -45,6 +45,14 @@ from opentelemetry.trace.status import Status, StatusCode +def _translate_spans_with_dropped_attributes(): + span = get_span_with_dropped_attributes_events_links() + translate = Translate([span]) + + # pylint: disable=protected-access + return translate._translate(ThriftTranslator(max_tag_value_length=5)) + + class TestJaegerExporter(unittest.TestCase): def setUp(self): # create and save span to be used in tests @@ -592,12 +600,8 @@ def test_max_tag_value_length(self): self.assertEqual("('tup", tags_by_keys["key_tuple"]) self.assertEqual("some_", tags_by_keys["key_resource"]) - def test_dropped_values(self): - span = get_span_with_dropped_attributes_events_links() - translate = Translate([span]) - - # pylint: disable=protected-access - spans = translate._translate(ThriftTranslator(max_tag_value_length=5)) + def test_dropped_span_attributes(self): + spans = _translate_spans_with_dropped_attributes() tags_by_keys = { tag.key: tag.vLong for tag in spans[0].tags @@ -608,6 +612,18 @@ def test_dropped_values(self): self.assertEqual(2, tags_by_keys["otel.dropped_attributes_count"]) self.assertEqual(3, tags_by_keys["otel.dropped_events_count"]) + def test_dropped_event_attributes(self): + spans = _translate_spans_with_dropped_attributes() + tags_by_keys = { + tag.key: tag.vLong + for tag in spans[0].logs[0].fields + if tag.vType == jaeger.TagType.LONG + } + self.assertEqual( + 2, + tags_by_keys["otel.dropped_attributes_count"], + ) + def test_agent_client_split(self): agent_client = jaeger_exporter.AgentClientUDP( host_name="localhost", diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 3385fbc89b..09dbda1682 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -138,7 +138,9 @@ def setUp(self): event_mock = Mock( **{ "timestamp": 1591240820506462784, - "attributes": BoundedAttributes(attributes={"a": 1, "b": False}), + "attributes": BoundedAttributes( + attributes={"a": 1, "b": False} + ), } ) @@ -162,7 +164,9 @@ def setUp(self): **{ "context.trace_id": 1, "context.span_id": 2, - "attributes": BoundedAttributes(attributes={"a":1, "b":False}), + "attributes": BoundedAttributes( + attributes={"a": 1, "b": False} + ), "kind": OTLPSpan.SpanKind.SPAN_KIND_INTERNAL, # pylint: disable=no-member } ) From d8259bb7292635694f94dc6d77b8341ad4ce7853 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Tue, 29 Jun 2021 10:36:27 -0700 Subject: [PATCH 21/22] update test name for zipkin --- .../tests/encoder/test_v1_json.py | 2 +- .../tests/encoder/test_v2_json.py | 2 +- .../tests/encoder/test_v2_protobuf.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py index a017c56f2d..a7e0480f0e 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py +++ b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v1_json.py @@ -253,7 +253,7 @@ def _test_encode_max_tag_length(self, max_tag_value_length: int): ), ) - def test_dropped(self): + def test_dropped_span_attributes(self): otel_span = get_span_with_dropped_attributes_events_links() annotations = JsonV1Encoder()._encode_span(otel_span, "test")[ "binaryAnnotations" diff --git a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py index 8911c48bed..2898604a25 100644 --- a/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py +++ b/exporter/opentelemetry-exporter-zipkin-json/tests/encoder/test_v2_json.py @@ -207,7 +207,7 @@ def _test_encode_max_tag_length(self, max_tag_value_length: int): ), ) - def test_dropped(self): + def test_dropped_span_attributes(self): otel_span = get_span_with_dropped_attributes_events_links() tags = JsonV2Encoder()._encode_span(otel_span, "test")["tags"] diff --git a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py index 6e9600d52d..787566e710 100644 --- a/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py +++ b/exporter/opentelemetry-exporter-zipkin-proto-http/tests/encoder/test_v2_protobuf.py @@ -236,7 +236,7 @@ def _test_encode_max_tag_length(self, max_tag_value_length: int): self.assertEqual(actual_output, expected_output) - def test_dropped(self): + def test_dropped_span_attributes(self): otel_span = get_span_with_dropped_attributes_events_links() # pylint: disable=no-member tags = ( From 097cf5db7d71c8be09da3849ace4d794f2985782 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Tue, 29 Jun 2021 11:06:56 -0700 Subject: [PATCH 22/22] fix lint --- .../jaeger/thrift/translate/__init__.py | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py index 7a4d047191..f21ede6f8b 100644 --- a/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py +++ b/exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/translate/__init__.py @@ -46,6 +46,11 @@ def _convert_int_to_i64(val): return val +def _append_dropped(tags, key, val): + if val: + tags.append(_get_long_tag(key, val)) + + class Translator(abc.ABC): def __init__(self, max_tag_value_length: Optional[int] = None): self._max_tag_value_length = max_tag_value_length @@ -181,7 +186,7 @@ def _translate_span(self, span: ReadableSpan) -> TCollector.Span: return jaeger_span def _extract_tags(self, span: ReadableSpan) -> Sequence[TCollector.Tag]: - + # pylint: disable=too-many-branches translated = [] if span.attributes: for key, value in span.attributes.items(): @@ -226,20 +231,17 @@ def _extract_tags(self, span: ReadableSpan) -> Sequence[TCollector.Tag]: if not span.status.is_ok: translated.append(_get_bool_tag("error", True)) - if span.dropped_attributes: - translated.append( - _get_long_tag( - "otel.dropped_attributes_count", span.dropped_attributes - ) - ) - if span.dropped_events: - translated.append( - _get_long_tag("otel.dropped_events_count", span.dropped_events) - ) - if span.dropped_links: - translated.append( - _get_long_tag("otel.dropped_links_count", span.dropped_links) - ) + _append_dropped( + translated, + "otel.dropped_attributes_count", + span.dropped_attributes, + ) + _append_dropped( + translated, "otel.dropped_events_count", span.dropped_events + ) + _append_dropped( + translated, "otel.dropped_links_count", span.dropped_links + ) return translated @@ -284,14 +286,11 @@ def _extract_logs( if tag: fields.append(tag) - if event.attributes.dropped: - fields.append( - _translate_attribute( - "otel.dropped_attributes_count", - event.attributes.dropped, - self._max_tag_value_length, - ) - ) + _append_dropped( + fields, + "otel.dropped_attributes_count", + event.attributes.dropped, + ) fields.append( TCollector.Tag(