diff --git a/docs/examples/auto-instrumentation/README.rst b/docs/examples/auto-instrumentation/README.rst index a37d8ea4dc..0c321eefe9 100644 --- a/docs/examples/auto-instrumentation/README.rst +++ b/docs/examples/auto-instrumentation/README.rst @@ -136,7 +136,14 @@ similar to the following example: "http.flavor": "1.1" }, "events": [], - "links": [] + "links": [], + "resource": { + "telemetry.sdk.language": "python", + "telemetry.sdk.name": "opentelemetry", + "telemetry.sdk.version": "0.16b1" + }, + "service_name": null + } Execute an automatically instrumented server @@ -191,7 +198,14 @@ similar to the following example: "http.status_code": 200 }, "events": [], - "links": [] + "links": [], + "resource": { + "telemetry.sdk.language": "python", + "telemetry.sdk.name": "opentelemetry", + "telemetry.sdk.version": "0.16b1", + "service.name": "" + }, + "service_name": "" } You can see that both outputs are the same because automatic instrumentation does diff --git a/opentelemetry-sdk/setup.cfg b/opentelemetry-sdk/setup.cfg index 6ef8fca662..4fc5eae848 100644 --- a/opentelemetry-sdk/setup.cfg +++ b/opentelemetry-sdk/setup.cfg @@ -54,7 +54,7 @@ opentelemetry_tracer_provider = opentelemetry_propagator = b3 = opentelemetry.sdk.trace.propagation.b3_format:B3Format opentelemetry_exporter = - console_span = opentelemetry.sdk.trace:ConsoleSpanExporter + console_span = opentelemetry.sdk.trace.export:ConsoleSpanExporter console_metrics = opentelemetry.sdk.metrics:ConsoleMetricsExporter [options.extras_require] diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py index 83bd9b97c3..beb32cdeda 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py @@ -13,12 +13,14 @@ # limitations under the License. import collections +import json import logging import os import sys import threading import typing from enum import Enum +from typing import Optional from opentelemetry.configuration import Configuration from opentelemetry.context import Context, attach, detach, set_value @@ -370,7 +372,7 @@ class ConsoleSpanExporter(SpanExporter): def __init__( self, - service_name=None, + service_name: Optional[str] = None, out: typing.IO = sys.stdout, formatter: typing.Callable[[Span], str] = lambda span: span.to_json() + os.linesep, @@ -381,6 +383,8 @@ def __init__( def export(self, spans: typing.Sequence[Span]) -> SpanExportResult: for span in spans: - self.out.write(self.formatter(span)) + span_json = json.loads(self.formatter(span)) + span_json.update({"service_name": self.service_name}) + self.out.write(json.dumps(span_json, indent=4)) self.out.flush() return SpanExportResult.SUCCESS diff --git a/opentelemetry-sdk/tests/trace/export/test_export.py b/opentelemetry-sdk/tests/trace/export/test_export.py index 4ad23dd863..cf48d19aa1 100644 --- a/opentelemetry-sdk/tests/trace/export/test_export.py +++ b/opentelemetry-sdk/tests/trace/export/test_export.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os +import json import threading import time import unittest @@ -478,26 +478,33 @@ class TestConsoleSpanExporter(unittest.TestCase): def test_export(self): # pylint: disable=no-self-use """Check that the console exporter prints spans.""" exporter = export.ConsoleSpanExporter() - # Mocking stdout interferes with debugging and test reporting, mock on # the exporter instance instead. span = trace._Span("span name", trace_api.INVALID_SPAN_CONTEXT) with mock.patch.object(exporter, "out") as mock_stdout: exporter.export([span]) - mock_stdout.write.assert_called_once_with(span.to_json() + os.linesep) + span_json = json.loads(span.to_json()) + span_json.update({"service_name": None}) + + mock_stdout.write.assert_called_once_with( + json.dumps(span_json, indent=4) + ) + self.assertEqual(mock_stdout.write.call_count, 1) self.assertEqual(mock_stdout.flush.call_count, 1) def test_export_custom(self): # pylint: disable=no-self-use """Check that console exporter uses custom io, formatter.""" - mock_span_str = mock.Mock(str) def formatter(span): # pylint: disable=unused-argument - return mock_span_str + return json.dumps({"service_name": None}, indent=4) mock_stdout = mock.Mock() exporter = export.ConsoleSpanExporter( out=mock_stdout, formatter=formatter ) - exporter.export([trace._Span("span name", mock.Mock())]) - mock_stdout.write.assert_called_once_with(mock_span_str) + span = trace._Span("span name", mock.Mock()) + exporter.export([span]) + mock_stdout.write.assert_called_once_with( + json.dumps({"service_name": None}, indent=4) + )