From 6609d89680868974cda17f58488ba5a6b4c2248a Mon Sep 17 00:00:00 2001 From: Marcelo Galigniana Date: Sun, 22 Dec 2024 00:19:09 -0300 Subject: [PATCH 1/8] ref(tracing): Move `TRANSACTION_SOURCE_*` constants to `Enum` Fixes GH-2696 --- CHANGELOG.md | 8 ++--- sentry_sdk/integrations/aiohttp.py | 4 +-- sentry_sdk/integrations/arq.py | 4 +-- sentry_sdk/integrations/asgi.py | 17 ++++------ sentry_sdk/integrations/aws_lambda.py | 4 +-- sentry_sdk/integrations/celery/__init__.py | 4 +-- sentry_sdk/integrations/chalice.py | 4 +-- sentry_sdk/integrations/django/__init__.py | 4 +-- sentry_sdk/integrations/fastapi.py | 4 +-- sentry_sdk/integrations/gcp.py | 4 +-- sentry_sdk/integrations/grpc/aio/server.py | 4 +-- sentry_sdk/integrations/grpc/server.py | 4 +-- sentry_sdk/integrations/huey.py | 4 +-- sentry_sdk/integrations/litestar.py | 4 +-- sentry_sdk/integrations/ray.py | 4 +-- sentry_sdk/integrations/rq.py | 4 +-- sentry_sdk/integrations/sanic.py | 12 ++++--- sentry_sdk/integrations/starlette.py | 9 +++-- sentry_sdk/integrations/starlite.py | 4 +-- sentry_sdk/integrations/strawberry.py | 4 +-- sentry_sdk/integrations/tornado.py | 9 ++--- sentry_sdk/integrations/wsgi.py | 4 +-- sentry_sdk/metrics.py | 15 +++------ sentry_sdk/tracing.py | 39 ++++++++++++---------- tests/integrations/asgi/test_asgi.py | 5 ++- tests/integrations/sanic/test_sanic.py | 8 ++--- tests/test_metrics.py | 6 ++-- 27 files changed, 97 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80ff6c2796..9075eec395 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2263,7 +2263,7 @@ By: @mgaligniana (#1773) import sentry_sdk from sentry_sdk.integrations.arq import ArqIntegration - from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT + from sentry_sdk.tracing import TransactionSource sentry_sdk.init( dsn="...", @@ -2283,7 +2283,7 @@ By: @mgaligniana (#1773) await ctx['session'].aclose() async def main(): - with sentry_sdk.start_transaction(name="testing_arq_tasks", source=TRANSACTION_SOURCE_COMPONENT): + with sentry_sdk.start_transaction(name="testing_arq_tasks", source=TransactionSource.COMPONENT.value): redis = await create_pool(RedisSettings()) for url in ('https://facebook.com', 'https://microsoft.com', 'https://github.com', "asdf" ): @@ -2357,7 +2357,7 @@ By: @mgaligniana (#1773) import sentry_sdk from sentry_sdk.integrations.huey import HueyIntegration - from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, Transaction + from sentry_sdk.tracing import TransactionSource, Transaction def main(): @@ -2369,7 +2369,7 @@ By: @mgaligniana (#1773) traces_sample_rate=1.0, ) - with sentry_sdk.start_transaction(name="testing_huey_tasks", source=TRANSACTION_SOURCE_COMPONENT): + with sentry_sdk.start_transaction(name="testing_huey_tasks", source=TransactionSource.COMPONENT.value): r = add_numbers(1, 2) if __name__ == "__main__": diff --git a/sentry_sdk/integrations/aiohttp.py b/sentry_sdk/integrations/aiohttp.py index 47c1272ae1..0506da8cf3 100644 --- a/sentry_sdk/integrations/aiohttp.py +++ b/sentry_sdk/integrations/aiohttp.py @@ -20,7 +20,7 @@ from sentry_sdk.tracing import ( BAGGAGE_HEADER_NAME, SOURCE_FOR_STYLE, - TRANSACTION_SOURCE_ROUTE, + TransactionSource, ) from sentry_sdk.tracing_utils import should_propagate_trace from sentry_sdk.utils import ( @@ -129,7 +129,7 @@ async def sentry_app_handle(self, request, *args, **kwargs): # If this transaction name makes it to the UI, AIOHTTP's # URL resolver did not find a route or died trying. name="generic AIOHTTP request", - source=TRANSACTION_SOURCE_ROUTE, + source=TransactionSource.ROUTE.value, origin=AioHttpIntegration.origin, ) with sentry_sdk.start_transaction( diff --git a/sentry_sdk/integrations/arq.py b/sentry_sdk/integrations/arq.py index a2cce8e0ff..2a3ae7e15e 100644 --- a/sentry_sdk/integrations/arq.py +++ b/sentry_sdk/integrations/arq.py @@ -5,7 +5,7 @@ from sentry_sdk.integrations import _check_minimum_version, DidNotEnable, Integration from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_TASK +from sentry_sdk.tracing import Transaction, TransactionSource from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -102,7 +102,7 @@ async def _sentry_run_job(self, job_id, score): name="unknown arq task", status="ok", op=OP.QUEUE_TASK_ARQ, - source=TRANSACTION_SOURCE_TASK, + source=TransactionSource.TASK.value, origin=ArqIntegration.origin, ) diff --git a/sentry_sdk/integrations/asgi.py b/sentry_sdk/integrations/asgi.py index f5e8665b4f..e3f22c3955 100644 --- a/sentry_sdk/integrations/asgi.py +++ b/sentry_sdk/integrations/asgi.py @@ -25,10 +25,7 @@ from sentry_sdk.sessions import track_session from sentry_sdk.tracing import ( SOURCE_FOR_STYLE, - TRANSACTION_SOURCE_ROUTE, - TRANSACTION_SOURCE_URL, - TRANSACTION_SOURCE_COMPONENT, - TRANSACTION_SOURCE_CUSTOM, + TransactionSource, ) from sentry_sdk.utils import ( ContextVar, @@ -273,9 +270,9 @@ def event_processor(self, event, hint, asgi_scope): already_set = event["transaction"] != _DEFAULT_TRANSACTION_NAME and event[ "transaction_info" ].get("source") in [ - TRANSACTION_SOURCE_COMPONENT, - TRANSACTION_SOURCE_ROUTE, - TRANSACTION_SOURCE_CUSTOM, + TransactionSource.COMPONENT.value, + TransactionSource.ROUTE.value, + TransactionSource.CUSTOM.value, ] if not already_set: name, source = self._get_transaction_name_and_source( @@ -313,7 +310,7 @@ def _get_transaction_name_and_source(self, transaction_style, asgi_scope): name = transaction_from_function(endpoint) or "" else: name = _get_url(asgi_scope, "http" if ty == "http" else "ws", host=None) - source = TRANSACTION_SOURCE_URL + source = TransactionSource.URL.value elif transaction_style == "url": # FastAPI includes the route object in the scope to let Sentry extract the @@ -325,11 +322,11 @@ def _get_transaction_name_and_source(self, transaction_style, asgi_scope): name = path else: name = _get_url(asgi_scope, "http" if ty == "http" else "ws", host=None) - source = TRANSACTION_SOURCE_URL + source = TransactionSource.URL.value if name is None: name = _DEFAULT_TRANSACTION_NAME - source = TRANSACTION_SOURCE_ROUTE + source = TransactionSource.ROUTE.value return name, source return name, source diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 831cde8999..4ccf4fbe3b 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -10,7 +10,7 @@ from sentry_sdk.api import continue_trace from sentry_sdk.consts import OP from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( AnnotatedValue, capture_internal_exceptions, @@ -150,7 +150,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): headers, op=OP.FUNCTION_AWS, name=aws_context.function_name, - source=TRANSACTION_SOURCE_COMPONENT, + source=TransactionSource.COMPONENT.value, origin=AwsLambdaIntegration.origin, ) with sentry_sdk.start_transaction( diff --git a/sentry_sdk/integrations/celery/__init__.py b/sentry_sdk/integrations/celery/__init__.py index 80decb6064..6d1e64af83 100644 --- a/sentry_sdk/integrations/celery/__init__.py +++ b/sentry_sdk/integrations/celery/__init__.py @@ -16,7 +16,7 @@ ) from sentry_sdk.integrations.celery.utils import _now_seconds_since_epoch from sentry_sdk.integrations.logging import ignore_logger -from sentry_sdk.tracing import BAGGAGE_HEADER_NAME, TRANSACTION_SOURCE_TASK +from sentry_sdk.tracing import BAGGAGE_HEADER_NAME, TransactionSource from sentry_sdk.tracing_utils import Baggage from sentry_sdk.utils import ( capture_internal_exceptions, @@ -326,7 +326,7 @@ def _inner(*args, **kwargs): headers, op=OP.QUEUE_TASK_CELERY, name="unknown celery task", - source=TRANSACTION_SOURCE_TASK, + source=TransactionSource.TASK.value, origin=CeleryIntegration.origin, ) transaction.name = task.name diff --git a/sentry_sdk/integrations/chalice.py b/sentry_sdk/integrations/chalice.py index 0754d1f13b..06f7dd5249 100644 --- a/sentry_sdk/integrations/chalice.py +++ b/sentry_sdk/integrations/chalice.py @@ -4,7 +4,7 @@ import sentry_sdk from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.integrations.aws_lambda import _make_request_event_processor -from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( capture_internal_exceptions, event_from_exception, @@ -67,7 +67,7 @@ def wrapped_view_function(**function_args): configured_time = app.lambda_context.get_remaining_time_in_millis() scope.set_transaction_name( app.lambda_context.function_name, - source=TRANSACTION_SOURCE_COMPONENT, + source=TransactionSource.COMPONENT.value, ) scope.add_event_processor( diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index 54bc25675d..b1472dfd6c 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -8,7 +8,7 @@ from sentry_sdk.consts import OP, SPANDATA from sentry_sdk.scope import add_global_event_processor, should_send_default_pii from sentry_sdk.serializer import add_global_repr_processor -from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_URL +from sentry_sdk.tracing import SOURCE_FOR_STYLE, TransactionSource from sentry_sdk.tracing_utils import add_query_source, record_sql_queries from sentry_sdk.utils import ( AnnotatedValue, @@ -398,7 +398,7 @@ def _set_transaction_name_and_source(scope, transaction_style, request): if transaction_name is None: transaction_name = request.path_info - source = TRANSACTION_SOURCE_URL + source = TransactionSource.URL.value else: source = SOURCE_FOR_STYLE[transaction_style] diff --git a/sentry_sdk/integrations/fastapi.py b/sentry_sdk/integrations/fastapi.py index 8877925a36..378a13b077 100644 --- a/sentry_sdk/integrations/fastapi.py +++ b/sentry_sdk/integrations/fastapi.py @@ -5,7 +5,7 @@ import sentry_sdk from sentry_sdk.integrations import DidNotEnable from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_ROUTE +from sentry_sdk.tracing import SOURCE_FOR_STYLE, TransactionSource from sentry_sdk.utils import ( transaction_from_function, logger, @@ -61,7 +61,7 @@ def _set_transaction_name_and_source(scope, transaction_style, request): if not name: name = _DEFAULT_TRANSACTION_NAME - source = TRANSACTION_SOURCE_ROUTE + source = TransactionSource.ROUTE.value else: source = SOURCE_FOR_STYLE[transaction_style] diff --git a/sentry_sdk/integrations/gcp.py b/sentry_sdk/integrations/gcp.py index 3983f550d3..ca460811e3 100644 --- a/sentry_sdk/integrations/gcp.py +++ b/sentry_sdk/integrations/gcp.py @@ -10,7 +10,7 @@ from sentry_sdk.integrations import Integration from sentry_sdk.integrations._wsgi_common import _filter_headers from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( AnnotatedValue, capture_internal_exceptions, @@ -88,7 +88,7 @@ def sentry_func(functionhandler, gcp_event, *args, **kwargs): headers, op=OP.FUNCTION_GCP, name=environ.get("FUNCTION_NAME", ""), - source=TRANSACTION_SOURCE_COMPONENT, + source=TransactionSource.COMPONENT.value, origin=GcpIntegration.origin, ) sampling_context = { diff --git a/sentry_sdk/integrations/grpc/aio/server.py b/sentry_sdk/integrations/grpc/aio/server.py index addc6bee36..32c38f6b72 100644 --- a/sentry_sdk/integrations/grpc/aio/server.py +++ b/sentry_sdk/integrations/grpc/aio/server.py @@ -2,7 +2,7 @@ from sentry_sdk.consts import OP from sentry_sdk.integrations import DidNotEnable from sentry_sdk.integrations.grpc.consts import SPAN_ORIGIN -from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_CUSTOM +from sentry_sdk.tracing import Transaction, TransactionSource from sentry_sdk.utils import event_from_exception from typing import TYPE_CHECKING @@ -48,7 +48,7 @@ async def wrapped(request, context): dict(context.invocation_metadata()), op=OP.GRPC_SERVER, name=name, - source=TRANSACTION_SOURCE_CUSTOM, + source=TransactionSource.CUSTOM.value, origin=SPAN_ORIGIN, ) diff --git a/sentry_sdk/integrations/grpc/server.py b/sentry_sdk/integrations/grpc/server.py index a640df5e11..4c2e2d822c 100644 --- a/sentry_sdk/integrations/grpc/server.py +++ b/sentry_sdk/integrations/grpc/server.py @@ -2,7 +2,7 @@ from sentry_sdk.consts import OP from sentry_sdk.integrations import DidNotEnable from sentry_sdk.integrations.grpc.consts import SPAN_ORIGIN -from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_CUSTOM +from sentry_sdk.tracing import Transaction, TransactionSource from typing import TYPE_CHECKING @@ -42,7 +42,7 @@ def behavior(request, context): metadata, op=OP.GRPC_SERVER, name=name, - source=TRANSACTION_SOURCE_CUSTOM, + source=TransactionSource.CUSTOM.value, origin=SPAN_ORIGIN, ) diff --git a/sentry_sdk/integrations/huey.py b/sentry_sdk/integrations/huey.py index 7db57680f6..43f8c1eaf7 100644 --- a/sentry_sdk/integrations/huey.py +++ b/sentry_sdk/integrations/huey.py @@ -9,7 +9,7 @@ from sentry_sdk.tracing import ( BAGGAGE_HEADER_NAME, SENTRY_TRACE_HEADER_NAME, - TRANSACTION_SOURCE_TASK, + TransactionSource, ) from sentry_sdk.utils import ( capture_internal_exceptions, @@ -159,7 +159,7 @@ def _sentry_execute(self, task, timestamp=None): sentry_headers or {}, name=task.name, op=OP.QUEUE_TASK_HUEY, - source=TRANSACTION_SOURCE_TASK, + source=TransactionSource.TASK.value, origin=HueyIntegration.origin, ) transaction.set_status(SPANSTATUS.OK) diff --git a/sentry_sdk/integrations/litestar.py b/sentry_sdk/integrations/litestar.py index 4b04dada8a..c92ca41e16 100644 --- a/sentry_sdk/integrations/litestar.py +++ b/sentry_sdk/integrations/litestar.py @@ -4,7 +4,7 @@ from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_ROUTE +from sentry_sdk.tracing import TransactionSource, SOURCE_FOR_STYLE from sentry_sdk.utils import ( ensure_integration_enabled, event_from_exception, @@ -237,7 +237,7 @@ def event_processor(event, _): if not tx_name: tx_name = _DEFAULT_TRANSACTION_NAME - tx_info = {"source": TRANSACTION_SOURCE_ROUTE} + tx_info = {"source": TransactionSource.ROUTE.value} event.update( { diff --git a/sentry_sdk/integrations/ray.py b/sentry_sdk/integrations/ray.py index 24a28c307f..2672208d9b 100644 --- a/sentry_sdk/integrations/ray.py +++ b/sentry_sdk/integrations/ray.py @@ -4,7 +4,7 @@ import sentry_sdk from sentry_sdk.consts import OP, SPANSTATUS from sentry_sdk.integrations import _check_minimum_version, DidNotEnable, Integration -from sentry_sdk.tracing import TRANSACTION_SOURCE_TASK +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( event_from_exception, logger, @@ -63,7 +63,7 @@ def _f(*f_args, _tracing=None, **f_kwargs): op=OP.QUEUE_TASK_RAY, name=qualname_from_function(f), origin=RayIntegration.origin, - source=TRANSACTION_SOURCE_TASK, + source=TransactionSource.TASK.value, ) with sentry_sdk.start_transaction(transaction) as transaction: diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py index d4fca6a33b..06312e6471 100644 --- a/sentry_sdk/integrations/rq.py +++ b/sentry_sdk/integrations/rq.py @@ -5,7 +5,7 @@ from sentry_sdk.api import continue_trace from sentry_sdk.integrations import _check_minimum_version, DidNotEnable, Integration from sentry_sdk.integrations.logging import ignore_logger -from sentry_sdk.tracing import TRANSACTION_SOURCE_TASK +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -57,7 +57,7 @@ def sentry_patched_perform_job(self, job, *args, **kwargs): job.meta.get("_sentry_trace_headers") or {}, op=OP.QUEUE_TASK_RQ, name="unknown RQ task", - source=TRANSACTION_SOURCE_TASK, + source=TransactionSource.TASK.value, origin=RqIntegration.origin, ) diff --git a/sentry_sdk/integrations/sanic.py b/sentry_sdk/integrations/sanic.py index dfcc299d42..e43e828984 100644 --- a/sentry_sdk/integrations/sanic.py +++ b/sentry_sdk/integrations/sanic.py @@ -9,7 +9,7 @@ from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable from sentry_sdk.integrations._wsgi_common import RequestExtractor, _filter_headers from sentry_sdk.integrations.logging import ignore_logger -from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, TRANSACTION_SOURCE_URL +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -192,7 +192,7 @@ async def _context_enter(request): op=OP.HTTP_SERVER, # Unless the request results in a 404 error, the name and source will get overwritten in _set_transaction name=request.path, - source=TRANSACTION_SOURCE_URL, + source=TransactionSource.URL.value, origin=SanicIntegration.origin, ) request.ctx._sentry_transaction = sentry_sdk.start_transaction( @@ -229,7 +229,9 @@ async def _set_transaction(request, route, **_): with capture_internal_exceptions(): scope = sentry_sdk.get_current_scope() route_name = route.name.replace(request.app.name, "").strip(".") - scope.set_transaction_name(route_name, source=TRANSACTION_SOURCE_COMPONENT) + scope.set_transaction_name( + route_name, source=TransactionSource.COMPONENT.value + ) def _sentry_error_handler_lookup(self, exception, *args, **kwargs): @@ -304,11 +306,11 @@ def _legacy_router_get(self, *args): sanic_route = sanic_route[len(sanic_app_name) + 1 :] scope.set_transaction_name( - sanic_route, source=TRANSACTION_SOURCE_COMPONENT + sanic_route, source=TransactionSource.COMPONENT.value ) else: scope.set_transaction_name( - rv[0].__name__, source=TRANSACTION_SOURCE_COMPONENT + rv[0].__name__, source=TransactionSource.COMPONENT.value ) return rv diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index d9db8bd6b8..66eca0868c 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -21,8 +21,7 @@ from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import ( SOURCE_FOR_STYLE, - TRANSACTION_SOURCE_COMPONENT, - TRANSACTION_SOURCE_ROUTE, + TransactionSource, ) from sentry_sdk.utils import ( AnnotatedValue, @@ -714,7 +713,7 @@ def _set_transaction_name_and_source(scope, transaction_style, request): if name is None: name = _DEFAULT_TRANSACTION_NAME - source = TRANSACTION_SOURCE_ROUTE + source = TransactionSource.ROUTE.value scope.set_transaction_name(name, source=source) logger.debug( @@ -729,9 +728,9 @@ def _get_transaction_from_middleware(app, asgi_scope, integration): if integration.transaction_style == "endpoint": name = transaction_from_function(app.__class__) - source = TRANSACTION_SOURCE_COMPONENT + source = TransactionSource.COMPONENT.value elif integration.transaction_style == "url": name = _transaction_name_from_router(asgi_scope) - source = TRANSACTION_SOURCE_ROUTE + source = TransactionSource.ROUTE.value return name, source diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 8714ee2f08..a0b09f2032 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -3,7 +3,7 @@ from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_ROUTE +from sentry_sdk.tracing import SOURCE_FOR_STYLE, TransactionSource from sentry_sdk.utils import ( ensure_integration_enabled, event_from_exception, @@ -235,7 +235,7 @@ def event_processor(event, _): if not tx_name: tx_name = _DEFAULT_TRANSACTION_NAME - tx_info = {"source": TRANSACTION_SOURCE_ROUTE} + tx_info = {"source": TransactionSource.ROUTE.value} event.update( { diff --git a/sentry_sdk/integrations/strawberry.py b/sentry_sdk/integrations/strawberry.py index d27e0eaf1c..95e14197ae 100644 --- a/sentry_sdk/integrations/strawberry.py +++ b/sentry_sdk/integrations/strawberry.py @@ -7,7 +7,7 @@ from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -204,7 +204,7 @@ def on_operation(self): transaction = self.graphql_span.containing_transaction if transaction and self.execution_context.operation_name: transaction.name = self.execution_context.operation_name - transaction.source = TRANSACTION_SOURCE_COMPONENT + transaction.source = TransactionSource.COMPONENT.value transaction.op = op self.graphql_span.finish() diff --git a/sentry_sdk/integrations/tornado.py b/sentry_sdk/integrations/tornado.py index b9e465c7c7..dcc9857167 100644 --- a/sentry_sdk/integrations/tornado.py +++ b/sentry_sdk/integrations/tornado.py @@ -6,10 +6,7 @@ from sentry_sdk.api import continue_trace from sentry_sdk.consts import OP from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.tracing import ( - TRANSACTION_SOURCE_COMPONENT, - TRANSACTION_SOURCE_ROUTE, -) +from sentry_sdk.tracing import TransactionSource from sentry_sdk.utils import ( HAS_REAL_CONTEXTVARS, CONTEXTVARS_ERROR_MESSAGE, @@ -122,7 +119,7 @@ def _handle_request_impl(self): # sentry_urldispatcher_resolve is responsible for # setting a transaction name later. name="generic Tornado request", - source=TRANSACTION_SOURCE_ROUTE, + source=TransactionSource.ROUTE.value, origin=TornadoIntegration.origin, ) @@ -160,7 +157,7 @@ def tornado_processor(event, hint): with capture_internal_exceptions(): method = getattr(handler, handler.request.method.lower()) event["transaction"] = transaction_from_function(method) or "" - event["transaction_info"] = {"source": TRANSACTION_SOURCE_COMPONENT} + event["transaction_info"] = {"source": TransactionSource.COMPONENT.value} with capture_internal_exceptions(): extractor = TornadoRequestExtractor(request) diff --git a/sentry_sdk/integrations/wsgi.py b/sentry_sdk/integrations/wsgi.py index 50deae10c5..6b6bd52666 100644 --- a/sentry_sdk/integrations/wsgi.py +++ b/sentry_sdk/integrations/wsgi.py @@ -13,7 +13,7 @@ ) from sentry_sdk.sessions import track_session from sentry_sdk.scope import use_isolation_scope -from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_ROUTE +from sentry_sdk.tracing import Transaction, TransactionSource from sentry_sdk.utils import ( ContextVar, capture_internal_exceptions, @@ -115,7 +115,7 @@ def __call__(self, environ, start_response): environ, op=OP.HTTP_SERVER, name="generic WSGI request", - source=TRANSACTION_SOURCE_ROUTE, + source=TransactionSource.ROUTE.value, origin=self.span_origin, ) diff --git a/sentry_sdk/metrics.py b/sentry_sdk/metrics.py index f6e9fd6bde..9f87873545 100644 --- a/sentry_sdk/metrics.py +++ b/sentry_sdk/metrics.py @@ -22,12 +22,7 @@ json_dumps, ) from sentry_sdk.envelope import Envelope, Item -from sentry_sdk.tracing import ( - TRANSACTION_SOURCE_ROUTE, - TRANSACTION_SOURCE_VIEW, - TRANSACTION_SOURCE_COMPONENT, - TRANSACTION_SOURCE_TASK, -) +from sentry_sdk.tracing import TransactionSource from typing import TYPE_CHECKING @@ -68,10 +63,10 @@ GOOD_TRANSACTION_SOURCES = frozenset( [ - TRANSACTION_SOURCE_ROUTE, - TRANSACTION_SOURCE_VIEW, - TRANSACTION_SOURCE_COMPONENT, - TRANSACTION_SOURCE_TASK, + TransactionSource.ROUTE.value, + TransactionSource.VIEW.value, + TransactionSource.COMPONENT.value, + TransactionSource.TASK.value, ] ) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 3868b2e6c8..7f8df6360d 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -2,6 +2,7 @@ import random import warnings from datetime import datetime, timedelta, timezone +from enum import Enum import sentry_sdk from sentry_sdk.consts import INSTRUMENTER, SPANSTATUS, SPANDATA @@ -15,6 +16,7 @@ from typing import TYPE_CHECKING + if TYPE_CHECKING: from collections.abc import Callable, Mapping, MutableMapping from typing import Any @@ -124,30 +126,33 @@ class TransactionKwargs(SpanKwargs, total=False): BAGGAGE_HEADER_NAME = "baggage" SENTRY_TRACE_HEADER_NAME = "sentry-trace" + # Transaction source # see https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations -TRANSACTION_SOURCE_CUSTOM = "custom" -TRANSACTION_SOURCE_URL = "url" -TRANSACTION_SOURCE_ROUTE = "route" -TRANSACTION_SOURCE_VIEW = "view" -TRANSACTION_SOURCE_COMPONENT = "component" -TRANSACTION_SOURCE_TASK = "task" +class TransactionSource(Enum): + CUSTOM = "custom" + URL = "url" + ROUTE = "route" + VIEW = "view" + COMPONENT = "component" + TASK = "task" + # These are typically high cardinality and the server hates them LOW_QUALITY_TRANSACTION_SOURCES = [ - TRANSACTION_SOURCE_URL, + TransactionSource.URL.value, ] SOURCE_FOR_STYLE = { - "endpoint": TRANSACTION_SOURCE_COMPONENT, - "function_name": TRANSACTION_SOURCE_COMPONENT, - "handler_name": TRANSACTION_SOURCE_COMPONENT, - "method_and_path_pattern": TRANSACTION_SOURCE_ROUTE, - "path": TRANSACTION_SOURCE_URL, - "route_name": TRANSACTION_SOURCE_COMPONENT, - "route_pattern": TRANSACTION_SOURCE_ROUTE, - "uri_template": TRANSACTION_SOURCE_ROUTE, - "url": TRANSACTION_SOURCE_ROUTE, + "endpoint": TransactionSource.COMPONENT.value, + "function_name": TransactionSource.COMPONENT.value, + "handler_name": TransactionSource.COMPONENT.value, + "method_and_path_pattern": TransactionSource.ROUTE.value, + "path": TransactionSource.URL.value, + "route_name": TransactionSource.COMPONENT.value, + "route_pattern": TransactionSource.ROUTE.value, + "uri_template": TransactionSource.ROUTE.value, + "url": TransactionSource.ROUTE.value, } @@ -772,7 +777,7 @@ def __init__( # type: ignore[misc] name="", # type: str parent_sampled=None, # type: Optional[bool] baggage=None, # type: Optional[Baggage] - source=TRANSACTION_SOURCE_CUSTOM, # type: str + source=TransactionSource.CUSTOM.value, # type: str **kwargs, # type: Unpack[SpanKwargs] ): # type: (...) -> None diff --git a/tests/integrations/asgi/test_asgi.py b/tests/integrations/asgi/test_asgi.py index f3bc7147bf..228ce36f1e 100644 --- a/tests/integrations/asgi/test_asgi.py +++ b/tests/integrations/asgi/test_asgi.py @@ -3,6 +3,7 @@ import pytest import sentry_sdk from sentry_sdk import capture_message +from sentry_sdk.tracing import TransactionSource from sentry_sdk.integrations._asgi_common import _get_ip, _get_headers from sentry_sdk.integrations.asgi import SentryAsgiMiddleware, _looks_like_asgi3 @@ -129,7 +130,9 @@ async def app(scope, receive, send): @pytest.fixture def asgi3_custom_transaction_app(): async def app(scope, receive, send): - sentry_sdk.get_current_scope().set_transaction_name("foobar", source="custom") + sentry_sdk.get_current_scope().set_transaction_name( + "foobar", source=TransactionSource.CUSTOM.value + ) await send( { "type": "http.response.start", diff --git a/tests/integrations/sanic/test_sanic.py b/tests/integrations/sanic/test_sanic.py index 9d95907144..872930bc2d 100644 --- a/tests/integrations/sanic/test_sanic.py +++ b/tests/integrations/sanic/test_sanic.py @@ -10,7 +10,7 @@ import sentry_sdk from sentry_sdk import capture_message from sentry_sdk.integrations.sanic import SanicIntegration -from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, TRANSACTION_SOURCE_URL +from sentry_sdk.tracing import TransactionSource from sanic import Sanic, request, response, __version__ as SANIC_VERSION_RAW from sanic.response import HTTPResponse @@ -370,7 +370,7 @@ def __init__( url="/message", expected_status=200, expected_transaction_name="hi", - expected_source=TRANSACTION_SOURCE_COMPONENT, + expected_source=TransactionSource.COMPONENT.value, ), TransactionTestConfig( # Transaction still recorded when we have an internal server error @@ -378,7 +378,7 @@ def __init__( url="/500", expected_status=500, expected_transaction_name="fivehundred", - expected_source=TRANSACTION_SOURCE_COMPONENT, + expected_source=TransactionSource.COMPONENT.value, ), TransactionTestConfig( # By default, no transaction when we have a 404 error @@ -393,7 +393,7 @@ def __init__( url="/404", expected_status=404, expected_transaction_name="/404", - expected_source=TRANSACTION_SOURCE_URL, + expected_source=TransactionSource.URL.value, ), TransactionTestConfig( # Transaction can be suppressed for other HTTP statuses, too, by passing config to the integration diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 537f8a9646..f382abded3 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -7,7 +7,7 @@ import sentry_sdk from sentry_sdk import metrics -from sentry_sdk.tracing import TRANSACTION_SOURCE_ROUTE +from sentry_sdk.tracing import TransactionSource from sentry_sdk.envelope import parse_json try: @@ -539,7 +539,7 @@ def test_transaction_name( envelopes = capture_envelopes() sentry_sdk.get_current_scope().set_transaction_name( - "/user/{user_id}", source="route" + "/user/{user_id}", source=TransactionSource.ROUTE.value ) metrics.distribution("dist", 1.0, tags={"a": "b"}, timestamp=ts) metrics.distribution("dist", 2.0, tags={"a": "b"}, timestamp=ts) @@ -581,7 +581,7 @@ def test_metric_summaries( envelopes = capture_envelopes() with sentry_sdk.start_transaction( - op="stuff", name="/foo", source=TRANSACTION_SOURCE_ROUTE + op="stuff", name="/foo", source=TransactionSource.ROUTE.value ) as transaction: metrics.increment("root-counter", timestamp=ts) with metrics.timing("my-timer-metric", tags={"a": "b"}, timestamp=ts): From 90358ddfdbf5ff1c04db7f5b022e65a2561f7269 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Feb 2025 09:25:25 +0100 Subject: [PATCH 2/8] Improvements to enum --- CHANGELOG.md | 4 +-- sentry_sdk/integrations/aiohttp.py | 2 +- sentry_sdk/integrations/arq.py | 2 +- sentry_sdk/integrations/asgi.py | 12 ++++---- sentry_sdk/integrations/aws_lambda.py | 2 +- sentry_sdk/integrations/celery/__init__.py | 2 +- sentry_sdk/integrations/chalice.py | 2 +- sentry_sdk/integrations/django/__init__.py | 2 +- sentry_sdk/integrations/fastapi.py | 2 +- sentry_sdk/integrations/gcp.py | 2 +- sentry_sdk/integrations/grpc/aio/server.py | 2 +- sentry_sdk/integrations/grpc/server.py | 2 +- sentry_sdk/integrations/huey.py | 2 +- sentry_sdk/integrations/litestar.py | 2 +- sentry_sdk/integrations/ray.py | 2 +- sentry_sdk/integrations/rq.py | 2 +- sentry_sdk/integrations/sanic.py | 8 +++--- sentry_sdk/integrations/starlette.py | 6 ++-- sentry_sdk/integrations/starlite.py | 2 +- sentry_sdk/integrations/strawberry.py | 2 +- sentry_sdk/integrations/tornado.py | 4 +-- sentry_sdk/integrations/wsgi.py | 2 +- sentry_sdk/metrics.py | 8 +++--- sentry_sdk/tracing.py | 33 ++++++++++++---------- tests/integrations/asgi/test_asgi.py | 2 +- tests/integrations/sanic/test_sanic.py | 6 ++-- tests/test_metrics.py | 4 +-- 27 files changed, 62 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7207f1127..939a612bc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2348,7 +2348,7 @@ By: @mgaligniana (#1773) await ctx['session'].aclose() async def main(): - with sentry_sdk.start_transaction(name="testing_arq_tasks", source=TransactionSource.COMPONENT.value): + with sentry_sdk.start_transaction(name="testing_arq_tasks", source=TransactionSource.COMPONENT): redis = await create_pool(RedisSettings()) for url in ('https://facebook.com', 'https://microsoft.com', 'https://github.com', "asdf" ): @@ -2434,7 +2434,7 @@ By: @mgaligniana (#1773) traces_sample_rate=1.0, ) - with sentry_sdk.start_transaction(name="testing_huey_tasks", source=TransactionSource.COMPONENT.value): + with sentry_sdk.start_transaction(name="testing_huey_tasks", source=TransactionSource.COMPONENT): r = add_numbers(1, 2) if __name__ == "__main__": diff --git a/sentry_sdk/integrations/aiohttp.py b/sentry_sdk/integrations/aiohttp.py index 0506da8cf3..ad3202bf2c 100644 --- a/sentry_sdk/integrations/aiohttp.py +++ b/sentry_sdk/integrations/aiohttp.py @@ -129,7 +129,7 @@ async def sentry_app_handle(self, request, *args, **kwargs): # If this transaction name makes it to the UI, AIOHTTP's # URL resolver did not find a route or died trying. name="generic AIOHTTP request", - source=TransactionSource.ROUTE.value, + source=TransactionSource.ROUTE, origin=AioHttpIntegration.origin, ) with sentry_sdk.start_transaction( diff --git a/sentry_sdk/integrations/arq.py b/sentry_sdk/integrations/arq.py index 2a3ae7e15e..c356347dad 100644 --- a/sentry_sdk/integrations/arq.py +++ b/sentry_sdk/integrations/arq.py @@ -102,7 +102,7 @@ async def _sentry_run_job(self, job_id, score): name="unknown arq task", status="ok", op=OP.QUEUE_TASK_ARQ, - source=TransactionSource.TASK.value, + source=TransactionSource.TASK, origin=ArqIntegration.origin, ) diff --git a/sentry_sdk/integrations/asgi.py b/sentry_sdk/integrations/asgi.py index e3f22c3955..733aa2b3fe 100644 --- a/sentry_sdk/integrations/asgi.py +++ b/sentry_sdk/integrations/asgi.py @@ -270,9 +270,9 @@ def event_processor(self, event, hint, asgi_scope): already_set = event["transaction"] != _DEFAULT_TRANSACTION_NAME and event[ "transaction_info" ].get("source") in [ - TransactionSource.COMPONENT.value, - TransactionSource.ROUTE.value, - TransactionSource.CUSTOM.value, + TransactionSource.COMPONENT, + TransactionSource.ROUTE, + TransactionSource.CUSTOM, ] if not already_set: name, source = self._get_transaction_name_and_source( @@ -310,7 +310,7 @@ def _get_transaction_name_and_source(self, transaction_style, asgi_scope): name = transaction_from_function(endpoint) or "" else: name = _get_url(asgi_scope, "http" if ty == "http" else "ws", host=None) - source = TransactionSource.URL.value + source = TransactionSource.URL elif transaction_style == "url": # FastAPI includes the route object in the scope to let Sentry extract the @@ -322,11 +322,11 @@ def _get_transaction_name_and_source(self, transaction_style, asgi_scope): name = path else: name = _get_url(asgi_scope, "http" if ty == "http" else "ws", host=None) - source = TransactionSource.URL.value + source = TransactionSource.URL if name is None: name = _DEFAULT_TRANSACTION_NAME - source = TransactionSource.ROUTE.value + source = TransactionSource.ROUTE return name, source return name, source diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 836341630f..4990fd6e6a 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -153,7 +153,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): headers, op=OP.FUNCTION_AWS, name=aws_context.function_name, - source=TransactionSource.COMPONENT.value, + source=TransactionSource.COMPONENT, origin=AwsLambdaIntegration.origin, ) with sentry_sdk.start_transaction( diff --git a/sentry_sdk/integrations/celery/__init__.py b/sentry_sdk/integrations/celery/__init__.py index a8b13ee5bf..e8811d767e 100644 --- a/sentry_sdk/integrations/celery/__init__.py +++ b/sentry_sdk/integrations/celery/__init__.py @@ -319,7 +319,7 @@ def _inner(*args, **kwargs): headers, op=OP.QUEUE_TASK_CELERY, name="unknown celery task", - source=TransactionSource.TASK.value, + source=TransactionSource.TASK, origin=CeleryIntegration.origin, ) transaction.name = task.name diff --git a/sentry_sdk/integrations/chalice.py b/sentry_sdk/integrations/chalice.py index 06f7dd5249..947e41ebf7 100644 --- a/sentry_sdk/integrations/chalice.py +++ b/sentry_sdk/integrations/chalice.py @@ -67,7 +67,7 @@ def wrapped_view_function(**function_args): configured_time = app.lambda_context.get_remaining_time_in_millis() scope.set_transaction_name( app.lambda_context.function_name, - source=TransactionSource.COMPONENT.value, + source=TransactionSource.COMPONENT, ) scope.add_event_processor( diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index b1472dfd6c..a9477d9954 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -398,7 +398,7 @@ def _set_transaction_name_and_source(scope, transaction_style, request): if transaction_name is None: transaction_name = request.path_info - source = TransactionSource.URL.value + source = TransactionSource.URL else: source = SOURCE_FOR_STYLE[transaction_style] diff --git a/sentry_sdk/integrations/fastapi.py b/sentry_sdk/integrations/fastapi.py index 378a13b077..76c6adee0f 100644 --- a/sentry_sdk/integrations/fastapi.py +++ b/sentry_sdk/integrations/fastapi.py @@ -61,7 +61,7 @@ def _set_transaction_name_and_source(scope, transaction_style, request): if not name: name = _DEFAULT_TRANSACTION_NAME - source = TransactionSource.ROUTE.value + source = TransactionSource.ROUTE else: source = SOURCE_FOR_STYLE[transaction_style] diff --git a/sentry_sdk/integrations/gcp.py b/sentry_sdk/integrations/gcp.py index ca460811e3..c637b7414a 100644 --- a/sentry_sdk/integrations/gcp.py +++ b/sentry_sdk/integrations/gcp.py @@ -88,7 +88,7 @@ def sentry_func(functionhandler, gcp_event, *args, **kwargs): headers, op=OP.FUNCTION_GCP, name=environ.get("FUNCTION_NAME", ""), - source=TransactionSource.COMPONENT.value, + source=TransactionSource.COMPONENT, origin=GcpIntegration.origin, ) sampling_context = { diff --git a/sentry_sdk/integrations/grpc/aio/server.py b/sentry_sdk/integrations/grpc/aio/server.py index 32c38f6b72..381c63103e 100644 --- a/sentry_sdk/integrations/grpc/aio/server.py +++ b/sentry_sdk/integrations/grpc/aio/server.py @@ -48,7 +48,7 @@ async def wrapped(request, context): dict(context.invocation_metadata()), op=OP.GRPC_SERVER, name=name, - source=TransactionSource.CUSTOM.value, + source=TransactionSource.CUSTOM, origin=SPAN_ORIGIN, ) diff --git a/sentry_sdk/integrations/grpc/server.py b/sentry_sdk/integrations/grpc/server.py index 4c2e2d822c..0d2792d1b7 100644 --- a/sentry_sdk/integrations/grpc/server.py +++ b/sentry_sdk/integrations/grpc/server.py @@ -42,7 +42,7 @@ def behavior(request, context): metadata, op=OP.GRPC_SERVER, name=name, - source=TransactionSource.CUSTOM.value, + source=TransactionSource.CUSTOM, origin=SPAN_ORIGIN, ) diff --git a/sentry_sdk/integrations/huey.py b/sentry_sdk/integrations/huey.py index 43f8c1eaf7..f0aff4c0dd 100644 --- a/sentry_sdk/integrations/huey.py +++ b/sentry_sdk/integrations/huey.py @@ -159,7 +159,7 @@ def _sentry_execute(self, task, timestamp=None): sentry_headers or {}, name=task.name, op=OP.QUEUE_TASK_HUEY, - source=TransactionSource.TASK.value, + source=TransactionSource.TASK, origin=HueyIntegration.origin, ) transaction.set_status(SPANSTATUS.OK) diff --git a/sentry_sdk/integrations/litestar.py b/sentry_sdk/integrations/litestar.py index ebf120b534..5f0b32b04e 100644 --- a/sentry_sdk/integrations/litestar.py +++ b/sentry_sdk/integrations/litestar.py @@ -249,7 +249,7 @@ def event_processor(event, _): if not tx_name: tx_name = _DEFAULT_TRANSACTION_NAME - tx_info = {"source": TransactionSource.ROUTE.value} + tx_info = {"source": TransactionSource.ROUTE} event.update( { diff --git a/sentry_sdk/integrations/ray.py b/sentry_sdk/integrations/ray.py index 2672208d9b..0842b92265 100644 --- a/sentry_sdk/integrations/ray.py +++ b/sentry_sdk/integrations/ray.py @@ -63,7 +63,7 @@ def _f(*f_args, _tracing=None, **f_kwargs): op=OP.QUEUE_TASK_RAY, name=qualname_from_function(f), origin=RayIntegration.origin, - source=TransactionSource.TASK.value, + source=TransactionSource.TASK, ) with sentry_sdk.start_transaction(transaction) as transaction: diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py index 06312e6471..6d7fcf723b 100644 --- a/sentry_sdk/integrations/rq.py +++ b/sentry_sdk/integrations/rq.py @@ -57,7 +57,7 @@ def sentry_patched_perform_job(self, job, *args, **kwargs): job.meta.get("_sentry_trace_headers") or {}, op=OP.QUEUE_TASK_RQ, name="unknown RQ task", - source=TransactionSource.TASK.value, + source=TransactionSource.TASK, origin=RqIntegration.origin, ) diff --git a/sentry_sdk/integrations/sanic.py b/sentry_sdk/integrations/sanic.py index e43e828984..492133dfcb 100644 --- a/sentry_sdk/integrations/sanic.py +++ b/sentry_sdk/integrations/sanic.py @@ -192,7 +192,7 @@ async def _context_enter(request): op=OP.HTTP_SERVER, # Unless the request results in a 404 error, the name and source will get overwritten in _set_transaction name=request.path, - source=TransactionSource.URL.value, + source=TransactionSource.URL, origin=SanicIntegration.origin, ) request.ctx._sentry_transaction = sentry_sdk.start_transaction( @@ -230,7 +230,7 @@ async def _set_transaction(request, route, **_): scope = sentry_sdk.get_current_scope() route_name = route.name.replace(request.app.name, "").strip(".") scope.set_transaction_name( - route_name, source=TransactionSource.COMPONENT.value + route_name, source=TransactionSource.COMPONENT ) @@ -306,11 +306,11 @@ def _legacy_router_get(self, *args): sanic_route = sanic_route[len(sanic_app_name) + 1 :] scope.set_transaction_name( - sanic_route, source=TransactionSource.COMPONENT.value + sanic_route, source=TransactionSource.COMPONENT ) else: scope.set_transaction_name( - rv[0].__name__, source=TransactionSource.COMPONENT.value + rv[0].__name__, source=TransactionSource.COMPONENT ) return rv diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index 66eca0868c..687a428203 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -713,7 +713,7 @@ def _set_transaction_name_and_source(scope, transaction_style, request): if name is None: name = _DEFAULT_TRANSACTION_NAME - source = TransactionSource.ROUTE.value + source = TransactionSource.ROUTE scope.set_transaction_name(name, source=source) logger.debug( @@ -728,9 +728,9 @@ def _get_transaction_from_middleware(app, asgi_scope, integration): if integration.transaction_style == "endpoint": name = transaction_from_function(app.__class__) - source = TransactionSource.COMPONENT.value + source = TransactionSource.COMPONENT elif integration.transaction_style == "url": name = _transaction_name_from_router(asgi_scope) - source = TransactionSource.ROUTE.value + source = TransactionSource.ROUTE return name, source diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index a0b09f2032..24707a18b1 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -235,7 +235,7 @@ def event_processor(event, _): if not tx_name: tx_name = _DEFAULT_TRANSACTION_NAME - tx_info = {"source": TransactionSource.ROUTE.value} + tx_info = {"source": TransactionSource.ROUTE} event.update( { diff --git a/sentry_sdk/integrations/strawberry.py b/sentry_sdk/integrations/strawberry.py index c36398cb9d..ae7d273079 100644 --- a/sentry_sdk/integrations/strawberry.py +++ b/sentry_sdk/integrations/strawberry.py @@ -208,7 +208,7 @@ def on_operation(self): transaction = self.graphql_span.containing_transaction if transaction and self.execution_context.operation_name: transaction.name = self.execution_context.operation_name - transaction.source = TransactionSource.COMPONENT.value + transaction.source = TransactionSource.COMPONENT transaction.op = op self.graphql_span.finish() diff --git a/sentry_sdk/integrations/tornado.py b/sentry_sdk/integrations/tornado.py index f46bde867f..3cd087524a 100644 --- a/sentry_sdk/integrations/tornado.py +++ b/sentry_sdk/integrations/tornado.py @@ -119,7 +119,7 @@ def _handle_request_impl(self): # sentry_urldispatcher_resolve is responsible for # setting a transaction name later. name="generic Tornado request", - source=TransactionSource.ROUTE.value, + source=TransactionSource.ROUTE, origin=TornadoIntegration.origin, ) @@ -157,7 +157,7 @@ def tornado_processor(event, hint): with capture_internal_exceptions(): method = getattr(handler, handler.request.method.lower()) event["transaction"] = transaction_from_function(method) or "" - event["transaction_info"] = {"source": TransactionSource.COMPONENT.value} + event["transaction_info"] = {"source": TransactionSource.COMPONENT} with capture_internal_exceptions(): extractor = TornadoRequestExtractor(request) diff --git a/sentry_sdk/integrations/wsgi.py b/sentry_sdk/integrations/wsgi.py index 6b6bd52666..e628e50e69 100644 --- a/sentry_sdk/integrations/wsgi.py +++ b/sentry_sdk/integrations/wsgi.py @@ -115,7 +115,7 @@ def __call__(self, environ, start_response): environ, op=OP.HTTP_SERVER, name="generic WSGI request", - source=TransactionSource.ROUTE.value, + source=TransactionSource.ROUTE, origin=self.span_origin, ) diff --git a/sentry_sdk/metrics.py b/sentry_sdk/metrics.py index 9f87873545..4bdbc62253 100644 --- a/sentry_sdk/metrics.py +++ b/sentry_sdk/metrics.py @@ -63,10 +63,10 @@ GOOD_TRANSACTION_SOURCES = frozenset( [ - TransactionSource.ROUTE.value, - TransactionSource.VIEW.value, - TransactionSource.COMPONENT.value, - TransactionSource.TASK.value, + TransactionSource.ROUTE, + TransactionSource.VIEW, + TransactionSource.COMPONENT, + TransactionSource.TASK, ] ) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 4c6c8ba428..13fd04cf8e 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -131,30 +131,33 @@ class TransactionKwargs(SpanKwargs, total=False): # Transaction source # see https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations -class TransactionSource(Enum): +class TransactionSource(str, Enum): + COMPONENT = "component" CUSTOM = "custom" - URL = "url" ROUTE = "route" - VIEW = "view" - COMPONENT = "component" TASK = "task" + URL = "url" + VIEW = "view" + + def __str__(self): + return self.value # These are typically high cardinality and the server hates them LOW_QUALITY_TRANSACTION_SOURCES = [ - TransactionSource.URL.value, + TransactionSource.URL, ] SOURCE_FOR_STYLE = { - "endpoint": TransactionSource.COMPONENT.value, - "function_name": TransactionSource.COMPONENT.value, - "handler_name": TransactionSource.COMPONENT.value, - "method_and_path_pattern": TransactionSource.ROUTE.value, - "path": TransactionSource.URL.value, - "route_name": TransactionSource.COMPONENT.value, - "route_pattern": TransactionSource.ROUTE.value, - "uri_template": TransactionSource.ROUTE.value, - "url": TransactionSource.ROUTE.value, + "endpoint": TransactionSource.COMPONENT, + "function_name": TransactionSource.COMPONENT, + "handler_name": TransactionSource.COMPONENT, + "method_and_path_pattern": TransactionSource.ROUTE, + "path": TransactionSource.URL, + "route_name": TransactionSource.COMPONENT, + "route_pattern": TransactionSource.ROUTE, + "uri_template": TransactionSource.ROUTE, + "url": TransactionSource.ROUTE, } @@ -782,7 +785,7 @@ def __init__( # type: ignore[misc] name="", # type: str parent_sampled=None, # type: Optional[bool] baggage=None, # type: Optional[Baggage] - source=TransactionSource.CUSTOM.value, # type: str + source=TransactionSource.CUSTOM, # type: str **kwargs, # type: Unpack[SpanKwargs] ): # type: (...) -> None diff --git a/tests/integrations/asgi/test_asgi.py b/tests/integrations/asgi/test_asgi.py index 228ce36f1e..f95ea14d01 100644 --- a/tests/integrations/asgi/test_asgi.py +++ b/tests/integrations/asgi/test_asgi.py @@ -131,7 +131,7 @@ async def app(scope, receive, send): def asgi3_custom_transaction_app(): async def app(scope, receive, send): sentry_sdk.get_current_scope().set_transaction_name( - "foobar", source=TransactionSource.CUSTOM.value + "foobar", source=TransactionSource.CUSTOM ) await send( { diff --git a/tests/integrations/sanic/test_sanic.py b/tests/integrations/sanic/test_sanic.py index 872930bc2d..0419127239 100644 --- a/tests/integrations/sanic/test_sanic.py +++ b/tests/integrations/sanic/test_sanic.py @@ -370,7 +370,7 @@ def __init__( url="/message", expected_status=200, expected_transaction_name="hi", - expected_source=TransactionSource.COMPONENT.value, + expected_source=TransactionSource.COMPONENT, ), TransactionTestConfig( # Transaction still recorded when we have an internal server error @@ -378,7 +378,7 @@ def __init__( url="/500", expected_status=500, expected_transaction_name="fivehundred", - expected_source=TransactionSource.COMPONENT.value, + expected_source=TransactionSource.COMPONENT, ), TransactionTestConfig( # By default, no transaction when we have a 404 error @@ -393,7 +393,7 @@ def __init__( url="/404", expected_status=404, expected_transaction_name="/404", - expected_source=TransactionSource.URL.value, + expected_source=TransactionSource.URL, ), TransactionTestConfig( # Transaction can be suppressed for other HTTP statuses, too, by passing config to the integration diff --git a/tests/test_metrics.py b/tests/test_metrics.py index f382abded3..c02f075288 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -539,7 +539,7 @@ def test_transaction_name( envelopes = capture_envelopes() sentry_sdk.get_current_scope().set_transaction_name( - "/user/{user_id}", source=TransactionSource.ROUTE.value + "/user/{user_id}", source=TransactionSource.ROUTE ) metrics.distribution("dist", 1.0, tags={"a": "b"}, timestamp=ts) metrics.distribution("dist", 2.0, tags={"a": "b"}, timestamp=ts) @@ -581,7 +581,7 @@ def test_metric_summaries( envelopes = capture_envelopes() with sentry_sdk.start_transaction( - op="stuff", name="/foo", source=TransactionSource.ROUTE.value + op="stuff", name="/foo", source=TransactionSource.ROUTE ) as transaction: metrics.increment("root-counter", timestamp=ts) with metrics.timing("my-timer-metric", tags={"a": "b"}, timestamp=ts): From 2a3f7a86d45ad299f283d636799749e64495621d Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Feb 2025 09:33:35 +0100 Subject: [PATCH 3/8] Formatting --- sentry_sdk/integrations/sanic.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sentry_sdk/integrations/sanic.py b/sentry_sdk/integrations/sanic.py index 492133dfcb..bd8f1f329b 100644 --- a/sentry_sdk/integrations/sanic.py +++ b/sentry_sdk/integrations/sanic.py @@ -229,9 +229,7 @@ async def _set_transaction(request, route, **_): with capture_internal_exceptions(): scope = sentry_sdk.get_current_scope() route_name = route.name.replace(request.app.name, "").strip(".") - scope.set_transaction_name( - route_name, source=TransactionSource.COMPONENT - ) + scope.set_transaction_name(route_name, source=TransactionSource.COMPONENT) def _sentry_error_handler_lookup(self, exception, *args, **kwargs): From bc4de2d18958f2a6b0fb83ca5c4a35588de8acdf Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Feb 2025 16:21:26 +0100 Subject: [PATCH 4/8] Fix clickhouse in our test suite --- .github/workflows/test-integrations-dbs.yml | 20 +++++++++++++++++-- .../templates/test_group.jinja | 10 +++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-integrations-dbs.yml b/.github/workflows/test-integrations-dbs.yml index d525e353ed..bb6e15dadc 100644 --- a/.github/workflows/test-integrations-dbs.yml +++ b/.github/workflows/test-integrations-dbs.yml @@ -59,7 +59,15 @@ jobs: with: python-version: ${{ matrix.python-version }} allow-prereleases: true - - uses: getsentry/action-clickhouse-in-ci@v1.1 + - name: "Setup ClickHouse Server" + uses: getsentry/action-clickhouse-in-ci@v1.2 + - name: Ensure ClickHouse Ready + run: | + set -x + sleep 3 + docker ps + docker logs clickhouse-test + curl -i 'http://localhost:8123/' --data-binary 'SELECT * FROM system.build_options' - name: Setup Test Env run: | pip install "coverage[toml]" tox @@ -154,7 +162,15 @@ jobs: with: python-version: ${{ matrix.python-version }} allow-prereleases: true - - uses: getsentry/action-clickhouse-in-ci@v1.1 + - name: "Setup ClickHouse Server" + uses: getsentry/action-clickhouse-in-ci@v1.2 + - name: Ensure ClickHouse Ready + run: | + set -x + sleep 3 + docker ps + docker logs clickhouse-test + curl -i 'http://localhost:8123/' --data-binary 'SELECT * FROM system.build_options' - name: Setup Test Env run: | pip install "coverage[toml]" tox diff --git a/scripts/split_tox_gh_actions/templates/test_group.jinja b/scripts/split_tox_gh_actions/templates/test_group.jinja index 66e346511d..b6e02551c0 100644 --- a/scripts/split_tox_gh_actions/templates/test_group.jinja +++ b/scripts/split_tox_gh_actions/templates/test_group.jinja @@ -51,7 +51,15 @@ python-version: {% raw %}${{ matrix.python-version }}{% endraw %} allow-prereleases: true {% if needs_clickhouse %} - - uses: getsentry/action-clickhouse-in-ci@v1.1 + - name: "Setup ClickHouse Server" + uses: getsentry/action-clickhouse-in-ci@v1.2 + - name: Ensure ClickHouse Ready + run: | + set -x + sleep 3 + docker ps + docker logs clickhouse-test + curl -i 'http://localhost:8123/' --data-binary 'SELECT * FROM system.build_options' {% endif %} {% if needs_redis %} From 0f0e46ba8a5bb9d878e75159c5e13cc16cc84966 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Feb 2025 16:32:37 +0100 Subject: [PATCH 5/8] The status output should be in the action. --- .github/workflows/test-integrations-dbs.yml | 18 ++---------------- .../templates/test_group.jinja | 9 +-------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/.github/workflows/test-integrations-dbs.yml b/.github/workflows/test-integrations-dbs.yml index bb6e15dadc..93e1a10e0c 100644 --- a/.github/workflows/test-integrations-dbs.yml +++ b/.github/workflows/test-integrations-dbs.yml @@ -60,14 +60,7 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.2 - - name: Ensure ClickHouse Ready - run: | - set -x - sleep 3 - docker ps - docker logs clickhouse-test - curl -i 'http://localhost:8123/' --data-binary 'SELECT * FROM system.build_options' + uses: getsentry/action-clickhouse-in-ci@v1.3 - name: Setup Test Env run: | pip install "coverage[toml]" tox @@ -163,14 +156,7 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.2 - - name: Ensure ClickHouse Ready - run: | - set -x - sleep 3 - docker ps - docker logs clickhouse-test - curl -i 'http://localhost:8123/' --data-binary 'SELECT * FROM system.build_options' + uses: getsentry/action-clickhouse-in-ci@v1.3 - name: Setup Test Env run: | pip install "coverage[toml]" tox diff --git a/scripts/split_tox_gh_actions/templates/test_group.jinja b/scripts/split_tox_gh_actions/templates/test_group.jinja index b6e02551c0..27b0af90da 100644 --- a/scripts/split_tox_gh_actions/templates/test_group.jinja +++ b/scripts/split_tox_gh_actions/templates/test_group.jinja @@ -52,14 +52,7 @@ allow-prereleases: true {% if needs_clickhouse %} - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.2 - - name: Ensure ClickHouse Ready - run: | - set -x - sleep 3 - docker ps - docker logs clickhouse-test - curl -i 'http://localhost:8123/' --data-binary 'SELECT * FROM system.build_options' + uses: getsentry/action-clickhouse-in-ci@v1.3 {% endif %} {% if needs_redis %} From 4a8b5a990f1739ec0b6680abfdc7aa8621d7a7b0 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Feb 2025 16:42:58 +0100 Subject: [PATCH 6/8] New version is fixed (hopefully) --- .github/workflows/test-integrations-dbs.yml | 4 ++-- scripts/split_tox_gh_actions/templates/test_group.jinja | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-integrations-dbs.yml b/.github/workflows/test-integrations-dbs.yml index 93e1a10e0c..9677f0d10f 100644 --- a/.github/workflows/test-integrations-dbs.yml +++ b/.github/workflows/test-integrations-dbs.yml @@ -60,7 +60,7 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.3 + uses: getsentry/action-clickhouse-in-ci@v1.4 - name: Setup Test Env run: | pip install "coverage[toml]" tox @@ -156,7 +156,7 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.3 + uses: getsentry/action-clickhouse-in-ci@v1.4 - name: Setup Test Env run: | pip install "coverage[toml]" tox diff --git a/scripts/split_tox_gh_actions/templates/test_group.jinja b/scripts/split_tox_gh_actions/templates/test_group.jinja index 27b0af90da..96abaad3b1 100644 --- a/scripts/split_tox_gh_actions/templates/test_group.jinja +++ b/scripts/split_tox_gh_actions/templates/test_group.jinja @@ -52,7 +52,7 @@ allow-prereleases: true {% if needs_clickhouse %} - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.3 + uses: getsentry/action-clickhouse-in-ci@v1.4 {% endif %} {% if needs_redis %} From 09553e62df436f5b25861a28ec6c37e0de5d0daa Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Feb 2025 16:47:14 +0100 Subject: [PATCH 7/8] bump version --- .github/workflows/test-integrations-dbs.yml | 4 ++-- scripts/split_tox_gh_actions/templates/test_group.jinja | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-integrations-dbs.yml b/.github/workflows/test-integrations-dbs.yml index 9677f0d10f..1fb0aa0715 100644 --- a/.github/workflows/test-integrations-dbs.yml +++ b/.github/workflows/test-integrations-dbs.yml @@ -60,7 +60,7 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.4 + uses: getsentry/action-clickhouse-in-ci@v1.5 - name: Setup Test Env run: | pip install "coverage[toml]" tox @@ -156,7 +156,7 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.4 + uses: getsentry/action-clickhouse-in-ci@v1.5 - name: Setup Test Env run: | pip install "coverage[toml]" tox diff --git a/scripts/split_tox_gh_actions/templates/test_group.jinja b/scripts/split_tox_gh_actions/templates/test_group.jinja index 96abaad3b1..01f9cd56ec 100644 --- a/scripts/split_tox_gh_actions/templates/test_group.jinja +++ b/scripts/split_tox_gh_actions/templates/test_group.jinja @@ -52,7 +52,7 @@ allow-prereleases: true {% if needs_clickhouse %} - name: "Setup ClickHouse Server" - uses: getsentry/action-clickhouse-in-ci@v1.4 + uses: getsentry/action-clickhouse-in-ci@v1.5 {% endif %} {% if needs_redis %} From 954a10227944cb7aa0509f44c1e0113953d93324 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Feb 2025 17:17:00 +0100 Subject: [PATCH 8/8] linting --- sentry_sdk/tracing.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 13fd04cf8e..cf708b839e 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -140,6 +140,7 @@ class TransactionSource(str, Enum): VIEW = "view" def __str__(self): + # type: () -> str return self.value