|
1 | 1 | import re |
2 | 2 | import uuid |
3 | 3 | import contextlib |
| 4 | +import time |
4 | 5 |
|
5 | | -from datetime import datetime |
| 6 | +from datetime import datetime, timedelta |
6 | 7 |
|
7 | 8 | import sentry_sdk |
8 | 9 |
|
@@ -101,6 +102,7 @@ class Span(object): |
101 | 102 | "op", |
102 | 103 | "description", |
103 | 104 | "start_timestamp", |
| 105 | + "_start_timestamp_monotonic", |
104 | 106 | "timestamp", |
105 | 107 | "_tags", |
106 | 108 | "_data", |
@@ -134,6 +136,14 @@ def __init__( |
134 | 136 | self._tags = {} # type: Dict[str, str] |
135 | 137 | self._data = {} # type: Dict[str, Any] |
136 | 138 | self.start_timestamp = datetime.utcnow() |
| 139 | + try: |
| 140 | + # TODO: For Python 3.7+, we could use a clock with ns resolution: |
| 141 | + # self._start_timestamp_monotonic = time.perf_counter_ns() |
| 142 | + |
| 143 | + # Python 3.3+ |
| 144 | + self._start_timestamp_monotonic = time.perf_counter() |
| 145 | + except AttributeError: |
| 146 | + self._start_timestamp_monotonic = self.start_timestamp |
137 | 147 |
|
138 | 148 | #: End timestamp of span |
139 | 149 | self.timestamp = None # type: Optional[datetime] |
@@ -309,7 +319,11 @@ def finish(self, hub=None): |
309 | 319 | # This transaction is already finished, so we should not flush it again. |
310 | 320 | return None |
311 | 321 |
|
312 | | - self.timestamp = datetime.utcnow() |
| 322 | + try: |
| 323 | + durationSeconds = time.perf_counter() - self._start_timestamp_monotonic |
| 324 | + self.timestamp = self.start_timestamp + timedelta(seconds=durationSeconds) |
| 325 | + except AttributeError: |
| 326 | + self.timestamp = datetime.utcnow() |
313 | 327 |
|
314 | 328 | _maybe_create_breadcrumbs_from_span(hub, self) |
315 | 329 |
|
|
0 commit comments