From e7c8c8e1e12bb5b84c562eb3416da1cec125b5ce Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 29 Jun 2021 10:52:16 -0700 Subject: [PATCH 1/5] otlp --- CHANGELOG.md | 2 ++ .../exporter/otlp/proto/grpc/exporter.py | 4 +-- .../proto/grpc/trace_exporter/__init__.py | 29 +++++++++---------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 306004537d..995be071a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `BoundedAttributes` to the API to make it available for `Link` which is defined in the API. Marked `BoundedDict` in the SDK as deprecated as a result. ([#1915](https://github.com/open-telemetry/opentelemetry-python/pull/1915)) +- Fix OTLP SpanExporter to distinguish spans based off Resource and InstrumentationInfo + ([#1915](https://github.com/open-telemetry/opentelemetry-python/pull/1915)) ## [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/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 7b9227fd07..f0317696c5 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -157,9 +157,7 @@ def get_resource_data( resource_class( **{ "resource": collector_resource, - "instrumentation_library_{}".format(name): [ - instrumentation_library_data - ], + "instrumentation_library_{}".format(name): instrumentation_library_data.values(), } ) ) 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..e8b30f9aac 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 @@ -236,12 +236,17 @@ def _translate_data( sdk_resource_instrumentation_library_spans = {} for sdk_span in data: - - if sdk_span.resource not in ( - sdk_resource_instrumentation_library_spans.keys() - ): + instrumentation_library_spans_map = sdk_resource_instrumentation_library_spans.get(sdk_span.resource, {}) + # If we haven't seen the Resource yet, add it to the map + if not instrumentation_library_spans_map: + sdk_resource_instrumentation_library_spans[ + sdk_span.resource + ] = instrumentation_library_spans_map + instrumentation_library_spans = instrumentation_library_spans_map.get(sdk_span.instrumentation_info) + # If we haven't seen the InstrumentationInfo for this Resource yet, add it to the map + if not instrumentation_library_spans: if sdk_span.instrumentation_info is not None: - instrumentation_library_spans = ( + instrumentation_library_spans_map[sdk_span.instrumentation_info] = ( InstrumentationLibrarySpans( instrumentation_library=InstrumentationLibrary( name=sdk_span.instrumentation_info.name, @@ -249,16 +254,12 @@ def _translate_data( ) ) ) - else: - instrumentation_library_spans = ( + # If no InstrumentationInfo, store in None key + instrumentation_library_spans_map[sdk_span.instrumentation_info] = ( InstrumentationLibrarySpans() ) - - sdk_resource_instrumentation_library_spans[ - sdk_span.resource - ] = instrumentation_library_spans - + instrumentation_library_spans = instrumentation_library_spans_map.get(sdk_span.instrumentation_info) self._collector_span_kwargs = {} self._translate_name(sdk_span) @@ -278,9 +279,7 @@ def _translate_data( "SPAN_KIND_{}".format(sdk_span.kind.name), ) - sdk_resource_instrumentation_library_spans[ - sdk_span.resource - ].spans.append(CollectorSpan(**self._collector_span_kwargs)) + instrumentation_library_spans.spans.append(CollectorSpan(**self._collector_span_kwargs)) return ExportTraceServiceRequest( resource_spans=get_resource_data( From 140fdbcb0c9b60255ddbb8c939eb97552867a1db Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 29 Jun 2021 12:46:13 -0700 Subject: [PATCH 2/5] test --- .../tests/test_otlp_trace_exporter.py | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) 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..afc66eb0ba 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 @@ -168,8 +168,44 @@ def setUp(self): ), ) + self.span2 = _Span( + "b", + context=Mock( + **{ + "trace_state": OrderedDict([("a", "b"), ("c", "d")]), + "span_id": 10217189687419569865, + "trace_id": 67545097771067222548457157018666467027, + } + ), + resource=SDKResource(OrderedDict([("a", 2), ("b", False)])), + parent=Mock(**{"span_id": 12345}), + instrumentation_info=InstrumentationInfo( + name="name", version="version" + ), + ) + + self.span3 = _Span( + "c", + context=Mock( + **{ + "trace_state": OrderedDict([("a", "b"), ("c", "d")]), + "span_id": 10217189687419569865, + "trace_id": 67545097771067222548457157018666467027, + } + ), + resource=SDKResource(OrderedDict([("a", 1), ("b", False)])), + parent=Mock(**{"span_id": 12345}), + instrumentation_info=InstrumentationInfo( + name="name2", version="version2" + ), + ) + self.span.start() self.span.end() + self.span2.start() + self.span2.end() + self.span3.start() + self.span3.end() def tearDown(self): self.server.stop(None) @@ -497,6 +533,179 @@ def test_translate_spans(self): # pylint: disable=protected-access self.assertEqual(expected, self.exporter._translate_data([self.span])) + def test_translate_spans_multi(self): + + expected = ExportTraceServiceRequest( + resource_spans=[ + ResourceSpans( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=1)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_spans=[ + InstrumentationLibrarySpans( + instrumentation_library=InstrumentationLibrary( + name="name", version="version" + ), + spans=[ + OTLPSpan( + # pylint: disable=no-member + name="a", + start_time_unix_nano=self.span.start_time, + end_time_unix_nano=self.span.end_time, + trace_state="a=b,c=d", + span_id=int.to_bytes( + 10217189687419569865, 8, "big" + ), + trace_id=int.to_bytes( + 67545097771067222548457157018666467027, + 16, + "big", + ), + parent_span_id=( + b"\000\000\000\000\000\00009" + ), + kind=( + OTLPSpan.SpanKind.SPAN_KIND_INTERNAL + ), + attributes=[ + KeyValue( + key="a", + value=AnyValue(int_value=1), + ), + KeyValue( + key="b", + value=AnyValue(bool_value=True), + ), + ], + events=[ + OTLPSpan.Event( + name="a", + time_unix_nano=1591240820506462784, + attributes=[ + KeyValue( + key="a", + value=AnyValue( + int_value=1 + ), + ), + KeyValue( + key="b", + value=AnyValue( + bool_value=False + ), + ), + ], + ) + ], + status=Status(code=0, message=""), + links=[ + OTLPSpan.Link( + trace_id=int.to_bytes( + 1, 16, "big" + ), + span_id=int.to_bytes(2, 8, "big"), + attributes=[ + KeyValue( + key="a", + value=AnyValue( + int_value=1 + ), + ), + KeyValue( + key="b", + value=AnyValue( + bool_value=False + ), + ), + ], + ) + ], + ) + ], + ), + InstrumentationLibrarySpans( + instrumentation_library=InstrumentationLibrary( + name="name2", version="version2" + ), + spans=[ + OTLPSpan( + # pylint: disable=no-member + name="c", + start_time_unix_nano=self.span.start_time, + end_time_unix_nano=self.span.end_time, + trace_state="a=b,c=d", + span_id=int.to_bytes( + 10217189687419569865, 8, "big" + ), + trace_id=int.to_bytes( + 67545097771067222548457157018666467027, + 16, + "big", + ), + parent_span_id=( + b"\000\000\000\000\000\00009" + ), + kind=( + OTLPSpan.SpanKind.SPAN_KIND_INTERNAL + ), + status=Status(code=0, message=""), + ) + ], + ) + ], + ), + ResourceSpans( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=2)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_spans=[ + InstrumentationLibrarySpans( + instrumentation_library=InstrumentationLibrary( + name="name", version="version" + ), + spans=[ + OTLPSpan( + # pylint: disable=no-member + name="b", + start_time_unix_nano=self.span.start_time, + end_time_unix_nano=self.span.end_time, + trace_state="a=b,c=d", + span_id=int.to_bytes( + 10217189687419569865, 8, "big" + ), + trace_id=int.to_bytes( + 67545097771067222548457157018666467027, + 16, + "big", + ), + parent_span_id=( + b"\000\000\000\000\000\00009" + ), + kind=( + OTLPSpan.SpanKind.SPAN_KIND_INTERNAL + ), + status=Status(code=0, message=""), + ) + ], + ) + ], + ), + ] + ) + + # pylint: disable=protected-access + self.assertEqual(expected, self.exporter._translate_data([self.span, self.span2, self.span3])) + def _check_translated_status( self, translated: ExportTraceServiceRequest, From c523d946b93bd30928cc5215450a4f4db05ec66d Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 29 Jun 2021 12:58:10 -0700 Subject: [PATCH 3/5] lint --- CHANGELOG.md | 2 +- .../proto/grpc/trace_exporter/__init__.py | 40 +++++++++++++------ .../tests/test_otlp_trace_exporter.py | 16 ++++---- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 995be071a2..76043e4235 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 API. Marked `BoundedDict` in the SDK as deprecated as a result. ([#1915](https://github.com/open-telemetry/opentelemetry-python/pull/1915)) - Fix OTLP SpanExporter to distinguish spans based off Resource and InstrumentationInfo - ([#1915](https://github.com/open-telemetry/opentelemetry-python/pull/1915)) + ([#1927](https://github.com/open-telemetry/opentelemetry-python/pull/1927)) ## [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 e8b30f9aac..4f563d31ad 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 @@ -236,30 +236,42 @@ def _translate_data( sdk_resource_instrumentation_library_spans = {} for sdk_span in data: - instrumentation_library_spans_map = sdk_resource_instrumentation_library_spans.get(sdk_span.resource, {}) + instrumentation_library_spans_map = ( + sdk_resource_instrumentation_library_spans.get( + sdk_span.resource, {} + ) + ) # If we haven't seen the Resource yet, add it to the map if not instrumentation_library_spans_map: sdk_resource_instrumentation_library_spans[ sdk_span.resource ] = instrumentation_library_spans_map - instrumentation_library_spans = instrumentation_library_spans_map.get(sdk_span.instrumentation_info) + instrumentation_library_spans = ( + instrumentation_library_spans_map.get( + sdk_span.instrumentation_info + ) + ) # If we haven't seen the InstrumentationInfo for this Resource yet, add it to the map if not instrumentation_library_spans: if sdk_span.instrumentation_info is not None: - instrumentation_library_spans_map[sdk_span.instrumentation_info] = ( - InstrumentationLibrarySpans( - instrumentation_library=InstrumentationLibrary( - name=sdk_span.instrumentation_info.name, - version=sdk_span.instrumentation_info.version, - ) + instrumentation_library_spans_map[ + sdk_span.instrumentation_info + ] = InstrumentationLibrarySpans( + instrumentation_library=InstrumentationLibrary( + name=sdk_span.instrumentation_info.name, + version=sdk_span.instrumentation_info.version, ) ) else: # If no InstrumentationInfo, store in None key - instrumentation_library_spans_map[sdk_span.instrumentation_info] = ( - InstrumentationLibrarySpans() - ) - instrumentation_library_spans = instrumentation_library_spans_map.get(sdk_span.instrumentation_info) + instrumentation_library_spans_map[ + sdk_span.instrumentation_info + ] = InstrumentationLibrarySpans() + instrumentation_library_spans = ( + instrumentation_library_spans_map.get( + sdk_span.instrumentation_info + ) + ) self._collector_span_kwargs = {} self._translate_name(sdk_span) @@ -279,7 +291,9 @@ def _translate_data( "SPAN_KIND_{}".format(sdk_span.kind.name), ) - instrumentation_library_spans.spans.append(CollectorSpan(**self._collector_span_kwargs)) + instrumentation_library_spans.spans.append( + CollectorSpan(**self._collector_span_kwargs) + ) return ExportTraceServiceRequest( resource_spans=get_resource_data( 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 afc66eb0ba..3991b147b6 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 @@ -534,7 +534,6 @@ def test_translate_spans(self): self.assertEqual(expected, self.exporter._translate_data([self.span])) def test_translate_spans_multi(self): - expected = ExportTraceServiceRequest( resource_spans=[ ResourceSpans( @@ -636,8 +635,8 @@ def test_translate_spans_multi(self): OTLPSpan( # pylint: disable=no-member name="c", - start_time_unix_nano=self.span.start_time, - end_time_unix_nano=self.span.end_time, + start_time_unix_nano=self.span3.start_time, + end_time_unix_nano=self.span3.end_time, trace_state="a=b,c=d", span_id=int.to_bytes( 10217189687419569865, 8, "big" @@ -656,7 +655,7 @@ def test_translate_spans_multi(self): status=Status(code=0, message=""), ) ], - ) + ), ], ), ResourceSpans( @@ -677,8 +676,8 @@ def test_translate_spans_multi(self): OTLPSpan( # pylint: disable=no-member name="b", - start_time_unix_nano=self.span.start_time, - end_time_unix_nano=self.span.end_time, + start_time_unix_nano=self.span2.start_time, + end_time_unix_nano=self.span2.end_time, trace_state="a=b,c=d", span_id=int.to_bytes( 10217189687419569865, 8, "big" @@ -704,7 +703,10 @@ def test_translate_spans_multi(self): ) # pylint: disable=protected-access - self.assertEqual(expected, self.exporter._translate_data([self.span, self.span2, self.span3])) + self.assertEqual( + expected, + self.exporter._translate_data([self.span, self.span2, self.span3]), + ) def _check_translated_status( self, From d329311263b0b30b7fb05382d31b63444cc2f633 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 29 Jun 2021 13:02:30 -0700 Subject: [PATCH 4/5] Update exporter.py --- .../src/opentelemetry/exporter/otlp/proto/grpc/exporter.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index f0317696c5..ba88dc1d7d 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -157,7 +157,9 @@ def get_resource_data( resource_class( **{ "resource": collector_resource, - "instrumentation_library_{}".format(name): instrumentation_library_data.values(), + "instrumentation_library_{}".format( + name + ): instrumentation_library_data.values(), } ) ) From 767bbd477b11ad1bc92826df6c08b15b08000532 Mon Sep 17 00:00:00 2001 From: alrex Date: Thu, 1 Jul 2021 14:02:17 -0700 Subject: [PATCH 5/5] update SHA --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c88b731332..7e2acbe3a6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: 82c4f600872a72fedaebad758f0d5588dfb53a00 + CONTRIB_REPO_SHA: c100b21fa40727709bb31cf4e2b67b737a09ea2c jobs: build: