Skip to content

Commit 4411184

Browse files
committed
Set status for ended spans
Fixes #292
1 parent fb3e715 commit 4411184

File tree

7 files changed

+274
-180
lines changed

7 files changed

+274
-180
lines changed

ext/opentelemetry-ext-pymongo/src/opentelemetry/ext/pymongo/__init__.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
from pymongo import monitoring
2121

2222
from opentelemetry.trace import SpanKind
23-
from opentelemetry.trace.status import Status, StatusCanonicalCode
23+
from opentelemetry.trace.status import (
24+
Status, StatusCanonicalCode, OkStatus, UnknownStatus
25+
)
2426

2527
DATABASE_TYPE = "mongodb"
2628
COMMAND_ATTRIBUTES = ["filter", "sort", "skip", "limit", "pipeline"]
@@ -82,7 +84,7 @@ def succeeded(self, event: monitoring.CommandSucceededEvent):
8284
span.set_attribute(
8385
"db.mongo.duration_micros", event.duration_micros
8486
)
85-
span.set_status(Status(StatusCanonicalCode.OK, event.reply))
87+
span.set_status(OkStatus())
8688
span.end()
8789
self._remove_span(event)
8890

@@ -92,7 +94,7 @@ def failed(self, event: monitoring.CommandFailedEvent):
9294
span.set_attribute(
9395
"db.mongo.duration_micros", event.duration_micros
9496
)
95-
span.set_status(Status(StatusCanonicalCode.UNKNOWN, event.failure))
97+
span.set_status(UnknownStatus())
9698
span.end()
9799
self._remove_span(event)
98100

ext/opentelemetry-ext-pymongo/tests/test_pymongo_integration.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ def test_succeeded(self):
8282
self.assertIs(
8383
span.status.canonical_code, trace_api.status.StatusCanonicalCode.OK
8484
)
85-
self.assertEqual(span.status.description, "reply")
85+
self.assertEqual(
86+
span.status.description,
87+
"Not an error, returned on success."
88+
)
8689
self.assertIsNotNone(span.end_time)
8790

8891
def test_failed(self):
@@ -100,7 +103,9 @@ def test_failed(self):
100103
span.status.canonical_code,
101104
trace_api.status.StatusCanonicalCode.UNKNOWN,
102105
)
103-
self.assertEqual(span.status.description, "failure")
106+
self.assertEqual(
107+
span.status.description, trace_api.status.UnknownStatus.__doc__
108+
)
104109
self.assertIsNotNone(span.end_time)
105110

106111
def test_multiple_commands(self):

opentelemetry-api/src/opentelemetry/trace/__init__.py

+29-4
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
import typing
6767
from contextlib import contextmanager
6868

69-
from opentelemetry.trace.status import Status
69+
from opentelemetry.trace.status import Status, UnknownStatus
7070
from opentelemetry.util import loader, types
7171

7272
# TODO: quarantine
@@ -124,10 +124,12 @@ class SpanKind(enum.Enum):
124124
https://github.com/open-telemetry/opentelemetry-specification/pull/226.
125125
"""
126126

127-
#: Default value. Indicates that the span is used internally in the application.
127+
#: Default value. Indicates that the span is used internally in the
128+
# application.
128129
INTERNAL = 0
129130

130-
#: Indicates that the span describes an operation that handles a remote request.
131+
#: Indicates that the span describes an operation that handles a remote
132+
# request.
131133
SERVER = 1
132134

133135
#: Indicates that the span describes a request to some remote service.
@@ -144,9 +146,13 @@ class SpanKind(enum.Enum):
144146
CONSUMER = 4
145147

146148

147-
class Span:
149+
class Span(object):
148150
"""A span represents a single operation within a trace."""
149151

152+
def __init__(self, auto_update_status=False):
153+
# FIXME what is the standard to follow for documentation of attributes?
154+
self._auto_update_status = auto_update_status
155+
150156
def start(self, start_time: typing.Optional[int] = None) -> None:
151157
"""Sets the current time as the span's start time.
152158
@@ -237,8 +243,27 @@ def __exit__(
237243
exc_tb: typing.Optional[python_types.TracebackType],
238244
) -> None:
239245
"""Ends context manager and calls `end` on the `Span`."""
246+
240247
self.end()
241248

249+
if (
250+
exc_val is not None and
251+
self.status is None and
252+
self._auto_update_status
253+
):
254+
if isinstance(exc_val, Status):
255+
self.set_status(exc_val.status)
256+
257+
else:
258+
self.set_status(UnknownStatus)
259+
260+
# return False
261+
# return True
262+
263+
# FIXME https://docs.python.org/3.7/reference/datamodel.html?highlight=__exit__#object.__exit__
264+
# says that a boolean value should be returned. Is the lack of the
265+
# return of a boolean value here intentional?
266+
242267

243268
class TraceOptions(int):
244269
"""A bitmask that represents options specific to the trace.

0 commit comments

Comments
 (0)