Просмотр исходного кода

Test `pytest-sentry` with SDK 2.0 support (#66504)

Use the new Python SDK 2.0.0 in sentry.io. Some minor changes where made
in the codebase to use the new API of Python SDK 2.0.0.

This also includes using an updated version of
getsentry/pytest-sentry#31.

---------

Co-authored-by: Anton Pirker <anton.pirker@sentry.io>
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
Co-authored-by: Francesco Vigliaturo <francesco.vigliaturo@sentry.io>
Co-authored-by: ArthurKnaus <arthur.knaus@sentry.io>
Daniel Szoke 11 месяцев назад
Родитель
Сommit
ac7f76dc87

+ 1 - 1
requirements-base.txt

@@ -66,7 +66,7 @@ sentry-kafka-schemas>=0.1.65
 sentry-ophio==0.2.6
 sentry-redis-tools>=0.1.7
 sentry-relay>=0.8.56
-sentry-sdk>=1.44.1
+sentry-sdk==2.0.0rc4
 snuba-sdk>=2.0.31
 simplejson>=3.17.6
 sqlparse>=0.4.4

+ 1 - 3
requirements-dev-frozen.txt

@@ -145,7 +145,6 @@ pytest-cov==4.0.0
 pytest-django==4.8.0
 pytest-fail-slow==0.3.0
 pytest-rerunfailures==11.0
-pytest-sentry==0.1.11
 pytest-xdist==3.0.2
 python-dateutil==2.8.2
 python-rapidjson==1.8
@@ -180,7 +179,7 @@ sentry-kafka-schemas==0.1.65
 sentry-ophio==0.2.6
 sentry-redis-tools==0.1.7
 sentry-relay==0.8.56
-sentry-sdk==1.44.1
+sentry-sdk==2.0.0rc4
 sentry-usage-accountant==0.0.10
 simplejson==3.17.6
 six==1.16.0
@@ -230,7 +229,6 @@ wcwidth==0.2.10
 websocket-client==1.3.2
 werkzeug==3.0.1
 wheel==0.38.4
-wrapt==1.14.1
 wsproto==1.1.0
 xmlsec==1.3.13
 zstandard==0.18.0

+ 2 - 1
requirements-dev.txt

@@ -12,7 +12,8 @@ pytest-cov>=4.0.0
 pytest-django>=4.8.0
 pytest-fail-slow>=0.3.0
 pytest-rerunfailures>=11
-pytest-sentry>=0.1.11
+# A version of pytest-sentry compatible with Python SDK 2.0 is set in requriements-getsentry-overrides.txt
+# pytest-sentry>=0.1.11
 pytest-xdist>=3
 responses>=0.23.1
 selenium>=4.16.0

+ 1 - 1
requirements-frozen.txt

@@ -122,7 +122,7 @@ sentry-kafka-schemas==0.1.65
 sentry-ophio==0.2.6
 sentry-redis-tools==0.1.7
 sentry-relay==0.8.56
-sentry-sdk==1.44.1
+sentry-sdk==2.0.0rc4
 sentry-usage-accountant==0.0.10
 simplejson==3.17.6
 six==1.16.0

+ 5 - 0
requirements-getsentry-overrides.txt

@@ -7,3 +7,8 @@
 # the format is:
 # # comment explaining what you're doing
 # library-name @ https://github.com/getsentry/<repo>/archive/<40 char sha>.zip
+
+# Version of pytest-sentry that is compatible to Python SDK 2.0.
+# After dog fooding SDK 2.0 we will make a new release of pytest-sentry
+# and remove this line and update requirements-dev.txt
+pytest-sentry @ https://github.com/getsentry/pytest-sentry/archive/6ab6a70015e150272039a12b3a9ae607ffca950e.zip

+ 6 - 6
src/sentry/cache/base.py

@@ -46,9 +46,9 @@ class BaseCache(local):
         if not self.is_default_cache:
             return
 
-        with sentry_sdk.configure_scope() as scope:
-            # Do not set this tag if we're in the global scope (which roughly
-            # equates to having a transaction).
-            if scope.transaction:
-                scope.set_tag(f"{op}_default_cache", "true")
-                scope.set_tag("used_default_cache", "true")
+        scope = sentry_sdk.Scope.get_current_scope()
+        # Do not set this tag if we're in the global scope (which roughly
+        # equates to having a transaction).
+        if scope.transaction:
+            sentry_sdk.set_tag(f"{op}_default_cache", "true")
+            sentry_sdk.set_tag("used_default_cache", "true")

+ 3 - 3
src/sentry/conf/types/sdk_config.py

@@ -3,7 +3,7 @@ from __future__ import annotations
 from collections.abc import Callable
 from typing import Any, Literal, NotRequired, TypedDict
 
-from sentry_sdk.types import Event
+from sentry_sdk.types import Event, Hint
 
 
 class SdkConfig(TypedDict):
@@ -18,8 +18,8 @@ class SdkConfig(TypedDict):
 
     send_client_reports: NotRequired[bool]
     traces_sampler: NotRequired[Callable[[dict[str, Any]], float]]
-    before_send: NotRequired[Callable[[Event, dict[str, Any]], Event | None]]
-    before_send_transaction: NotRequired[Callable[[Event, dict[str, Any]], Event | None]]
+    before_send: NotRequired[Callable[[Event, Hint], Event | None]]
+    before_send_transaction: NotRequired[Callable[[Event, Hint], Event | None]]
     profiles_sample_rate: NotRequired[float]
     profiler_mode: NotRequired[Literal["sleep", "thread", "gevent", "unknown"]]
     enable_db_query_source: NotRequired[bool]

+ 1 - 1
src/sentry/scim/endpoints/utils.py

@@ -20,7 +20,7 @@ ACCEPTED_FILTERED_KEYS = ["userName", "value", "displayName"]
 
 class SCIMApiError(APIException):
     def __init__(self, detail, status_code=400):
-        transaction = sentry_sdk.Hub.current.scope.transaction
+        transaction = sentry_sdk.Scope.get_current_scope().transaction
         if transaction is not None:
             transaction.set_tag("http.status_code", status_code)
         self.status_code = status_code

+ 2 - 3
src/sentry/utils/rust.py

@@ -1,6 +1,6 @@
 import re
 
-from sentry_sdk.hub import Hub
+import sentry_sdk
 from sentry_sdk.integrations import Integration
 from sentry_sdk.scope import add_global_event_processor
 
@@ -249,8 +249,7 @@ class RustInfoIntegration(Integration):
     def setup_once():
         @add_global_event_processor
         def processor(event, hint):
-            integration = Hub.current.get_integration(RustInfoIntegration)
-            if integration is None:
+            if sentry_sdk.get_client().get_integration(RustInfoIntegration) is None:
                 return event
 
             return merge_rust_info_frames(event, hint)

+ 19 - 20
src/sentry/utils/sdk.py

@@ -29,6 +29,8 @@ from sentry.utils.rust import RustInfoIntegration
 
 # Can't import models in utils because utils should be the bottom of the food chain
 if TYPE_CHECKING:
+    from sentry_sdk.types import Event, Hint
+
     from sentry.models.organization import Organization
     from sentry.services.hybrid_cloud.organization import RpcOrganization
 
@@ -200,7 +202,7 @@ def traces_sampler(sampling_context):
     return float(settings.SENTRY_BACKEND_APM_SAMPLING or 0)
 
 
-def before_send_transaction(event, _):
+def before_send_transaction(event: Event, _: Hint) -> Event | None:
     # Discard generic redirects.
     # This condition can be removed once https://github.com/getsentry/team-sdks/issues/48 is fixed.
     if (
@@ -211,14 +213,14 @@ def before_send_transaction(event, _):
 
     # Occasionally the span limit is hit and we drop spans from transactions, this helps find transactions where this occurs.
     num_of_spans = len(event["spans"])
-    event["tags"]["spans_over_limit"] = num_of_spans >= 1000
+    event["tags"]["spans_over_limit"] = str(num_of_spans >= 1000)
     if not event["measurements"]:
         event["measurements"] = {}
     event["measurements"]["num_of_spans"] = {"value": num_of_spans}
     return event
 
 
-def before_send(event, _):
+def before_send(event: Event, _: Hint) -> Event | None:
     if event.get("tags"):
         if settings.SILO_MODE:
             event["tags"]["silo_mode"] = str(settings.SILO_MODE)
@@ -271,8 +273,6 @@ def configure_sdk():
     """
     Setup and initialize the Sentry SDK.
     """
-    assert sentry_sdk.Hub.main.client is None
-
     sdk_options, dsns = _get_sdk_options()
 
     internal_project_key = get_project_key()
@@ -568,21 +568,20 @@ def check_current_scope_transaction(
     Note: Ignores scope `transaction` values with `source = "custom"`, indicating a value which has
     been set maunually.
     """
+    scope = sentry_sdk.Scope.get_current_scope()
+    transaction_from_request = get_transaction_name_from_request(request)
 
-    with configure_scope() as scope:
-        transaction_from_request = get_transaction_name_from_request(request)
-
-        if (
-            scope._transaction is not None
-            and scope._transaction != transaction_from_request
-            and scope._transaction_info.get("source") != "custom"
-        ):
-            return {
-                "scope_transaction": scope._transaction,
-                "request_transaction": transaction_from_request,
-            }
-        else:
-            return None
+    if (
+        scope._transaction is not None
+        and scope._transaction != transaction_from_request
+        and scope._transaction_info.get("source") != "custom"
+    ):
+        return {
+            "scope_transaction": scope._transaction,
+            "request_transaction": transaction_from_request,
+        }
+    else:
+        return None
 
 
 def capture_exception_with_scope_check(
@@ -681,7 +680,7 @@ def bind_ambiguous_org_context(
 
 def set_measurement(measurement_name, value, unit=None):
     try:
-        transaction = sentry_sdk.Hub.current.scope.transaction
+        transaction = sentry_sdk.Scope.get_current_scope().transaction
         if transaction is not None:
             transaction.set_measurement(measurement_name, value, unit)
     except Exception:

Некоторые файлы не были показаны из-за большого количества измененных файлов