From ef97faaa442700122aece41240193dbfe2420c4a Mon Sep 17 00:00:00 2001 From: Marcelo Galigniana Date: Sun, 22 Dec 2024 00:19:09 -0300 Subject: [PATCH] ref(tracing): Move `TRANSACTION_SOURCE_*` constants to `Enum` Fixes GH-2696 --- CHANGELOG.md | 8 ++-- sentry_sdk/api.py | 4 +- sentry_sdk/hub.py | 4 +- sentry_sdk/integrations/aiohttp.py | 4 +- sentry_sdk/integrations/arq.py | 4 +- sentry_sdk/integrations/asgi.py | 19 ++++----- 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 | 10 ++--- sentry_sdk/integrations/starlette.py | 11 +++--- 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/scope.py | 8 ++-- sentry_sdk/tracing.py | 46 ++++++++++++---------- tests/integrations/asgi/test_asgi.py | 5 ++- tests/integrations/sanic/test_sanic.py | 8 ++-- tests/test_metrics.py | 6 +-- 30 files changed, 108 insertions(+), 113 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af4eb04fef..7ff08e370a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2226,7 +2226,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="...", @@ -2246,7 +2246,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): redis = await create_pool(RedisSettings()) for url in ('https://facebook.com', 'https://microsoft.com', 'https://github.com', "asdf" ): @@ -2320,7 +2320,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(): @@ -2332,7 +2332,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): r = add_numbers(1, 2) if __name__ == "__main__": diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index d60434079c..11b65454d5 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -37,7 +37,7 @@ LogLevelStr, SamplingContext, ) - from sentry_sdk.tracing import Span, TransactionKwargs + from sentry_sdk.tracing import Span, TransactionKwargs, TransactionSource T = TypeVar("T") F = TypeVar("F", bound=Callable[..., Any]) @@ -424,7 +424,7 @@ def get_baggage(): def continue_trace( environ_or_headers, op=None, name=None, source=None, origin="manual" ): - # type: (Dict[str, Any], Optional[str], Optional[str], Optional[str], str) -> Transaction + # type: (Dict[str, Any], Optional[str], Optional[str], Optional[TransactionSource], str) -> Transaction """ Sets the propagation context from environment or headers and returns a transaction. """ diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index 7fda9202df..469a53c959 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -52,7 +52,7 @@ LogLevelStr, SamplingContext, ) - from sentry_sdk.tracing import TransactionKwargs + from sentry_sdk.tracing import TransactionKwargs, TransactionSource T = TypeVar("T") @@ -473,7 +473,7 @@ def start_transaction( ) def continue_trace(self, environ_or_headers, op=None, name=None, source=None): - # type: (Dict[str, Any], Optional[str], Optional[str], Optional[str]) -> Transaction + # type: (Dict[str, Any], Optional[str], Optional[str], Optional[TransactionSource]) -> Transaction """ .. deprecated:: 2.0.0 This function is deprecated and will be removed in a future release. diff --git a/sentry_sdk/integrations/aiohttp.py b/sentry_sdk/integrations/aiohttp.py index d0226bc156..432d0b4d29 100644 --- a/sentry_sdk/integrations/aiohttp.py +++ b/sentry_sdk/integrations/aiohttp.py @@ -19,7 +19,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 ( @@ -133,7 +133,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, origin=AioHttpIntegration.origin, ) with sentry_sdk.start_transaction( diff --git a/sentry_sdk/integrations/arq.py b/sentry_sdk/integrations/arq.py index d568714fe2..1d9fc174db 100644 --- a/sentry_sdk/integrations/arq.py +++ b/sentry_sdk/integrations/arq.py @@ -5,7 +5,7 @@ from sentry_sdk.integrations import 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, @@ -104,7 +104,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, origin=ArqIntegration.origin, ) diff --git a/sentry_sdk/integrations/asgi.py b/sentry_sdk/integrations/asgi.py index f5e8665b4f..d033d87d4a 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, + TransactionSource.ROUTE, + TransactionSource.CUSTOM, ] if not already_set: name, source = self._get_transaction_name_and_source( @@ -299,7 +296,7 @@ def event_processor(self, event, hint, asgi_scope): # for that. def _get_transaction_name_and_source(self, transaction_style, asgi_scope): - # type: (SentryAsgiMiddleware, str, Any) -> Tuple[str, str] + # type: (SentryAsgiMiddleware, str, Any) -> Tuple[str, TransactionSource] name = None source = SOURCE_FOR_STYLE[transaction_style] ty = asgi_scope.get("type") @@ -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 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 if name is None: name = _DEFAULT_TRANSACTION_NAME - source = TRANSACTION_SOURCE_ROUTE + 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 831cde8999..ea583a331d 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, 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 9a984de8c3..3b762b9930 100644 --- a/sentry_sdk/integrations/celery/__init__.py +++ b/sentry_sdk/integrations/celery/__init__.py @@ -14,7 +14,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, @@ -320,7 +320,7 @@ def _inner(*args, **kwargs): headers, op=OP.QUEUE_TASK_CELERY, name="unknown celery task", - source=TRANSACTION_SOURCE_TASK, + 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 0754d1f13b..947e41ebf7 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, ) scope.add_event_processor( diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index e68f0cacef..17da7375be 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, @@ -400,7 +400,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 else: source = SOURCE_FOR_STYLE[transaction_style] diff --git a/sentry_sdk/integrations/fastapi.py b/sentry_sdk/integrations/fastapi.py index 8877925a36..76c6adee0f 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 else: source = SOURCE_FOR_STYLE[transaction_style] diff --git a/sentry_sdk/integrations/gcp.py b/sentry_sdk/integrations/gcp.py index 3983f550d3..c637b7414a 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, 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..381c63103e 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, origin=SPAN_ORIGIN, ) diff --git a/sentry_sdk/integrations/grpc/server.py b/sentry_sdk/integrations/grpc/server.py index a640df5e11..0d2792d1b7 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, origin=SPAN_ORIGIN, ) diff --git a/sentry_sdk/integrations/huey.py b/sentry_sdk/integrations/huey.py index 7db57680f6..f0aff4c0dd 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, origin=HueyIntegration.origin, ) transaction.set_status(SPANSTATUS.OK) diff --git a/sentry_sdk/integrations/litestar.py b/sentry_sdk/integrations/litestar.py index 4b04dada8a..96b46722c2 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} event.update( { diff --git a/sentry_sdk/integrations/ray.py b/sentry_sdk/integrations/ray.py index 2f5086ed92..a513e2fe18 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 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, ) with sentry_sdk.start_transaction(transaction) as transaction: diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py index 462f3ad30a..dcb1c5e182 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 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, @@ -63,7 +63,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, origin=RqIntegration.origin, ) diff --git a/sentry_sdk/integrations/sanic.py b/sentry_sdk/integrations/sanic.py index 26e29cb78c..a1f5ddaddf 100644 --- a/sentry_sdk/integrations/sanic.py +++ b/sentry_sdk/integrations/sanic.py @@ -9,7 +9,7 @@ from sentry_sdk.integrations import 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, @@ -198,7 +198,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, origin=SanicIntegration.origin, ) request.ctx._sentry_transaction = sentry_sdk.start_transaction( @@ -235,7 +235,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=TRANSACTION_SOURCE_COMPONENT) + scope.set_transaction_name(route_name, source=TransactionSource.COMPONENT) def _sentry_error_handler_lookup(self, exception, *args, **kwargs): @@ -310,11 +310,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 ) else: scope.set_transaction_name( - rv[0].__name__, source=TRANSACTION_SOURCE_COMPONENT + rv[0].__name__, source=TransactionSource.COMPONENT ) return rv diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index d9db8bd6b8..a81b0edf38 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 scope.set_transaction_name(name, source=source) logger.debug( @@ -723,15 +722,15 @@ def _set_transaction_name_and_source(scope, transaction_style, request): def _get_transaction_from_middleware(app, asgi_scope, integration): - # type: (Any, Dict[str, Any], StarletteIntegration) -> Tuple[Optional[str], Optional[str]] + # type: (Any, Dict[str, Any], StarletteIntegration) -> Tuple[Optional[str], Optional[sentry_sdk.tracing.TransactionSource]] name = None source = None if integration.transaction_style == "endpoint": name = transaction_from_function(app.__class__) - source = TRANSACTION_SOURCE_COMPONENT + source = TransactionSource.COMPONENT elif integration.transaction_style == "url": name = _transaction_name_from_router(asgi_scope) - source = TRANSACTION_SOURCE_ROUTE + source = TransactionSource.ROUTE return name, source diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 8714ee2f08..24707a18b1 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} event.update( { diff --git a/sentry_sdk/integrations/strawberry.py b/sentry_sdk/integrations/strawberry.py index 58860a633b..d10976855d 100644 --- a/sentry_sdk/integrations/strawberry.py +++ b/sentry_sdk/integrations/strawberry.py @@ -7,7 +7,7 @@ from sentry_sdk.integrations import 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, @@ -211,7 +211,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 transaction.op = op self.graphql_span.finish() diff --git a/sentry_sdk/integrations/tornado.py b/sentry_sdk/integrations/tornado.py index f1bd196261..d19ea5eee5 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, @@ -123,7 +120,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, origin=TornadoIntegration.origin, ) @@ -161,7 +158,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} with capture_internal_exceptions(): extractor = TornadoRequestExtractor(request) diff --git a/sentry_sdk/integrations/wsgi.py b/sentry_sdk/integrations/wsgi.py index 50deae10c5..e628e50e69 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, origin=self.span_origin, ) diff --git a/sentry_sdk/metrics.py b/sentry_sdk/metrics.py index f6e9fd6bde..4bdbc62253 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, + TransactionSource.VIEW, + TransactionSource.COMPONENT, + TransactionSource.TASK, ] ) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index bb45143c48..a71e9acc55 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -72,7 +72,7 @@ Type, ) - from sentry_sdk.tracing import TransactionKwargs + from sentry_sdk.tracing import TransactionKwargs, TransactionSource import sentry_sdk @@ -669,7 +669,7 @@ def clear(self): self._level = None # type: Optional[LogLevelStr] self._fingerprint = None # type: Optional[List[str]] self._transaction = None # type: Optional[str] - self._transaction_info = {} # type: MutableMapping[str, str] + self._transaction_info = {} # type: MutableMapping[str, TransactionSource] self._user = None # type: Optional[Dict[str, Any]] self._tags = {} # type: Dict[str, Any] @@ -768,7 +768,7 @@ def transaction(self, value): self._span.containing_transaction.name = value def set_transaction_name(self, name, source=None): - # type: (str, Optional[str]) -> None + # type: (str, Optional[TransactionSource]) -> None """Set the transaction name and optionally the transaction source.""" self._transaction = name @@ -1111,7 +1111,7 @@ def start_span(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs): def continue_trace( self, environ_or_headers, op=None, name=None, source=None, origin="manual" ): - # type: (Dict[str, Any], Optional[str], Optional[str], Optional[str], str) -> Transaction + # type: (Dict[str, Any], Optional[str], Optional[str], Optional[TransactionSource], str) -> Transaction """ Sets the propagation context from environment or headers and returns a transaction. """ diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 3868b2e6c8..fe2d1d49a8 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,18 @@ from typing import TYPE_CHECKING + +# Transaction source +# see https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations +class TransactionSource(Enum): + CUSTOM = "custom" + URL = "url" + ROUTE = "route" + VIEW = "view" + COMPONENT = "component" + TASK = "task" + + if TYPE_CHECKING: from collections.abc import Callable, Mapping, MutableMapping from typing import Any @@ -101,7 +114,7 @@ class SpanKwargs(TypedDict, total=False): """A string describing what operation is being performed within the span/transaction.""" class TransactionKwargs(SpanKwargs, total=False): - source: str + source: TransactionSource """ A string describing the source of the transaction name. This will be used to determine the transaction's type. See https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations for more information. @@ -124,30 +137,21 @@ 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" - # These are typically high cardinality and the server hates them LOW_QUALITY_TRANSACTION_SOURCES = [ - TRANSACTION_SOURCE_URL, + TransactionSource.URL, ] 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, + "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, } @@ -772,7 +776,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, # type: sentry_sdk.tracing.TransactionSource **kwargs, # type: Unpack[SpanKwargs] ): # type: (...) -> None diff --git a/tests/integrations/asgi/test_asgi.py b/tests/integrations/asgi/test_asgi.py index f3bc7147bf..f95ea14d01 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 + ) await send( { "type": "http.response.start", diff --git a/tests/integrations/sanic/test_sanic.py b/tests/integrations/sanic/test_sanic.py index 9d95907144..0419127239 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, ), 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, ), 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, ), 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..c02f075288 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 ) 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 ) as transaction: metrics.increment("root-counter", timestamp=ts) with metrics.timing("my-timer-metric", tags={"a": "b"}, timestamp=ts):