Skip to content

Commit 4f5dbbf

Browse files
committed
fix: Use monotonic clock to compute durations
In summary, care must be taken when computing durations. Monotonic clocks are not subject to system clock adjustments or system clock skew. The difference between any two chronologically recorded time values is guaranteed to never be negative. The same guarantee above does not exist for the difference between two calls to datetime.now() and friends. More details and rationale see PEP 418. Resources: PEP 418 -- Add monotonic time, performance counter, and process time functions https://www.python.org/dev/peps/pep-0418/ PEP 564 -- Add new time functions with nanosecond resolution https://www.python.org/dev/peps/pep-0564/
1 parent dd85044 commit 4f5dbbf

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

sentry_sdk/tracing.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class Span(object):
101101
"op",
102102
"description",
103103
"start_timestamp",
104+
"_start_timestamp_monotonic",
104105
"timestamp",
105106
"_tags",
106107
"_data",
@@ -134,6 +135,14 @@ def __init__(
134135
self._tags = {} # type: Dict[str, str]
135136
self._data = {} # type: Dict[str, Any]
136137
self.start_timestamp = datetime.utcnow()
138+
try:
139+
# TODO: For Python 3.7+, we could use a clock with ns resolution:
140+
# self._start_timestamp_monotonic = time.perf_counter_ns()
141+
142+
# Python 3.3+
143+
self._start_timestamp_monotonic = time.perf_counter()
144+
except AttributeError:
145+
self._start_timestamp_monotonic = self.start_timestamp
137146

138147
#: End timestamp of span
139148
self.timestamp = None # type: Optional[datetime]
@@ -309,7 +318,11 @@ def finish(self, hub=None):
309318
# This transaction is already finished, so we should not flush it again.
310319
return None
311320

312-
self.timestamp = datetime.utcnow()
321+
try:
322+
durationSeconds = time.perf_counter() - self._start_timestamp_monotonic
323+
self.timestamp = self.start_timestamp + durationSeconds
324+
except AttributeError:
325+
self.timestamp = datetime.utcnow()
313326

314327
_maybe_create_breadcrumbs_from_span(hub, self)
315328

0 commit comments

Comments
 (0)