|
3 | 3 | from datetime import datetime, timedelta, timezone |
4 | 4 |
|
5 | 5 | from opentelemetry import trace as otel_trace, context |
6 | | -from opentelemetry.trace import format_trace_id, format_span_id |
| 6 | +from opentelemetry.trace import format_trace_id, format_span_id, Span as OtelSpan |
7 | 7 | from opentelemetry.trace.status import StatusCode |
8 | 8 | from opentelemetry.sdk.trace import ReadableSpan |
9 | 9 |
|
|
17 | 17 | nanosecond_time, |
18 | 18 | ) |
19 | 19 |
|
20 | | -from typing import TYPE_CHECKING |
| 20 | +from typing import TYPE_CHECKING, cast |
21 | 21 |
|
22 | 22 | if TYPE_CHECKING: |
23 | 23 | from collections.abc import Callable, Mapping, MutableMapping |
@@ -1201,32 +1201,42 @@ def __init__( |
1201 | 1201 | start_timestamp=None, # type: Optional[Union[datetime, float]] |
1202 | 1202 | origin=None, # type: Optional[str] |
1203 | 1203 | name=None, # type: Optional[str] |
| 1204 | + otel_span=None, # type: Optional[OtelSpan] |
1204 | 1205 | **_, # type: dict[str, object] |
1205 | 1206 | ): |
1206 | 1207 | # type: (...) -> None |
1207 | 1208 | """ |
1208 | 1209 | For backwards compatibility with old the old Span interface, this class |
1209 | 1210 | accepts arbitrary keyword arguments, in addition to the ones explicitly |
1210 | 1211 | listed in the signature. These additional arguments are ignored. |
| 1212 | +
|
| 1213 | + If otel_span is passed explicitly, just acts as a proxy. |
1211 | 1214 | """ |
1212 | | - from sentry_sdk.integrations.opentelemetry.utils import ( |
1213 | | - convert_to_otel_timestamp, |
1214 | | - ) |
| 1215 | + if otel_span is not None: |
| 1216 | + self._otel_span = otel_span |
| 1217 | + else: |
| 1218 | + from sentry_sdk.integrations.opentelemetry.utils import ( |
| 1219 | + convert_to_otel_timestamp, |
| 1220 | + ) |
1215 | 1221 |
|
1216 | | - if start_timestamp is not None: |
1217 | | - # OTel timestamps have nanosecond precision |
1218 | | - start_timestamp = convert_to_otel_timestamp(start_timestamp) |
| 1222 | + if start_timestamp is not None: |
| 1223 | + # OTel timestamps have nanosecond precision |
| 1224 | + start_timestamp = convert_to_otel_timestamp(start_timestamp) |
1219 | 1225 |
|
1220 | | - self._otel_span = tracer.start_span( |
1221 | | - description or op or "", start_time=start_timestamp |
1222 | | - ) |
| 1226 | + self._otel_span = tracer.start_span( |
| 1227 | + description or op or "", start_time=start_timestamp |
| 1228 | + ) |
1223 | 1229 |
|
1224 | | - self.origin = origin or DEFAULT_SPAN_ORIGIN |
1225 | | - self.op = op |
1226 | | - self.description = description |
1227 | | - self.name = name |
1228 | | - if status is not None: |
1229 | | - self.set_status(status) |
| 1230 | + self.origin = origin or DEFAULT_SPAN_ORIGIN |
| 1231 | + self.op = op |
| 1232 | + self.description = description |
| 1233 | + self.name = name |
| 1234 | + if status is not None: |
| 1235 | + self.set_status(status) |
| 1236 | + |
| 1237 | + def __eq__(self, other): |
| 1238 | + # type: (POTelSpan) -> bool |
| 1239 | + return self._otel_span == other._otel_span |
1230 | 1240 |
|
1231 | 1241 | def __repr__(self): |
1232 | 1242 | # type: () -> str |
@@ -1318,17 +1328,16 @@ def containing_transaction(self): |
1318 | 1328 | @property |
1319 | 1329 | def root_span(self): |
1320 | 1330 | # type: () -> Optional[POTelSpan] |
1321 | | - # XXX implement this |
1322 | | - # there's a span.parent property, but it returns the parent spancontext |
1323 | | - # not sure if there's a way to retrieve the parent with pure otel. |
1324 | | - return None |
| 1331 | + root_otel_span = cast( |
| 1332 | + "Optional[OtelSpan]", |
| 1333 | + getattr(self._otel_span, "_sentry_root_otel_span", None), |
| 1334 | + ) |
| 1335 | + return POTelSpan(otel_span=root_otel_span) if root_otel_span else None |
1325 | 1336 |
|
1326 | 1337 | @property |
1327 | 1338 | def is_root_span(self): |
1328 | 1339 | # type: () -> bool |
1329 | | - return ( |
1330 | | - isinstance(self._otel_span, ReadableSpan) and self._otel_span.parent is None |
1331 | | - ) |
| 1340 | + return self.root_span == self |
1332 | 1341 |
|
1333 | 1342 | @property |
1334 | 1343 | def parent_span_id(self): |
|
0 commit comments