Skip to content

Commit 724c792

Browse files
authored
Populate service_name from exporting span in JaegerExporters (open-telemetry#1703)
1 parent 77ff070 commit 724c792

File tree

6 files changed

+83
-21
lines changed

6 files changed

+83
-21
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6666
install it as a dependency. This will allow for the next package/protocol to also be in
6767
its own package.
6868
([#1695](https://github.com/open-telemetry/opentelemetry-python/pull/1695))
69+
- Change Jaeger exporters to obtain service.name from span
70+
([#1703](https://github.com/open-telemetry/opentelemetry-python/pull/1703))
6971

7072
### Removed
7173
- Removed unused `get_hexadecimal_trace_id` and `get_hexadecimal_span_id` methods.

exporter/opentelemetry-exporter-jaeger-proto/src/opentelemetry/exporter/jaeger/proto/__init__.py

+9
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@ def _collector_grpc_client(self) -> Optional[CollectorServiceStub]:
145145
return self._grpc_client
146146

147147
def export(self, spans) -> SpanExportResult:
148+
# Populate service_name from first span
149+
# We restrict any SpanProcessor to be only associated with a single
150+
# TracerProvider, so it is safe to assume that all Spans in a single
151+
# batch all originate from one TracerProvider (and in turn have all
152+
# the same service.name)
153+
if spans:
154+
service_name = spans[0].resource.attributes.get(SERVICE_NAME)
155+
if service_name:
156+
self.service_name = service_name
148157
translator = Translate(spans)
149158
pb_translator = ProtobufTranslator(
150159
self.service_name, self._max_tag_value_length

exporter/opentelemetry-exporter-jaeger-proto/tests/test_jaeger_exporter_protobuf.py

+34-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import os
1616
import unittest
1717
from collections import OrderedDict
18-
from unittest.mock import patch
18+
from unittest import mock
1919

2020
# pylint:disable=no-name-in-module
2121
# pylint:disable=import-error
@@ -34,7 +34,9 @@
3434
OTEL_EXPORTER_JAEGER_ENDPOINT,
3535
OTEL_RESOURCE_ATTRIBUTES,
3636
)
37-
from opentelemetry.sdk.trace import Resource, TracerProvider
37+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
38+
from opentelemetry.sdk.trace import TracerProvider
39+
from opentelemetry.sdk.trace.export import SpanExportResult
3840
from opentelemetry.sdk.util.instrumentation import InstrumentationInfo
3941
from opentelemetry.trace.status import Status, StatusCode
4042

@@ -43,13 +45,13 @@
4345
class TestJaegerExporter(unittest.TestCase):
4446
def setUp(self):
4547
# create and save span to be used in tests
46-
context = trace_api.SpanContext(
48+
self.context = trace_api.SpanContext(
4749
trace_id=0x000000000000000000000000DEADBEEF,
4850
span_id=0x00000000DEADBEF0,
4951
is_remote=False,
5052
)
5153

52-
self._test_span = trace._Span("test_span", context=context)
54+
self._test_span = trace._Span("test_span", context=self.context)
5355
self._test_span.start()
5456
self._test_span.end()
5557

@@ -62,7 +64,7 @@ def test_constructor_by_environment_variables(self):
6264

6365
collector_endpoint = "localhost:14250"
6466

65-
env_patch = patch.dict(
67+
env_patch = mock.patch.dict(
6668
"os.environ",
6769
{
6870
OTEL_EXPORTER_JAEGER_ENDPOINT: collector_endpoint,
@@ -438,3 +440,30 @@ def test_max_tag_value_length(self):
438440
self.assertEqual("hello", tags_by_keys["key_string"])
439441
self.assertEqual("('tup", tags_by_keys["key_tuple"])
440442
self.assertEqual("some_", tags_by_keys["key_resource"])
443+
444+
def test_export(self):
445+
client_mock = mock.Mock()
446+
spans = []
447+
exporter = JaegerExporter()
448+
exporter._grpc_client = client_mock
449+
status = exporter.export(spans)
450+
self.assertEqual(SpanExportResult.SUCCESS, status)
451+
452+
def test_export_span_service_name(self):
453+
resource = Resource.create({SERVICE_NAME: "test"})
454+
span = trace._Span(
455+
"test_span", context=self.context, resource=resource
456+
)
457+
span.start()
458+
span.end()
459+
client_mock = mock.Mock()
460+
exporter = JaegerExporter()
461+
exporter._grpc_client = client_mock
462+
exporter.export([span])
463+
self.assertEqual(exporter.service_name, "test")
464+
465+
466+
class MockResponse:
467+
def __init__(self, status_code):
468+
self.status_code = status_code
469+
self.text = status_code

exporter/opentelemetry-exporter-jaeger-thrift/src/opentelemetry/exporter/jaeger/thrift/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,15 @@ def _collector_http_client(self) -> Optional[Collector]:
201201
return self._collector
202202

203203
def export(self, spans) -> SpanExportResult:
204-
204+
# Populate service_name from first span
205+
# We restrict any SpanProcessor to be only associated with a single
206+
# TracerProvider, so it is safe to assume that all Spans in a single
207+
# batch all originate from one TracerProvider (and in turn have all
208+
# the same service.name)
209+
if spans:
210+
service_name = spans[0].resource.attributes.get(SERVICE_NAME)
211+
if service_name:
212+
self.service_name = service_name
205213
translator = Translate(spans)
206214
thrift_translator = ThriftTranslator(self._max_tag_value_length)
207215
jaeger_spans = translator._translate(thrift_translator)

exporter/opentelemetry-exporter-jaeger-thrift/tests/test_jaeger_exporter_thrift.py

+23-2
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@
4444
class TestJaegerExporter(unittest.TestCase):
4545
def setUp(self):
4646
# create and save span to be used in tests
47-
context = trace_api.SpanContext(
47+
self.context = trace_api.SpanContext(
4848
trace_id=0x000000000000000000000000DEADBEEF,
4949
span_id=0x00000000DEADBEF0,
5050
is_remote=False,
5151
)
5252

53-
self._test_span = trace._Span("test_span", context=context)
53+
self._test_span = trace._Span("test_span", context=self.context)
5454
self._test_span.start()
5555
self._test_span.end()
5656
# pylint: disable=protected-access
@@ -491,6 +491,27 @@ def test_export(self):
491491
self.assertEqual(collector_mock.submit.call_count, 1)
492492
# trace_api._TRACER_PROVIDER = None
493493

494+
@patch("opentelemetry.exporter.jaeger.thrift.trace._TRACER_PROVIDER", None)
495+
def test_export_span_service_name(self):
496+
trace_api.set_tracer_provider(
497+
TracerProvider(
498+
resource=Resource.create({SERVICE_NAME: "text_export"})
499+
)
500+
)
501+
exporter = jaeger_exporter.JaegerExporter(
502+
agent_host_name="localhost", agent_port=6318
503+
)
504+
agent_client_mock = mock.Mock(spec=jaeger_exporter.AgentClientUDP)
505+
exporter._agent_client = agent_client_mock
506+
resource = Resource.create({SERVICE_NAME: "test"})
507+
span = trace._Span(
508+
"test_span", context=self.context, resource=resource
509+
)
510+
span.start()
511+
span.end()
512+
exporter.export([span])
513+
self.assertEqual(exporter.service_name, "test")
514+
494515
def test_agent_client(self):
495516
agent_client = jaeger_exporter.AgentClientUDP(
496517
host_name="localhost", port=6354

exporter/opentelemetry-exporter-jaeger/README.rst

+6-13
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ OpenTelemetry Jaeger Exporter
66
.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-jaeger.svg
77
:target: https://pypi.org/project/opentelemetry-exporter-jaeger/
88

9-
This library allows to export tracing data to `Jaeger <https://www.jaegertracing.io/>`_.
9+
This library is provided as a convenience to install all supported Jaeger Exporters. Currently it installs:
10+
* opentelemetry-exporter-jaeger-proto
11+
* opentelemetry-exporter-jaeger-thrift
12+
13+
To avoid unnecessary dependencies, users should install the specific package once they've determined their
14+
preferred serialization method.
1015

1116
Installation
1217
------------
@@ -16,18 +21,6 @@ Installation
1621
pip install opentelemetry-exporter-jaeger
1722

1823

19-
.. _Jaeger: https://www.jaegertracing.io/
20-
.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/
21-
22-
Configuration
23-
-------------
24-
25-
OpenTelemetry Jaeger Exporter can be configured by setting `JaegerExporter parameters
26-
<https://github.com/open-telemetry/opentelemetry-python/blob/main/exporter/opentelemetry-exporter-jaeger
27-
/src/opentelemetry/exporter/jaeger/__init__.py#L88>`_ or by setting
28-
`environment variables <https://github.com/open-telemetry/opentelemetry-specification/blob/main/
29-
specification/sdk-environment-variables.md#jaeger-exporter>`_
30-
3124
References
3225
----------
3326

0 commit comments

Comments
 (0)