Skip to content

Commit d4b1d00

Browse files
authored
Merge branch 'master' into potel-base
2 parents de1b0e3 + b7fd54a commit d4b1d00

20 files changed

+419
-73
lines changed

sentry_sdk/_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
"profile_chunk",
156156
"metric_bucket",
157157
"monitor",
158+
"span",
158159
]
159160
SessionStatus = Literal["ok", "exited", "crashed", "abnormal"]
160161

sentry_sdk/client.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ def _prepare_event(
448448

449449
if scope is not None:
450450
is_transaction = event.get("type") == "transaction"
451+
spans_before = len(event.get("spans", []))
451452
event_ = scope.apply_to_event(event, hint, self.options)
452453

453454
# one of the event/error processors returned None
@@ -457,10 +458,22 @@ def _prepare_event(
457458
"event_processor",
458459
data_category=("transaction" if is_transaction else "error"),
459460
)
461+
if is_transaction:
462+
self.transport.record_lost_event(
463+
"event_processor",
464+
data_category="span",
465+
quantity=spans_before + 1, # +1 for the transaction itself
466+
)
460467
return None
461468

462469
event = event_
463470

471+
spans_delta = spans_before - len(event.get("spans", []))
472+
if is_transaction and spans_delta > 0 and self.transport is not None:
473+
self.transport.record_lost_event(
474+
"event_processor", data_category="span", quantity=spans_delta
475+
)
476+
464477
if (
465478
self.options["attach_stacktrace"]
466479
and "exception" not in event
@@ -541,14 +554,27 @@ def _prepare_event(
541554
and event.get("type") == "transaction"
542555
):
543556
new_event = None
557+
spans_before = len(event.get("spans", []))
544558
with capture_internal_exceptions():
545559
new_event = before_send_transaction(event, hint or {})
546560
if new_event is None:
547561
logger.info("before send transaction dropped event")
548562
if self.transport:
549563
self.transport.record_lost_event(
550-
"before_send", data_category="transaction"
564+
reason="before_send", data_category="transaction"
565+
)
566+
self.transport.record_lost_event(
567+
reason="before_send",
568+
data_category="span",
569+
quantity=spans_before + 1, # +1 for the transaction itself
551570
)
571+
else:
572+
spans_delta = spans_before - len(new_event.get("spans", []))
573+
if spans_delta > 0 and self.transport is not None:
574+
self.transport.record_lost_event(
575+
reason="before_send", data_category="span", quantity=spans_delta
576+
)
577+
552578
event = new_event # type: ignore
553579

554580
return event

sentry_sdk/consts.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,32 @@ class SPANDATA:
386386
"""
387387

388388

389+
class SPANSTATUS:
390+
"""
391+
The status of a Sentry span.
392+
393+
See: https://develop.sentry.dev/sdk/event-payloads/contexts/#trace-context
394+
"""
395+
396+
ABORTED = "aborted"
397+
ALREADY_EXISTS = "already_exists"
398+
CANCELLED = "cancelled"
399+
DATA_LOSS = "data_loss"
400+
DEADLINE_EXCEEDED = "deadline_exceeded"
401+
FAILED_PRECONDITION = "failed_precondition"
402+
INTERNAL_ERROR = "internal_error"
403+
INVALID_ARGUMENT = "invalid_argument"
404+
NOT_FOUND = "not_found"
405+
OK = "ok"
406+
OUT_OF_RANGE = "out_of_range"
407+
PERMISSION_DENIED = "permission_denied"
408+
RESOURCE_EXHAUSTED = "resource_exhausted"
409+
UNAUTHENTICATED = "unauthenticated"
410+
UNAVAILABLE = "unavailable"
411+
UNIMPLEMENTED = "unimplemented"
412+
UNKNOWN_ERROR = "unknown_error"
413+
414+
389415
class OP:
390416
ANTHROPIC_MESSAGES_CREATE = "ai.messages.create.anthropic"
391417
CACHE_GET = "cache.get"

sentry_sdk/integrations/aiohttp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import sentry_sdk
55
from sentry_sdk.api import continue_trace
6-
from sentry_sdk.consts import OP, SPANDATA
6+
from sentry_sdk.consts import OP, SPANSTATUS, SPANDATA
77
from sentry_sdk.integrations import Integration, DidNotEnable
88
from sentry_sdk.integrations.logging import ignore_logger
99
from sentry_sdk.scope import Scope
@@ -133,7 +133,7 @@ async def sentry_app_handle(self, request, *args, **kwargs):
133133
transaction.set_http_status(e.status_code)
134134
raise
135135
except (asyncio.CancelledError, ConnectionResetError):
136-
transaction.set_status("cancelled")
136+
transaction.set_status(SPANSTATUS.CANCELLED)
137137
raise
138138
except Exception:
139139
# This will probably map to a 500 but seems like we

sentry_sdk/integrations/arq.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import sentry_sdk
44
from sentry_sdk._types import TYPE_CHECKING
5-
from sentry_sdk.consts import OP
5+
from sentry_sdk.consts import OP, SPANSTATUS
66
from sentry_sdk.integrations import DidNotEnable, Integration
77
from sentry_sdk.integrations.logging import ignore_logger
88
from sentry_sdk.scope import Scope, should_send_default_pii
@@ -119,10 +119,10 @@ def _capture_exception(exc_info):
119119

120120
if scope.transaction is not None:
121121
if exc_info[0] in ARQ_CONTROL_FLOW_EXCEPTIONS:
122-
scope.transaction.set_status("aborted")
122+
scope.transaction.set_status(SPANSTATUS.ABORTED)
123123
return
124124

125-
scope.transaction.set_status("internal_error")
125+
scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
126126

127127
event, hint = event_from_exception(
128128
exc_info,

sentry_sdk/integrations/celery/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sentry_sdk
66
from sentry_sdk import isolation_scope
77
from sentry_sdk.api import continue_trace
8-
from sentry_sdk.consts import OP, SPANDATA
8+
from sentry_sdk.consts import OP, SPANSTATUS, SPANDATA
99
from sentry_sdk.integrations import Integration, DidNotEnable
1010
from sentry_sdk.integrations.celery.beat import (
1111
_patch_beat_apply_entry,
@@ -317,7 +317,7 @@ def _inner(*args, **kwargs):
317317
origin=CeleryIntegration.origin,
318318
)
319319
transaction.name = task.name
320-
transaction.set_status("ok")
320+
transaction.set_status(SPANSTATUS.OK)
321321

322322
if transaction is None:
323323
return f(*args, **kwargs)

sentry_sdk/integrations/huey.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import sentry_sdk
55
from sentry_sdk._types import TYPE_CHECKING
66
from sentry_sdk.api import continue_trace, get_baggage, get_traceparent
7-
from sentry_sdk.consts import OP
7+
from sentry_sdk.consts import OP, SPANSTATUS
88
from sentry_sdk.integrations import DidNotEnable, Integration
99
from sentry_sdk.scope import Scope, should_send_default_pii
1010
from sentry_sdk.tracing import (
@@ -109,10 +109,10 @@ def _capture_exception(exc_info):
109109
scope = Scope.get_current_scope()
110110

111111
if exc_info[0] in HUEY_CONTROL_FLOW_EXCEPTIONS:
112-
scope.transaction.set_status("aborted")
112+
scope.transaction.set_status(SPANSTATUS.ABORTED)
113113
return
114114

115-
scope.transaction.set_status("internal_error")
115+
scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
116116
event, hint = event_from_exception(
117117
exc_info,
118118
client_options=Scope.get_client().options,
@@ -161,7 +161,7 @@ def _sentry_execute(self, task, timestamp=None):
161161
source=TRANSACTION_SOURCE_TASK,
162162
origin=HueyIntegration.origin,
163163
)
164-
transaction.set_status("ok")
164+
transaction.set_status(SPANSTATUS.OK)
165165

166166
if not getattr(task, "_sentry_is_patched", False):
167167
task.execute = _wrap_task_execute(task.execute)

sentry_sdk/integrations/opentelemetry/span_processor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
INVALID_TRACE_ID,
1515
)
1616
from sentry_sdk import get_client, start_transaction
17-
from sentry_sdk.consts import INSTRUMENTER
17+
from sentry_sdk.consts import INSTRUMENTER, SPANSTATUS
1818
from sentry_sdk.integrations.opentelemetry.consts import (
1919
SENTRY_BAGGAGE_KEY,
2020
SENTRY_TRACE_KEY,
@@ -273,10 +273,10 @@ def _update_span_with_otel_status(self, sentry_span, otel_span):
273273
return
274274

275275
if otel_span.status.is_ok:
276-
sentry_span.set_status("ok")
276+
sentry_span.set_status(SPANSTATUS.OK)
277277
return
278278

279-
sentry_span.set_status("internal_error")
279+
sentry_span.set_status(SPANSTATUS.INTERNAL_ERROR)
280280

281281
def _update_span_with_otel_data(self, sentry_span, otel_span):
282282
# type: (SentrySpan, OTelSpan) -> None

sentry_sdk/integrations/pymongo.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import copy
22

33
import sentry_sdk
4-
from sentry_sdk.consts import SPANDATA, OP
4+
from sentry_sdk.consts import SPANSTATUS, SPANDATA, OP
55
from sentry_sdk.integrations import DidNotEnable, Integration
66
from sentry_sdk.scope import should_send_default_pii
77
from sentry_sdk.tracing import Span
@@ -181,7 +181,7 @@ def failed(self, event):
181181

182182
try:
183183
span = self._ongoing_operations.pop(self._operation_key(event))
184-
span.set_status("internal_error")
184+
span.set_status(SPANSTATUS.INTERNAL_ERROR)
185185
span.__exit__(None, None, None)
186186
except KeyError:
187187
return
@@ -193,7 +193,7 @@ def succeeded(self, event):
193193

194194
try:
195195
span = self._ongoing_operations.pop(self._operation_key(event))
196-
span.set_status("ok")
196+
span.set_status(SPANSTATUS.OK)
197197
span.__exit__(None, None, None)
198198
except KeyError:
199199
pass

sentry_sdk/integrations/sqlalchemy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import sentry_sdk
22
from sentry_sdk._types import TYPE_CHECKING
3-
from sentry_sdk.consts import SPANDATA
3+
from sentry_sdk.consts import SPANSTATUS, SPANDATA
44
from sentry_sdk.db.explain_plan.sqlalchemy import attach_explain_plan_to_span
55
from sentry_sdk.integrations import Integration, DidNotEnable
66
from sentry_sdk.tracing_utils import add_query_source, record_sql_queries
@@ -107,7 +107,7 @@ def _handle_error(context, *args):
107107
span = getattr(execution_context, "_sentry_sql_span", None) # type: Optional[Span]
108108

109109
if span is not None:
110-
span.set_status("internal_error")
110+
span.set_status(SPANSTATUS.INTERNAL_ERROR)
111111

112112
# _after_cursor_execute does not get called for crashing SQL stmts. Judging
113113
# from SQLAlchemy codebase it does seem like any error coming into this

0 commit comments

Comments
 (0)