|
3 | 3 | from datetime import datetime, timedelta, timezone
|
4 | 4 |
|
5 | 5 | import sentry_sdk
|
6 |
| -from sentry_sdk.consts import INSTRUMENTER, SPANDATA |
| 6 | +from sentry_sdk.consts import INSTRUMENTER, SPANSTATUS, SPANDATA |
7 | 7 | from sentry_sdk.profiler.continuous_profiler import get_profiler_id
|
8 | 8 | from sentry_sdk.utils import (
|
9 | 9 | get_current_thread_meta,
|
@@ -119,11 +119,9 @@ class TransactionKwargs(SpanKwargs, total=False):
|
119 | 119 | },
|
120 | 120 | )
|
121 | 121 |
|
122 |
| - |
123 | 122 | BAGGAGE_HEADER_NAME = "baggage"
|
124 | 123 | SENTRY_TRACE_HEADER_NAME = "sentry-trace"
|
125 | 124 |
|
126 |
| - |
127 | 125 | # Transaction source
|
128 | 126 | # see https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations
|
129 | 127 | TRANSACTION_SOURCE_CUSTOM = "custom"
|
@@ -151,6 +149,45 @@ class TransactionKwargs(SpanKwargs, total=False):
|
151 | 149 | }
|
152 | 150 |
|
153 | 151 |
|
| 152 | +def get_span_status_from_http_code(http_status_code): |
| 153 | + # type: (int) -> str |
| 154 | + """ |
| 155 | + Returns the Sentry status corresponding to the given HTTP status code. |
| 156 | +
|
| 157 | + See: https://develop.sentry.dev/sdk/event-payloads/contexts/#trace-context |
| 158 | + """ |
| 159 | + if http_status_code < 400: |
| 160 | + return SPANSTATUS.OK |
| 161 | + |
| 162 | + elif 400 <= http_status_code < 500: |
| 163 | + if http_status_code == 403: |
| 164 | + return SPANSTATUS.PERMISSION_DENIED |
| 165 | + elif http_status_code == 404: |
| 166 | + return SPANSTATUS.NOT_FOUND |
| 167 | + elif http_status_code == 429: |
| 168 | + return SPANSTATUS.RESOURCE_EXHAUSTED |
| 169 | + elif http_status_code == 413: |
| 170 | + return SPANSTATUS.FAILED_PRECONDITION |
| 171 | + elif http_status_code == 401: |
| 172 | + return SPANSTATUS.UNAUTHENTICATED |
| 173 | + elif http_status_code == 409: |
| 174 | + return SPANSTATUS.ALREADY_EXISTS |
| 175 | + else: |
| 176 | + return SPANSTATUS.INVALID_ARGUMENT |
| 177 | + |
| 178 | + elif 500 <= http_status_code < 600: |
| 179 | + if http_status_code == 504: |
| 180 | + return SPANSTATUS.DEADLINE_EXCEEDED |
| 181 | + elif http_status_code == 501: |
| 182 | + return SPANSTATUS.UNIMPLEMENTED |
| 183 | + elif http_status_code == 503: |
| 184 | + return SPANSTATUS.UNAVAILABLE |
| 185 | + else: |
| 186 | + return SPANSTATUS.INTERNAL_ERROR |
| 187 | + |
| 188 | + return SPANSTATUS.UNKNOWN_ERROR |
| 189 | + |
| 190 | + |
154 | 191 | class _SpanRecorder:
|
155 | 192 | """Limits the number of spans recorded in a transaction."""
|
156 | 193 |
|
@@ -319,7 +356,7 @@ def __enter__(self):
|
319 | 356 | def __exit__(self, ty, value, tb):
|
320 | 357 | # type: (Optional[Any], Optional[Any], Optional[Any]) -> None
|
321 | 358 | if value is not None:
|
322 |
| - self.set_status("internal_error") |
| 359 | + self.set_status(SPANSTATUS.INTERNAL_ERROR) |
323 | 360 |
|
324 | 361 | scope, old_span = self._context_manager_state
|
325 | 362 | del self._context_manager_state
|
@@ -542,37 +579,9 @@ def set_http_status(self, http_status):
|
542 | 579 | # type: (int) -> None
|
543 | 580 | self.set_tag(
|
544 | 581 | "http.status_code", str(http_status)
|
545 |
| - ) # we keep this for backwards compatability |
| 582 | + ) # we keep this for backwards compatibility |
546 | 583 | self.set_data(SPANDATA.HTTP_STATUS_CODE, http_status)
|
547 |
| - |
548 |
| - if http_status < 400: |
549 |
| - self.set_status("ok") |
550 |
| - elif 400 <= http_status < 500: |
551 |
| - if http_status == 403: |
552 |
| - self.set_status("permission_denied") |
553 |
| - elif http_status == 404: |
554 |
| - self.set_status("not_found") |
555 |
| - elif http_status == 429: |
556 |
| - self.set_status("resource_exhausted") |
557 |
| - elif http_status == 413: |
558 |
| - self.set_status("failed_precondition") |
559 |
| - elif http_status == 401: |
560 |
| - self.set_status("unauthenticated") |
561 |
| - elif http_status == 409: |
562 |
| - self.set_status("already_exists") |
563 |
| - else: |
564 |
| - self.set_status("invalid_argument") |
565 |
| - elif 500 <= http_status < 600: |
566 |
| - if http_status == 504: |
567 |
| - self.set_status("deadline_exceeded") |
568 |
| - elif http_status == 501: |
569 |
| - self.set_status("unimplemented") |
570 |
| - elif http_status == 503: |
571 |
| - self.set_status("unavailable") |
572 |
| - else: |
573 |
| - self.set_status("internal_error") |
574 |
| - else: |
575 |
| - self.set_status("unknown_error") |
| 584 | + self.set_status(get_span_status_from_http_code(http_status)) |
576 | 585 |
|
577 | 586 | def is_success(self):
|
578 | 587 | # type: () -> bool
|
@@ -858,6 +867,8 @@ def finish(self, hub=None, end_timestamp=None):
|
858 | 867 |
|
859 | 868 | client.transport.record_lost_event(reason, data_category="transaction")
|
860 | 869 |
|
| 870 | + # Only one span (the transaction itself) is discarded, since we did not record any spans here. |
| 871 | + client.transport.record_lost_event(reason, data_category="span") |
861 | 872 | return None
|
862 | 873 |
|
863 | 874 | if not self.name:
|
|
0 commit comments