diff --git a/README.md b/README.md index b597d6f6119..a7fbd3efd7a 100644 --- a/README.md +++ b/README.md @@ -43,17 +43,18 @@ pip install -e ./ext/opentelemetry-ext-{integration} from opentelemetry import trace from opentelemetry.context import Context from opentelemetry.sdk.trace import Tracer +from opentelemetry.sdk.trace.export import ConsoleSpanExporter +from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor trace.set_preferred_tracer_implementation(lambda T: Tracer()) tracer = trace.tracer() +tracer.add_span_processor( + SimpleExportSpanProcessor(ConsoleSpanExporter()) +) with tracer.start_span('foo'): - print(Context) with tracer.start_span('bar'): - print(Context) with tracer.start_span('baz'): print(Context) - print(Context) - print(Context) ``` See [opentelemetry-example-app](./opentelemetry-example-app/README.rst) for a complete example. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index a694476e1fe..c839fe4b616 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -280,7 +280,20 @@ def __init__( self.start_time = None def __repr__(self): - return '{}(name="{}")'.format(type(self).__name__, self.name) + return '{}(name="{}", context={})'.format( + 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 get_context(self): return self.context diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py index 0c011f99761..52d6d3bd22f 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py @@ -76,3 +76,17 @@ def on_end(self, span: Span) -> None: def shutdown(self) -> None: self.span_exporter.shutdown() + + +class ConsoleSpanExporter(SpanExporter): + """Implementation of :class:`SpanExporter` that prints spans to the + console. + + This class can be used for diagnostic purposes. It prints the exported + spans to the console STDOUT. + """ + + def export(self, spans: typing.Sequence[Span]) -> SpanExportResult: + for span in spans: + print(span) + return SpanExportResult.SUCCESS diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/in_memory_span_exporter.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/in_memory_span_exporter.py index b5361205602..0818805f39c 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/in_memory_span_exporter.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/export/in_memory_span_exporter.py @@ -20,7 +20,7 @@ class InMemorySpanExporter(SpanExporter): - """Implementation of :class:`.Exporter` that stores spans in memory. + """Implementation of :class:`.SpanExporter` that stores spans in memory. This class can be used for testing purposes. It stores the exported spans in a list in memory that can be retrieved using the diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/util.py b/opentelemetry-sdk/src/opentelemetry/sdk/util.py index d814433eeec..d855e851794 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/util.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/util.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import datetime import time try: @@ -21,3 +22,9 @@ def time_ns(): return int(time.time() * 1e9) + + +def ns_to_iso_str(nanoseconds): + """Get an ISO 8601 string from time_ns value.""" + ts = datetime.datetime.fromtimestamp(nanoseconds / 1e9) + return ts.strftime("%Y-%m-%dT%H:%M:%S.%fZ")