Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve console span exporter #505

128 changes: 115 additions & 13 deletions opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import atexit
import logging
import os
import random
import threading
from contextlib import contextmanager
Expand Down Expand Up @@ -204,19 +205,120 @@ def __repr__(self):
type(self).__name__, self.name, self.context
)

def __str__(self):
return (
'{}(name="{}", context={}, kind={}, '
"parent={}, start_time={}, end_time={})"
).format(
type(self).__name__,
self.name,
self.context,
self.kind,
repr(self.parent),
util.ns_to_iso_str(self.start_time) if self.start_time else "None",
util.ns_to_iso_str(self.end_time) if self.end_time else "None",
)
def __str__(self, indent=0):
def format_context(context, indent=0):
text = [
type(context).__name__ + "(",
"trace_id=" + trace_api.format_trace_id(context.trace_id),
"span_id=" + trace_api.format_span_id(context.span_id),
"trace_state=" + repr(context.trace_state),
")",
]

# add indentation
for index in range(1, len(text) - 1):
text[index] = " " * (2 + indent) + text[index]
text[-1] = " " * indent + text[-1]

return os.linesep.join(text)

def format_attributes(attributes, indent=0):
if not attributes:
return "None"
text = [
" " * (2 + indent) + k + "=" + str(v)
for (k, v) in attributes.items()
]
return os.linesep + os.linesep.join(text)

def format_event(event, indent=0):
text = [
"Event(",
'name="' + event.name + '"',
"timestamp=" + util.ns_to_iso_str(event.timestamp),
"attributes="
+ format_attributes(event.attributes, indent + 2),
")",
]

for index in range(1, len(text) - 1):
text[index] = " " * (2 + indent) + text[index]

text[0] = " " * indent + text[0]
text[-1] = " " * indent + text[-1]

return os.linesep.join(text)

def format_events(events, indent=0):
if not events:
return "None"
text = ""
for event in events:
text += os.linesep + format_event(event, indent)
return text

def format_link(link, indent=0):
text = [
"Link(",
"context="
+ format_context(link.context, 2 + indent + len("context=")),
"attributes=" + format_attributes(link.attributes, indent + 2),
")",
]

# add indentation
for index in range(1, len(text) - 1):
text[index] = " " * (2 + indent) + text[index]
text[0] = " " * indent + text[0]
text[-1] = " " * indent + text[-1]

return os.linesep.join(text)

def format_links(links, indent=0):
if not links:
return "None"
text = ""
for link in links:
text += os.linesep + format_link(link, indent)
return text

parent_id = "None"
if self.parent is not None:
if isinstance(self.parent, Span):
ctx = self.parent.context
parent_id = trace_api.format_span_id(ctx.span_id)
elif isinstance(self.parent, SpanContext):
parent_id = trace_api.format_span_id(self.parent.span_id)

start_time = "None"
if self.start_time:
start_time = util.ns_to_iso_str(self.start_time)

end_time = "None"
if self.end_time:
end_time = util.ns_to_iso_str(self.end_time)

text = [
type(self).__name__ + "(",
'name="' + self.name + '"',
"context="
+ format_context(self.context, 2 + indent + len("context=")),
"kind=" + str(self.kind),
"parent_id=" + parent_id,
"start_time=" + start_time,
"end_time=" + end_time,
"attributes=" + format_attributes(self.attributes, 2),
"events=" + format_events(self.events, indent + 4),
"links=" + format_links(self.links, indent + 4),
")",
]

# add indentation
for index in range(1, len(text) - 1):
text[index] = " " * (2 + indent) + text[index]
text[-1] = " " * indent + text[-1]

return os.linesep.join(text)
mauriciovasquezbernal marked this conversation as resolved.
Show resolved Hide resolved

def get_context(self):
return self.context
Expand Down
2 changes: 1 addition & 1 deletion opentelemetry-sdk/tests/trace/export/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def test_export(self): # pylint: disable=no-self-use

# Mocking stdout interferes with debugging and test reporting, mock on
# the exporter instance instead.
span = trace.Span("span name", mock.Mock())
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(str(span) + os.linesep)
Expand Down