sentry-sdk 2.30.0__py2.py3-none-any.whl → 3.0.0a2__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sentry-sdk might be problematic. Click here for more details.
- sentry_sdk/__init__.py +3 -8
- sentry_sdk/_compat.py +0 -1
- sentry_sdk/_init_implementation.py +6 -44
- sentry_sdk/_types.py +2 -64
- sentry_sdk/ai/monitoring.py +14 -10
- sentry_sdk/ai/utils.py +1 -1
- sentry_sdk/api.py +56 -169
- sentry_sdk/client.py +27 -72
- sentry_sdk/consts.py +60 -23
- sentry_sdk/debug.py +0 -10
- sentry_sdk/envelope.py +1 -3
- sentry_sdk/feature_flags.py +1 -1
- sentry_sdk/integrations/__init__.py +4 -2
- sentry_sdk/integrations/_asgi_common.py +5 -6
- sentry_sdk/integrations/_wsgi_common.py +11 -40
- sentry_sdk/integrations/aiohttp.py +104 -57
- sentry_sdk/integrations/anthropic.py +10 -7
- sentry_sdk/integrations/arq.py +24 -13
- sentry_sdk/integrations/asgi.py +102 -83
- sentry_sdk/integrations/asyncio.py +1 -0
- sentry_sdk/integrations/asyncpg.py +45 -30
- sentry_sdk/integrations/aws_lambda.py +109 -92
- sentry_sdk/integrations/boto3.py +38 -9
- sentry_sdk/integrations/bottle.py +1 -1
- sentry_sdk/integrations/celery/__init__.py +51 -41
- sentry_sdk/integrations/clickhouse_driver.py +59 -28
- sentry_sdk/integrations/cohere.py +2 -0
- sentry_sdk/integrations/django/__init__.py +25 -46
- sentry_sdk/integrations/django/asgi.py +6 -2
- sentry_sdk/integrations/django/caching.py +13 -22
- sentry_sdk/integrations/django/middleware.py +1 -0
- sentry_sdk/integrations/django/signals_handlers.py +3 -1
- sentry_sdk/integrations/django/templates.py +8 -12
- sentry_sdk/integrations/django/transactions.py +1 -6
- sentry_sdk/integrations/django/views.py +5 -2
- sentry_sdk/integrations/falcon.py +7 -25
- sentry_sdk/integrations/fastapi.py +3 -3
- sentry_sdk/integrations/flask.py +1 -1
- sentry_sdk/integrations/gcp.py +63 -38
- sentry_sdk/integrations/graphene.py +6 -13
- sentry_sdk/integrations/grpc/aio/client.py +14 -8
- sentry_sdk/integrations/grpc/aio/server.py +19 -21
- sentry_sdk/integrations/grpc/client.py +8 -6
- sentry_sdk/integrations/grpc/server.py +12 -14
- sentry_sdk/integrations/httpx.py +47 -12
- sentry_sdk/integrations/huey.py +26 -22
- sentry_sdk/integrations/huggingface_hub.py +1 -0
- sentry_sdk/integrations/langchain.py +22 -15
- sentry_sdk/integrations/litestar.py +4 -2
- sentry_sdk/integrations/logging.py +7 -2
- sentry_sdk/integrations/openai.py +2 -0
- sentry_sdk/integrations/pymongo.py +18 -25
- sentry_sdk/integrations/pyramid.py +1 -1
- sentry_sdk/integrations/quart.py +3 -3
- sentry_sdk/integrations/ray.py +23 -17
- sentry_sdk/integrations/redis/_async_common.py +29 -18
- sentry_sdk/integrations/redis/_sync_common.py +28 -19
- sentry_sdk/integrations/redis/modules/caches.py +13 -10
- sentry_sdk/integrations/redis/modules/queries.py +14 -11
- sentry_sdk/integrations/redis/rb.py +4 -4
- sentry_sdk/integrations/redis/redis.py +6 -6
- sentry_sdk/integrations/redis/redis_cluster.py +18 -18
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +4 -4
- sentry_sdk/integrations/redis/utils.py +64 -24
- sentry_sdk/integrations/rq.py +68 -23
- sentry_sdk/integrations/rust_tracing.py +28 -43
- sentry_sdk/integrations/sanic.py +23 -13
- sentry_sdk/integrations/socket.py +9 -5
- sentry_sdk/integrations/sqlalchemy.py +8 -8
- sentry_sdk/integrations/starlette.py +11 -31
- sentry_sdk/integrations/starlite.py +4 -2
- sentry_sdk/integrations/stdlib.py +56 -9
- sentry_sdk/integrations/strawberry.py +40 -59
- sentry_sdk/integrations/threading.py +10 -26
- sentry_sdk/integrations/tornado.py +57 -18
- sentry_sdk/integrations/trytond.py +4 -1
- sentry_sdk/integrations/wsgi.py +84 -38
- sentry_sdk/opentelemetry/__init__.py +9 -0
- sentry_sdk/opentelemetry/consts.py +33 -0
- sentry_sdk/opentelemetry/contextvars_context.py +81 -0
- sentry_sdk/{integrations/opentelemetry → opentelemetry}/propagator.py +19 -28
- sentry_sdk/opentelemetry/sampler.py +326 -0
- sentry_sdk/opentelemetry/scope.py +218 -0
- sentry_sdk/opentelemetry/span_processor.py +335 -0
- sentry_sdk/opentelemetry/tracing.py +59 -0
- sentry_sdk/opentelemetry/utils.py +484 -0
- sentry_sdk/profiler/__init__.py +0 -40
- sentry_sdk/profiler/continuous_profiler.py +1 -30
- sentry_sdk/profiler/transaction_profiler.py +5 -56
- sentry_sdk/scope.py +108 -361
- sentry_sdk/sessions.py +0 -87
- sentry_sdk/tracing.py +415 -1161
- sentry_sdk/tracing_utils.py +130 -166
- sentry_sdk/transport.py +4 -104
- sentry_sdk/utils.py +169 -152
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/METADATA +3 -5
- sentry_sdk-3.0.0a2.dist-info/RECORD +154 -0
- sentry_sdk-3.0.0a2.dist-info/entry_points.txt +2 -0
- sentry_sdk/hub.py +0 -739
- sentry_sdk/integrations/opentelemetry/__init__.py +0 -7
- sentry_sdk/integrations/opentelemetry/consts.py +0 -5
- sentry_sdk/integrations/opentelemetry/integration.py +0 -58
- sentry_sdk/integrations/opentelemetry/span_processor.py +0 -391
- sentry_sdk/metrics.py +0 -965
- sentry_sdk-2.30.0.dist-info/RECORD +0 -152
- sentry_sdk-2.30.0.dist-info/entry_points.txt +0 -2
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/WHEEL +0 -0
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-2.30.0.dist-info → sentry_sdk-3.0.0a2.dist-info}/top_level.txt +0 -0
|
@@ -50,6 +50,7 @@ def patch_signals():
|
|
|
50
50
|
|
|
51
51
|
old_live_receivers = Signal._live_receivers
|
|
52
52
|
|
|
53
|
+
@wraps(old_live_receivers)
|
|
53
54
|
def _sentry_live_receivers(self, sender):
|
|
54
55
|
# type: (Signal, Any) -> Union[tuple[list[Callable[..., Any]], list[Callable[..., Any]]], list[Callable[..., Any]]]
|
|
55
56
|
if DJANGO_VERSION >= (5, 0):
|
|
@@ -68,8 +69,9 @@ def patch_signals():
|
|
|
68
69
|
op=OP.EVENT_DJANGO,
|
|
69
70
|
name=signal_name,
|
|
70
71
|
origin=DjangoIntegration.origin,
|
|
72
|
+
only_if_parent=True,
|
|
71
73
|
) as span:
|
|
72
|
-
span.
|
|
74
|
+
span.set_attribute("signal", signal_name)
|
|
73
75
|
return receiver(*args, **kwargs)
|
|
74
76
|
|
|
75
77
|
return wrapper
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
|
|
3
3
|
from django.template import TemplateSyntaxError
|
|
4
|
+
from django.template.base import Origin
|
|
4
5
|
from django.utils.safestring import mark_safe
|
|
5
|
-
from django import VERSION as DJANGO_VERSION
|
|
6
6
|
|
|
7
7
|
import sentry_sdk
|
|
8
8
|
from sentry_sdk.consts import OP
|
|
@@ -17,13 +17,6 @@ if TYPE_CHECKING:
|
|
|
17
17
|
from typing import Iterator
|
|
18
18
|
from typing import Tuple
|
|
19
19
|
|
|
20
|
-
try:
|
|
21
|
-
# support Django 1.9
|
|
22
|
-
from django.template.base import Origin
|
|
23
|
-
except ImportError:
|
|
24
|
-
# backward compatibility
|
|
25
|
-
from django.template.loader import LoaderOrigin as Origin
|
|
26
|
-
|
|
27
20
|
|
|
28
21
|
def get_template_frame_from_exception(exc_value):
|
|
29
22
|
# type: (Optional[BaseException]) -> Optional[Dict[str, Any]]
|
|
@@ -72,14 +65,15 @@ def patch_templates():
|
|
|
72
65
|
op=OP.TEMPLATE_RENDER,
|
|
73
66
|
name=_get_template_name_description(self.template_name),
|
|
74
67
|
origin=DjangoIntegration.origin,
|
|
68
|
+
only_if_parent=True,
|
|
75
69
|
) as span:
|
|
76
|
-
|
|
70
|
+
if isinstance(self.context_data, dict):
|
|
71
|
+
for k, v in self.context_data.items():
|
|
72
|
+
span.set_attribute(f"context.{k}", v)
|
|
77
73
|
return real_rendered_content.fget(self)
|
|
78
74
|
|
|
79
75
|
SimpleTemplateResponse.rendered_content = rendered_content
|
|
80
76
|
|
|
81
|
-
if DJANGO_VERSION < (1, 7):
|
|
82
|
-
return
|
|
83
77
|
import django.shortcuts
|
|
84
78
|
|
|
85
79
|
real_render = django.shortcuts.render
|
|
@@ -100,8 +94,10 @@ def patch_templates():
|
|
|
100
94
|
op=OP.TEMPLATE_RENDER,
|
|
101
95
|
name=_get_template_name_description(template_name),
|
|
102
96
|
origin=DjangoIntegration.origin,
|
|
97
|
+
only_if_parent=True,
|
|
103
98
|
) as span:
|
|
104
|
-
|
|
99
|
+
for k, v in context.items():
|
|
100
|
+
span.set_attribute(f"context.{k}", v)
|
|
105
101
|
return real_render(request, template_name, context, *args, **kwargs)
|
|
106
102
|
|
|
107
103
|
django.shortcuts.render = render
|
|
@@ -19,12 +19,7 @@ if TYPE_CHECKING:
|
|
|
19
19
|
from typing import Union
|
|
20
20
|
from re import Pattern
|
|
21
21
|
|
|
22
|
-
from django import
|
|
23
|
-
|
|
24
|
-
if DJANGO_VERSION >= (2, 0):
|
|
25
|
-
from django.urls.resolvers import RoutePattern
|
|
26
|
-
else:
|
|
27
|
-
RoutePattern = None
|
|
22
|
+
from django.urls.resolvers import RoutePattern
|
|
28
23
|
|
|
29
24
|
try:
|
|
30
25
|
from django.urls import get_resolver
|
|
@@ -31,12 +31,14 @@ def patch_views():
|
|
|
31
31
|
old_make_view_atomic = BaseHandler.make_view_atomic
|
|
32
32
|
old_render = SimpleTemplateResponse.render
|
|
33
33
|
|
|
34
|
+
@functools.wraps(old_render)
|
|
34
35
|
def sentry_patched_render(self):
|
|
35
36
|
# type: (SimpleTemplateResponse) -> Any
|
|
36
37
|
with sentry_sdk.start_span(
|
|
37
38
|
op=OP.VIEW_RESPONSE_RENDER,
|
|
38
39
|
name="serialize response",
|
|
39
40
|
origin=DjangoIntegration.origin,
|
|
41
|
+
only_if_parent=True,
|
|
40
42
|
):
|
|
41
43
|
return old_render(self)
|
|
42
44
|
|
|
@@ -77,8 +79,8 @@ def _wrap_sync_view(callback):
|
|
|
77
79
|
def sentry_wrapped_callback(request, *args, **kwargs):
|
|
78
80
|
# type: (Any, *Any, **Any) -> Any
|
|
79
81
|
current_scope = sentry_sdk.get_current_scope()
|
|
80
|
-
if current_scope.
|
|
81
|
-
current_scope.
|
|
82
|
+
if current_scope.root_span is not None:
|
|
83
|
+
current_scope.root_span.update_active_thread()
|
|
82
84
|
|
|
83
85
|
sentry_scope = sentry_sdk.get_isolation_scope()
|
|
84
86
|
# set the active thread id to the handler thread for sync views
|
|
@@ -90,6 +92,7 @@ def _wrap_sync_view(callback):
|
|
|
90
92
|
op=OP.VIEW_RENDER,
|
|
91
93
|
name=request.resolver_match.view_name,
|
|
92
94
|
origin=DjangoIntegration.origin,
|
|
95
|
+
only_if_parent=True,
|
|
93
96
|
):
|
|
94
97
|
return callback(request, *args, **kwargs)
|
|
95
98
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import sentry_sdk
|
|
2
|
+
from sentry_sdk.consts import SOURCE_FOR_STYLE
|
|
2
3
|
from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable
|
|
3
4
|
from sentry_sdk.integrations._wsgi_common import RequestExtractor
|
|
4
5
|
from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
|
|
5
|
-
from sentry_sdk.tracing import SOURCE_FOR_STYLE
|
|
6
6
|
from sentry_sdk.utils import (
|
|
7
7
|
capture_internal_exceptions,
|
|
8
8
|
ensure_integration_enabled,
|
|
@@ -19,8 +19,6 @@ if TYPE_CHECKING:
|
|
|
19
19
|
|
|
20
20
|
from sentry_sdk._types import Event, EventProcessor
|
|
21
21
|
|
|
22
|
-
# In Falcon 3.0 `falcon.api_helpers` is renamed to `falcon.app_helpers`
|
|
23
|
-
# and `falcon.API` to `falcon.App`
|
|
24
22
|
|
|
25
23
|
try:
|
|
26
24
|
import falcon # type: ignore
|
|
@@ -29,24 +27,15 @@ try:
|
|
|
29
27
|
except ImportError:
|
|
30
28
|
raise DidNotEnable("Falcon not installed")
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
import falcon.app_helpers # type: ignore
|
|
34
|
-
|
|
35
|
-
falcon_helpers = falcon.app_helpers
|
|
36
|
-
falcon_app_class = falcon.App
|
|
37
|
-
FALCON3 = True
|
|
38
|
-
except ImportError:
|
|
39
|
-
import falcon.api_helpers # type: ignore
|
|
30
|
+
import falcon.app_helpers # type: ignore
|
|
40
31
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
FALCON3 = False
|
|
32
|
+
falcon_helpers = falcon.app_helpers
|
|
33
|
+
falcon_app_class = falcon.App
|
|
44
34
|
|
|
45
35
|
|
|
46
36
|
_FALCON_UNSET = None # type: Optional[object]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
from falcon.request import _UNSET as _FALCON_UNSET # type: ignore[import-not-found, no-redef]
|
|
37
|
+
with capture_internal_exceptions():
|
|
38
|
+
from falcon.request import _UNSET as _FALCON_UNSET # type: ignore[import-not-found, no-redef]
|
|
50
39
|
|
|
51
40
|
|
|
52
41
|
class FalconRequestExtractor(RequestExtractor):
|
|
@@ -232,14 +221,7 @@ def _exception_leads_to_http_5xx(ex, response):
|
|
|
232
221
|
ex, (falcon.HTTPError, falcon.http_status.HTTPStatus)
|
|
233
222
|
)
|
|
234
223
|
|
|
235
|
-
|
|
236
|
-
# at the stage where we capture it is listed as 200, even though we would expect to see a 500
|
|
237
|
-
# status. Since at the time of this change, Falcon 2 is ca. 4 years old, we have decided to
|
|
238
|
-
# only perform this check on Falcon 3+, despite the risk that some handled errors might be
|
|
239
|
-
# reported to Sentry as unhandled on Falcon 2.
|
|
240
|
-
return (is_server_error or is_unhandled_error) and (
|
|
241
|
-
not FALCON3 or _has_http_5xx_status(response)
|
|
242
|
-
)
|
|
224
|
+
return (is_server_error or is_unhandled_error) and _has_http_5xx_status(response)
|
|
243
225
|
|
|
244
226
|
|
|
245
227
|
def _has_http_5xx_status(response):
|
|
@@ -3,9 +3,9 @@ from copy import deepcopy
|
|
|
3
3
|
from functools import wraps
|
|
4
4
|
|
|
5
5
|
import sentry_sdk
|
|
6
|
+
from sentry_sdk.consts import SOURCE_FOR_STYLE, TransactionSource
|
|
6
7
|
from sentry_sdk.integrations import DidNotEnable
|
|
7
8
|
from sentry_sdk.scope import should_send_default_pii
|
|
8
|
-
from sentry_sdk.tracing import SOURCE_FOR_STYLE, TransactionSource
|
|
9
9
|
from sentry_sdk.utils import (
|
|
10
10
|
transaction_from_function,
|
|
11
11
|
logger,
|
|
@@ -89,8 +89,8 @@ def patch_get_request_handler():
|
|
|
89
89
|
def _sentry_call(*args, **kwargs):
|
|
90
90
|
# type: (*Any, **Any) -> Any
|
|
91
91
|
current_scope = sentry_sdk.get_current_scope()
|
|
92
|
-
if current_scope.
|
|
93
|
-
current_scope.
|
|
92
|
+
if current_scope.root_span is not None:
|
|
93
|
+
current_scope.root_span.update_active_thread()
|
|
94
94
|
|
|
95
95
|
sentry_scope = sentry_sdk.get_isolation_scope()
|
|
96
96
|
if sentry_scope.profile is not None:
|
sentry_sdk/integrations/flask.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import sentry_sdk
|
|
2
|
+
from sentry_sdk.consts import SOURCE_FOR_STYLE
|
|
2
3
|
from sentry_sdk.integrations import _check_minimum_version, DidNotEnable, Integration
|
|
3
4
|
from sentry_sdk.integrations._wsgi_common import (
|
|
4
5
|
DEFAULT_HTTP_METHODS_TO_CAPTURE,
|
|
@@ -6,7 +7,6 @@ from sentry_sdk.integrations._wsgi_common import (
|
|
|
6
7
|
)
|
|
7
8
|
from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
|
|
8
9
|
from sentry_sdk.scope import should_send_default_pii
|
|
9
|
-
from sentry_sdk.tracing import SOURCE_FOR_STYLE
|
|
10
10
|
from sentry_sdk.utils import (
|
|
11
11
|
capture_internal_exceptions,
|
|
12
12
|
ensure_integration_enabled,
|
sentry_sdk/integrations/gcp.py
CHANGED
|
@@ -5,10 +5,12 @@ from datetime import datetime, timedelta, timezone
|
|
|
5
5
|
from os import environ
|
|
6
6
|
|
|
7
7
|
import sentry_sdk
|
|
8
|
-
from sentry_sdk.api import continue_trace
|
|
9
8
|
from sentry_sdk.consts import OP
|
|
10
9
|
from sentry_sdk.integrations import Integration
|
|
11
|
-
from sentry_sdk.integrations._wsgi_common import
|
|
10
|
+
from sentry_sdk.integrations._wsgi_common import (
|
|
11
|
+
_filter_headers,
|
|
12
|
+
_request_headers_to_span_attributes,
|
|
13
|
+
)
|
|
12
14
|
from sentry_sdk.scope import should_send_default_pii
|
|
13
15
|
from sentry_sdk.tracing import TransactionSource
|
|
14
16
|
from sentry_sdk.utils import (
|
|
@@ -84,42 +86,30 @@ def _wrap_func(func):
|
|
|
84
86
|
if hasattr(gcp_event, "headers"):
|
|
85
87
|
headers = gcp_event.headers
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
sentry_event, hint = event_from_exception(
|
|
112
|
-
exc_info,
|
|
113
|
-
client_options=client.options,
|
|
114
|
-
mechanism={"type": "gcp", "handled": False},
|
|
115
|
-
)
|
|
116
|
-
sentry_sdk.capture_event(sentry_event, hint=hint)
|
|
117
|
-
reraise(*exc_info)
|
|
118
|
-
finally:
|
|
119
|
-
if timeout_thread:
|
|
120
|
-
timeout_thread.stop()
|
|
121
|
-
# Flush out the event queue
|
|
122
|
-
client.flush()
|
|
89
|
+
with sentry_sdk.continue_trace(headers):
|
|
90
|
+
with sentry_sdk.start_span(
|
|
91
|
+
op=OP.FUNCTION_GCP,
|
|
92
|
+
name=environ.get("FUNCTION_NAME", ""),
|
|
93
|
+
source=TransactionSource.COMPONENT,
|
|
94
|
+
origin=GcpIntegration.origin,
|
|
95
|
+
attributes=_prepopulate_attributes(gcp_event),
|
|
96
|
+
):
|
|
97
|
+
try:
|
|
98
|
+
return func(functionhandler, gcp_event, *args, **kwargs)
|
|
99
|
+
except Exception:
|
|
100
|
+
exc_info = sys.exc_info()
|
|
101
|
+
sentry_event, hint = event_from_exception(
|
|
102
|
+
exc_info,
|
|
103
|
+
client_options=client.options,
|
|
104
|
+
mechanism={"type": "gcp", "handled": False},
|
|
105
|
+
)
|
|
106
|
+
sentry_sdk.capture_event(sentry_event, hint=hint)
|
|
107
|
+
reraise(*exc_info)
|
|
108
|
+
finally:
|
|
109
|
+
if timeout_thread:
|
|
110
|
+
timeout_thread.stop()
|
|
111
|
+
# Flush out the event queue
|
|
112
|
+
client.flush()
|
|
123
113
|
|
|
124
114
|
return sentry_func # type: ignore
|
|
125
115
|
|
|
@@ -232,3 +222,38 @@ def _get_google_cloud_logs_url(final_time):
|
|
|
232
222
|
)
|
|
233
223
|
|
|
234
224
|
return url
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
ENV_TO_ATTRIBUTE = {
|
|
228
|
+
"FUNCTION_NAME": "faas.name",
|
|
229
|
+
"ENTRY_POINT": "gcp.function.entry_point",
|
|
230
|
+
"FUNCTION_IDENTITY": "gcp.function.identity",
|
|
231
|
+
"FUNCTION_REGION": "faas.region",
|
|
232
|
+
"GCP_PROJECT": "gcp.function.project",
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
EVENT_TO_ATTRIBUTE = {
|
|
236
|
+
"method": "http.request.method",
|
|
237
|
+
"query_string": "url.query",
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _prepopulate_attributes(gcp_event):
|
|
242
|
+
# type: (Any) -> dict[str, Any]
|
|
243
|
+
attributes = {
|
|
244
|
+
"cloud.provider": "gcp",
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
for key, attr in ENV_TO_ATTRIBUTE.items():
|
|
248
|
+
if environ.get(key):
|
|
249
|
+
attributes[attr] = environ[key]
|
|
250
|
+
|
|
251
|
+
for key, attr in EVENT_TO_ATTRIBUTE.items():
|
|
252
|
+
if getattr(gcp_event, key, None):
|
|
253
|
+
attributes[attr] = getattr(gcp_event, key)
|
|
254
|
+
|
|
255
|
+
if hasattr(gcp_event, "headers"):
|
|
256
|
+
headers = gcp_event.headers
|
|
257
|
+
attributes.update(_request_headers_to_span_attributes(headers))
|
|
258
|
+
|
|
259
|
+
return attributes
|
|
@@ -135,17 +135,10 @@ def graphql_span(schema, source, kwargs):
|
|
|
135
135
|
},
|
|
136
136
|
)
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
_graphql_span.set_data("graphql.document", source)
|
|
145
|
-
_graphql_span.set_data("graphql.operation.name", operation_name)
|
|
146
|
-
_graphql_span.set_data("graphql.operation.type", operation_type)
|
|
147
|
-
|
|
148
|
-
try:
|
|
138
|
+
with sentry_sdk.start_span(
|
|
139
|
+
op=op, name=operation_name, only_if_parent=True
|
|
140
|
+
) as graphql_span:
|
|
141
|
+
graphql_span.set_attribute("graphql.document", source)
|
|
142
|
+
graphql_span.set_attribute("graphql.operation.name", operation_name)
|
|
143
|
+
graphql_span.set_attribute("graphql.operation.type", operation_type)
|
|
149
144
|
yield
|
|
150
|
-
finally:
|
|
151
|
-
_graphql_span.finish()
|
|
@@ -44,14 +44,17 @@ class SentryUnaryUnaryClientInterceptor(ClientInterceptor, UnaryUnaryClientInter
|
|
|
44
44
|
request: Message,
|
|
45
45
|
) -> Union[UnaryUnaryCall, Message]:
|
|
46
46
|
method = client_call_details.method
|
|
47
|
+
if isinstance(method, bytes):
|
|
48
|
+
method = method.decode()
|
|
47
49
|
|
|
48
50
|
with sentry_sdk.start_span(
|
|
49
51
|
op=OP.GRPC_CLIENT,
|
|
50
|
-
name="unary unary call to %s" % method
|
|
52
|
+
name="unary unary call to %s" % method,
|
|
51
53
|
origin=SPAN_ORIGIN,
|
|
54
|
+
only_if_parent=True,
|
|
52
55
|
) as span:
|
|
53
|
-
span.
|
|
54
|
-
span.
|
|
56
|
+
span.set_attribute("type", "unary unary")
|
|
57
|
+
span.set_attribute("method", method)
|
|
55
58
|
|
|
56
59
|
client_call_details = self._update_client_call_details_metadata_from_scope(
|
|
57
60
|
client_call_details
|
|
@@ -59,7 +62,7 @@ class SentryUnaryUnaryClientInterceptor(ClientInterceptor, UnaryUnaryClientInter
|
|
|
59
62
|
|
|
60
63
|
response = await continuation(client_call_details, request)
|
|
61
64
|
status_code = await response.code()
|
|
62
|
-
span.
|
|
65
|
+
span.set_attribute("code", status_code.name)
|
|
63
66
|
|
|
64
67
|
return response
|
|
65
68
|
|
|
@@ -74,14 +77,17 @@ class SentryUnaryStreamClientInterceptor(
|
|
|
74
77
|
request: Message,
|
|
75
78
|
) -> Union[AsyncIterable[Any], UnaryStreamCall]:
|
|
76
79
|
method = client_call_details.method
|
|
80
|
+
if isinstance(method, bytes):
|
|
81
|
+
method = method.decode()
|
|
77
82
|
|
|
78
83
|
with sentry_sdk.start_span(
|
|
79
84
|
op=OP.GRPC_CLIENT,
|
|
80
|
-
name="unary stream call to %s" % method
|
|
85
|
+
name="unary stream call to %s" % method,
|
|
81
86
|
origin=SPAN_ORIGIN,
|
|
87
|
+
only_if_parent=True,
|
|
82
88
|
) as span:
|
|
83
|
-
span.
|
|
84
|
-
span.
|
|
89
|
+
span.set_attribute("type", "unary stream")
|
|
90
|
+
span.set_attribute("method", method)
|
|
85
91
|
|
|
86
92
|
client_call_details = self._update_client_call_details_metadata_from_scope(
|
|
87
93
|
client_call_details
|
|
@@ -89,6 +95,6 @@ class SentryUnaryStreamClientInterceptor(
|
|
|
89
95
|
|
|
90
96
|
response = await continuation(client_call_details, request)
|
|
91
97
|
# status_code = await response.code()
|
|
92
|
-
# span.
|
|
98
|
+
# span.set_attribute("code", status_code)
|
|
93
99
|
|
|
94
100
|
return response
|
|
@@ -2,7 +2,7 @@ import sentry_sdk
|
|
|
2
2
|
from sentry_sdk.consts import OP
|
|
3
3
|
from sentry_sdk.integrations import DidNotEnable
|
|
4
4
|
from sentry_sdk.integrations.grpc.consts import SPAN_ORIGIN
|
|
5
|
-
from sentry_sdk.tracing import
|
|
5
|
+
from sentry_sdk.tracing import TransactionSource
|
|
6
6
|
from sentry_sdk.utils import event_from_exception
|
|
7
7
|
|
|
8
8
|
from typing import TYPE_CHECKING
|
|
@@ -44,26 +44,24 @@ class ServerInterceptor(grpc.aio.ServerInterceptor): # type: ignore
|
|
|
44
44
|
return await handler(request, context)
|
|
45
45
|
|
|
46
46
|
# What if the headers are empty?
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
sentry_sdk.capture_event(event, hint=hint)
|
|
66
|
-
raise
|
|
47
|
+
with sentry_sdk.continue_trace(dict(context.invocation_metadata())):
|
|
48
|
+
with sentry_sdk.start_span(
|
|
49
|
+
op=OP.GRPC_SERVER,
|
|
50
|
+
name=name,
|
|
51
|
+
source=TransactionSource.CUSTOM,
|
|
52
|
+
origin=SPAN_ORIGIN,
|
|
53
|
+
):
|
|
54
|
+
try:
|
|
55
|
+
return await handler.unary_unary(request, context)
|
|
56
|
+
except AbortError:
|
|
57
|
+
raise
|
|
58
|
+
except Exception as exc:
|
|
59
|
+
event, hint = event_from_exception(
|
|
60
|
+
exc,
|
|
61
|
+
mechanism={"type": "grpc", "handled": False},
|
|
62
|
+
)
|
|
63
|
+
sentry_sdk.capture_event(event, hint=hint)
|
|
64
|
+
raise
|
|
67
65
|
|
|
68
66
|
elif not handler.request_streaming and handler.response_streaming:
|
|
69
67
|
handler_factory = grpc.unary_stream_rpc_method_handler
|
|
@@ -31,16 +31,17 @@ class ClientInterceptor(
|
|
|
31
31
|
op=OP.GRPC_CLIENT,
|
|
32
32
|
name="unary unary call to %s" % method,
|
|
33
33
|
origin=SPAN_ORIGIN,
|
|
34
|
+
only_if_parent=True,
|
|
34
35
|
) as span:
|
|
35
|
-
span.
|
|
36
|
-
span.
|
|
36
|
+
span.set_attribute("type", "unary unary")
|
|
37
|
+
span.set_attribute("method", method)
|
|
37
38
|
|
|
38
39
|
client_call_details = self._update_client_call_details_metadata_from_scope(
|
|
39
40
|
client_call_details
|
|
40
41
|
)
|
|
41
42
|
|
|
42
43
|
response = continuation(client_call_details, request)
|
|
43
|
-
span.
|
|
44
|
+
span.set_attribute("code", response.code().name)
|
|
44
45
|
|
|
45
46
|
return response
|
|
46
47
|
|
|
@@ -52,9 +53,10 @@ class ClientInterceptor(
|
|
|
52
53
|
op=OP.GRPC_CLIENT,
|
|
53
54
|
name="unary stream call to %s" % method,
|
|
54
55
|
origin=SPAN_ORIGIN,
|
|
56
|
+
only_if_parent=True,
|
|
55
57
|
) as span:
|
|
56
|
-
span.
|
|
57
|
-
span.
|
|
58
|
+
span.set_attribute("type", "unary stream")
|
|
59
|
+
span.set_attribute("method", method)
|
|
58
60
|
|
|
59
61
|
client_call_details = self._update_client_call_details_metadata_from_scope(
|
|
60
62
|
client_call_details
|
|
@@ -64,7 +66,7 @@ class ClientInterceptor(
|
|
|
64
66
|
client_call_details, request
|
|
65
67
|
) # type: UnaryStreamCall
|
|
66
68
|
# Setting code on unary-stream leads to execution getting stuck
|
|
67
|
-
# span.
|
|
69
|
+
# span.set_attribute("code", response.code().name)
|
|
68
70
|
|
|
69
71
|
return response
|
|
70
72
|
|
|
@@ -2,7 +2,7 @@ import sentry_sdk
|
|
|
2
2
|
from sentry_sdk.consts import OP
|
|
3
3
|
from sentry_sdk.integrations import DidNotEnable
|
|
4
4
|
from sentry_sdk.integrations.grpc.consts import SPAN_ORIGIN
|
|
5
|
-
from sentry_sdk.tracing import
|
|
5
|
+
from sentry_sdk.tracing import TransactionSource
|
|
6
6
|
|
|
7
7
|
from typing import TYPE_CHECKING
|
|
8
8
|
|
|
@@ -38,19 +38,17 @@ class ServerInterceptor(grpc.ServerInterceptor): # type: ignore
|
|
|
38
38
|
if name:
|
|
39
39
|
metadata = dict(context.invocation_metadata())
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
except BaseException as e:
|
|
53
|
-
raise e
|
|
41
|
+
with sentry_sdk.continue_trace(metadata):
|
|
42
|
+
with sentry_sdk.start_span(
|
|
43
|
+
op=OP.GRPC_SERVER,
|
|
44
|
+
name=name,
|
|
45
|
+
source=TransactionSource.CUSTOM,
|
|
46
|
+
origin=SPAN_ORIGIN,
|
|
47
|
+
):
|
|
48
|
+
try:
|
|
49
|
+
return handler.unary_unary(request, context)
|
|
50
|
+
except BaseException as e:
|
|
51
|
+
raise e
|
|
54
52
|
else:
|
|
55
53
|
return handler.unary_unary(request, context)
|
|
56
54
|
|