8000 Fill out more property/method stubs (#3441) · getsentry/sentry-python@5ccfb34 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5ccfb34

Browse files
authored
Fill out more property/method stubs (#3441)
1 parent 74d62f9 commit 5ccfb34

File tree

2 files changed

+203
-11
lines changed
8000

2 files changed

+203
-11
lines changed

MIGRATION_GUIDE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
1313

1414
### Removed
1515

16+
- When setting span status, the HTTP status code is no longer automatically added as a tag.
17+
1618
### Deprecated
1719

1820
- `sentry_sdk.start_transaction` is deprecated. Use `sentry_sdk.start_span` instead.

sentry_sdk/tracing.py

Lines changed: 201 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
R = TypeVar("R")
3737

3838
import sentry_sdk.profiler
39+
from sentry_sdk.scope import Scope
3940
from sentry_sdk._types import (
4041
Event,
4142
MeasurementUnit,
@@ -1262,6 +1263,9 @@ def __init__(
12621263
active=True, # type: bool
12631264
op=None, # type: Optional[str]
12641265
description=None, # type: Optional[str]
1266+
status=None, # type: Optional[str]
1267+
scope=None, # type: Optional[Scope]
1268+
start_timestamp=None, # type: Optional[Union[datetime, float]]
12651269
origin="manual", # type: str
12661270
**_, # type: dict[str, object]
12671271
):
@@ -1272,15 +1276,41 @@ def __init__(
12721276
listed in the signature. These additional arguments are ignored.
12731277
"""
12741278
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1279+
from sentry_sdk.integrations.opentelemetry.utils import (
1280+
convert_to_otel_timestamp,
1281+
)
1282+
1283+
if start_timestamp is not None:
1284+
# OTel timestamps have nanosecond precision
1285+
start_timestamp = convert_to_otel_timestamp(start_timestamp)
12751286

1276-
self._otel_span = tracer.start_span(description or op or "") # XXX
1287+
# XXX deal with _otel_span being a NonRecordingSpan
1288+
self._otel_span = tracer.start_span(
1289+
description or op or "", start_time=start_timestamp
1290+
) # XXX
12771291
self._active = active
12781292

12791293
self._otel_span.set_attribute(SentrySpanAttribute.ORIGIN, origin)
1280-
if op is not None:
1281-
self._otel_span.set_attribute(SentrySpanAttribute.OP, op)
1282-
if description is not None:
1283-
self._otel_span.set_attribute(SentrySpanAttribute.DESCRIPTION, description)
1294+
self.op = op
1295+
self.description = description
1296+
if status is not None:
1297+
self.set_status(status)
1298+
1299+
def __repr__(self):
1300+
# type: () -> str
1301+
return (
1302+
"<%s(op=%r, description:%r, trace_id=%r, span_id=%r, parent_span_id=%r, sampled=%r, origin=%r)>"
1303+
% (
1304+
self.__class__.__name__,
1305+
self.op,
1306+
self.description,
1307+
self.trace_id,
1308+
self.span_id,
1309+
self.parent_span_id,
1310+
self.sampled,
1311+
self.origin,
1312+
)
1313+
)
12841314

12851315
def __enter__(self):
12861316
# type: () -> POTelSpan
@@ -1301,9 +1331,142 @@ def __exit__(self, ty, value, tb):
13011331
if self._active:
13021332
context.detach(self._ctx_token)
13031333

1334+
@property
1335+
def description(self):
1336+
# type: () -> Optional[str]
1337+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1338+
1339+
return self._otel_span.attributes.get(SentrySpanAttribute.DESCRIPTION)
1340+
1341+
@description.setter
1342+
def description(self, value):
1343+
# type: (Op A3E2 tional[str]) -> None
1344+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1345+
1346+
if value is not None:
1347+
self._otel_span.set_attribute(SentrySpanAttribute.DESCRIPTION, value)
1348+
1349+
@property
1350+
def origin(self):
1351+
# type: () -> Optional[str]
1352+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1353+
1354+
return self._otel_span.attributes.get(SentrySpanAttribute.ORIGIN)
1355+
1356+
@origin.setter
1357+
def origin(self, value):
1358+
# type: (Optional[str]) -> None
1359+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1360+
1361+
if value is not None:
1362+
self._otel_span.set_attribute(SentrySpanAttribute.ORIGIN, value)
1363+
13041364
@property
13051365
def containing_transaction(self):
13061366
# type: () -> Optional[Transaction]
1367+
"""
1368+
Get the transaction this span is a child of.
1369+
1370+
.. deprecated:: 3.0.0
1371+
This will be removed in the future. Use :func:`root_span` instead.
1372+
"""
1373+
logger.warning("Deprecated: This will be removed in the future.")
1374+
return self.root_span
1375+
1376+
@containing_transaction.setter
1377+
def containing_transaction(self, value):
1378+
# type: (Span) -> None
1379+
"""
1380+
Set this span's transaction.
1381+
.. deprecated:: 3.0.0
1382+
Use :func:`root_span` instead.
1383+
"""
1384+
pass
1385+
1386+
@property
1387+
def root_span(self):
1388+
if isinstance(self._otel_span, otel_trace.NonRecordingSpan):
1389+
return None
1390+
1391+
parent = None
1392+
while True:
1393+
# XXX test if this actually works
1394+
if self._otel_span.parent:
1395+
parent = self._otel_span.parent
1396+
else:
1397+
break
1398+
1399+
return parent
1400+
1401+
@root_span.setter
1402+
def root_span(self, value):
1403+
pass
1404+
1405+
@property
1406+
def is_root_span(self):
1407+
if isinstance(self._otel_span, otel_trace.NonRecordingSpan):
1408+
return False
1409+
1410+
return self._otel_span.parent is None
1411+
1412+
@property
1413+
def parent_span_id(self):
1414+
# type: () -> Optional[str]
1415+
return self._otel_span.parent if hasattr(self._otel_span, "parent") else None
1416+
1417+
@property
1418+
def trace_id(self):
1419+
# type: () -> Optional[str]
1420+
return self._otel_span.get_span_context().trace_id
1421+
1422+
@property
1423+
def span_id(self):
1424+
# type: () -> Optional[str]
1425+
return self._otel_span.get_span_context().span_id
1426+
1427+
@property
1428+
def sampled(self):
1429+
# type: () -> Optional[bool]
1430+
return self._otel_span.get_span_context().trace_flags.sampled
1431+
1432+
@sampled.setter
1433+
def sampled(self, value):
1434+
# type: () -> Optional[bool]
1435+
pass
1436+
1437+
@property
1438+
def op(self):
1439+
# type: () -> Optional[str]
1440+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1441+
1442+
self._otel_span.attributes.get(SentrySpanAttribute.OP)
1443+
1444+
@op.setter
1445+
def op(self, value):
1446+
# type: (Optional[str]) -> None
1447+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1448+
1449+
if value is not None:
1450+
self._otel_span.set_attribute(SentrySpanAttribute.OP, value)
1451+
1452+
@property
1453+
def name(self):
1454+
# type: () -> str
1455+
pass
1456+
1457+
@name.setter
1458+
def name(self, value):
1459+
# type: (str) -> None
1460+
pass
1461+
1462+
@property
1463+
def source(self):
1464+
# type: () -> str
1465+
pass
1466+
1467+
@source.setter
1468+
def source(self, value):
1469+
# type: (str) -> None
13071470
pass
13081471

13091472
def start_child(self, **kwargs):
@@ -1352,7 +1515,18 @@ def from_traceparent(
13521515

13531516
def to_traceparent(self):
13541517
# type: () -> str
1355-
pass
1518+
if self.sampled is True:
1519+
sampled = "1"
1520+
elif self.sampled is False:
1521+
sampled = "0"
1522+
else:
1523+
sampled = None
1524+
1525+
traceparent = "%s-%s" % (self.trace_id, self.span_id)
1526+
if sampled is not None:
1527+
traceparent += "-%s" % (sampled,)
1528+
1529+
return traceparent
13561530

13571531
def to_baggage(self):
13581532
# type: () -> Optional[Baggage]
@@ -1368,23 +1542,39 @@ def set_data(self, key, value):
13681542

13691543
def set_status(self, status):
13701544
# type: (str) -> None
1371-
pass
1545+
if status == SPANSTATUS.OK:
1546+
otel_status = StatusCode.OK
1547+
otel_description = None
1548+
else:
1549+
otel_status = StatusCode.ERROR
1550+
otel_description = status.value
1551+
1552+
self._otel_span.set_status(otel_status, otel_description)
13721553

13731554
def set_measurement(self, name, value, unit=""):
13741555
# type: (str, float, MeasurementUnit) -> None
1375-
pass
1556+
# XXX own namespace, e.g. sentry.measurement.xxx, so that we can group
1557+
# these back together in the processor?
1558+
# XXX otel throws a warning about value, unit being different types
1559+
self._otel_span.set_attribute(name, (value, unit))
13761560

13771561
def set_thread(self, thread_id, thread_name):
13781562
# type: (Optional[int], Optional[str]) -> None
1379-
pass
1563+
if thread_id is not None:
1564+
self.set_data(SPANDATA.THREAD_ID, str(thread_id))
1565+
1566+
if thread_name is not None:
1567+
self.set_data(SPANDATA.THREAD_NAME, thread_name)
13801568

13811569
def set_profiler_id(self, profiler_id):
13821570
# type: (Optional[str]) -> None
1383-
pass
1571+
if profiler_id is not None:
1572+
self.set_data(SPANDATA.PROFILER_ID, profiler_id)
13841573

13851574
def set_http_status(self, http_status):
13861575
# type: (int) -> None
1387-
pass
1576+
self.set_data(SPANDATA.HTTP_STATUS_CODE, http_status)
1577+
self.set_status(get_span_status_from_http_code(http_status))
13881578

13891579
def is_success(self):
13901580
# type: () -> bool

0 commit comments

Comments
 (0)
0