From 6b099241f2e79b307cae90af59a7b008d18f76f4 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 10:14:20 +0200 Subject: [PATCH 01/12] Unified naming for span ops. --- sentry_sdk/consts.py | 23 +++++++++++++ sentry_sdk/integrations/aiohttp.py | 3 +- sentry_sdk/integrations/asgi.py | 3 +- sentry_sdk/integrations/aws_lambda.py | 3 +- sentry_sdk/integrations/boto3.py | 5 +-- sentry_sdk/integrations/celery.py | 7 ++-- sentry_sdk/integrations/django/__init__.py | 3 +- sentry_sdk/integrations/django/asgi.py | 3 +- sentry_sdk/integrations/django/middleware.py | 3 +- .../integrations/django/signals_handlers.py | 3 +- sentry_sdk/integrations/django/templates.py | 5 +-- sentry_sdk/integrations/django/views.py | 3 +- sentry_sdk/integrations/gcp.py | 3 +- sentry_sdk/integrations/httpx.py | 5 +-- sentry_sdk/integrations/redis.py | 7 ++-- sentry_sdk/integrations/rq.py | 3 +- sentry_sdk/integrations/starlette.py | 3 +- sentry_sdk/integrations/stdlib.py | 11 +++--- sentry_sdk/integrations/tornado.py | 3 +- sentry_sdk/integrations/wsgi.py | 3 +- sentry_sdk/tracing_utils.py | 7 ++-- tests/integrations/aws_lambda/test_aws.py | 7 ++-- tests/integrations/boto3/test_s3.py | 11 +++--- tests/integrations/celery/test_celery.py | 5 +-- tests/integrations/django/asgi/test_asgi.py | 14 ++++---- tests/integrations/django/test_basic.py | 34 +++++++++---------- tests/integrations/gcp/test_gcp.py | 6 ++-- tests/integrations/redis/test_redis.py | 3 +- .../rediscluster/test_rediscluster.py | 3 +- tests/integrations/rq/test_rq.py | 5 +-- .../integrations/starlette/test_starlette.py | 3 +- 31 files changed, 129 insertions(+), 71 deletions(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index ceba6b512e..39ad7cec1d 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -110,3 +110,26 @@ def _get_default_options(): "version": VERSION, "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}], } + + +class OP: + ASGI_SERVER = "asgi.server" + DB = "db" + DB_REDIS = "db.redis" + EVENT_DJANGO = "event.django" + FUNCTION_AWS_LAMBDA = "function.aws.lambda" + FUNCTION_GCP = "function.gcp" + HTTP_CLIENT = "http.client" + HTTP_CLIENT_STREAM = "http.client.stream" + HTTP_SERVER = "http.server" + MIDDLEWARE_DJANGO = "middleware.django" + MIDDLEWARE_STARLETTE = "middleware.starlette" + QUEUE_SUBMIT_CELERY = "queue.submit.celery" + QUEUE_TASK_CELERY = "queue.task.celery" + QUEUE_TASK_RQ = "queue.task.rq" + SUBPROCESS = "subprocess" + SUBPROCESS_WAIT = "subprocess.wait" + SUBPROCESS_COMMUNICATE = "subprocess.communicate" + TEMPLATE_RENDER = "template.render" + VIEW_DJANGO = "view.django" + WEBSOCKET_SERVER = "websocket.server" diff --git a/sentry_sdk/integrations/aiohttp.py b/sentry_sdk/integrations/aiohttp.py index c9a637eeb4..5b9db91bdb 100644 --- a/sentry_sdk/integrations/aiohttp.py +++ b/sentry_sdk/integrations/aiohttp.py @@ -2,6 +2,7 @@ import weakref from sentry_sdk._compat import reraise +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.integrations.logging import ignore_logger @@ -99,7 +100,7 @@ async def sentry_app_handle(self, request, *args, **kwargs): transaction = Transaction.continue_from_headers( request.headers, - op="http.server", + op=OP.HTTP_SERVER, # 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", diff --git a/sentry_sdk/integrations/asgi.py b/sentry_sdk/integrations/asgi.py index 67e6eac230..90848752af 100644 --- a/sentry_sdk/integrations/asgi.py +++ b/sentry_sdk/integrations/asgi.py @@ -10,6 +10,7 @@ from sentry_sdk._functools import partial from sentry_sdk._types import MYPY +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.integrations._wsgi_common import _filter_headers from sentry_sdk.integrations.modules import _get_installed_modules @@ -166,7 +167,7 @@ async def _run_app(self, scope, callback): op="{}.server".format(ty), ) else: - transaction = Transaction(op="asgi.server") + transaction = Transaction(op=OP.ASGI_SERVER) transaction.name = _DEFAULT_TRANSACTION_NAME transaction.source = TRANSACTION_SOURCE_ROUTE diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 365247781c..20e1a3eb3f 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -1,6 +1,7 @@ from datetime import datetime, timedelta from os import environ import sys +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, Transaction @@ -140,7 +141,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): headers = {} transaction = Transaction.continue_from_headers( headers, - op="serverless.function", + op=OP.FUNCTION_AWS_LAMBDA, name=aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT, ) diff --git a/sentry_sdk/integrations/boto3.py b/sentry_sdk/integrations/boto3.py index e65f5a754b..2f2f6bbea9 100644 --- a/sentry_sdk/integrations/boto3.py +++ b/sentry_sdk/integrations/boto3.py @@ -1,6 +1,7 @@ from __future__ import absolute_import from sentry_sdk import Hub +from sentry_sdk.consts import OP from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.tracing import Span @@ -62,7 +63,7 @@ def _sentry_request_created(service_id, request, operation_name, **kwargs): description = "aws.%s.%s" % (service_id, operation_name) span = hub.start_span( hub=hub, - op="aws.request", + op=OP.HTTP_CLIENT, description=description, ) span.set_tag("aws.service_id", service_id) @@ -92,7 +93,7 @@ def _sentry_after_call(context, parsed, **kwargs): return streaming_span = span.start_child( - op="aws.request.stream", + op=OP.HTTP_CLIENT_STREAM, description=span.description, ) diff --git a/sentry_sdk/integrations/celery.py b/sentry_sdk/integrations/celery.py index 2a095ec8c6..ea865b35a4 100644 --- a/sentry_sdk/integrations/celery.py +++ b/sentry_sdk/integrations/celery.py @@ -1,6 +1,7 @@ from __future__ import absolute_import import sys +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub from sentry_sdk.tracing import TRANSACTION_SOURCE_TASK @@ -103,7 +104,9 @@ def apply_async(*args, **kwargs): hub = Hub.current integration = hub.get_integration(CeleryIntegration) if integration is not None and integration.propagate_traces: - with hub.start_span(op="celery.submit", description=args[0].name) as span: + with hub.start_span( + op=OP.QUEUE_SUBMIT_CELERY, description=args[0].name + ) as span: with capture_internal_exceptions(): headers = dict(hub.iter_trace_propagation_headers(span)) @@ -156,7 +159,7 @@ def _inner(*args, **kwargs): with capture_internal_exceptions(): transaction = Transaction.continue_from_headers( args[3].get("headers") or {}, - op="celery.task", + op=OP.QUEUE_TASK_CELERY, name="unknown celery task", source=TRANSACTION_SOURCE_TASK, ) diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index 23b446f2d7..67a0bf3844 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -6,6 +6,7 @@ import weakref from sentry_sdk._types import MYPY +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.scope import add_global_event_processor from sentry_sdk.serializer import add_global_repr_processor @@ -581,7 +582,7 @@ def connect(self): with capture_internal_exceptions(): hub.add_breadcrumb(message="connect", category="query") - with hub.start_span(op="db", description="connect"): + with hub.start_span(op=OP.DB, description="connect"): return real_connect(self) CursorWrapper.execute = execute diff --git a/sentry_sdk/integrations/django/asgi.py b/sentry_sdk/integrations/django/asgi.py index 79916e94fb..2bdbab7249 100644 --- a/sentry_sdk/integrations/django/asgi.py +++ b/sentry_sdk/integrations/django/asgi.py @@ -10,6 +10,7 @@ from sentry_sdk import Hub, _functools from sentry_sdk._types import MYPY +from sentry_sdk.consts import OP from sentry_sdk.integrations.asgi import SentryAsgiMiddleware @@ -89,7 +90,7 @@ async def sentry_wrapped_callback(request, *args, **kwargs): # type: (Any, *Any, **Any) -> Any with hub.start_span( - op="django.view", description=request.resolver_match.view_name + op=OP.VIEW_DJANGO, description=request.resolver_match.view_name ): return await callback(request, *args, **kwargs) diff --git a/sentry_sdk/integrations/django/middleware.py b/sentry_sdk/integrations/django/middleware.py index c9001cdbf4..35680e10b1 100644 --- a/sentry_sdk/integrations/django/middleware.py +++ b/sentry_sdk/integrations/django/middleware.py @@ -7,6 +7,7 @@ from sentry_sdk import Hub from sentry_sdk._functools import wraps from sentry_sdk._types import MYPY +from sentry_sdk.consts import OP from sentry_sdk.utils import ( ContextVar, transaction_from_function, @@ -88,7 +89,7 @@ def _check_middleware_span(old_method): description = "{}.{}".format(description, function_basename) middleware_span = hub.start_span( - op="django.middleware", description=description + op=OP.MIDDLEWARE_DJANGO, description=description ) middleware_span.set_tag("django.function_name", function_name) middleware_span.set_tag("django.middleware_name", middleware_name) diff --git a/sentry_sdk/integrations/django/signals_handlers.py b/sentry_sdk/integrations/django/signals_handlers.py index 4d81772452..e207a4b711 100644 --- a/sentry_sdk/integrations/django/signals_handlers.py +++ b/sentry_sdk/integrations/django/signals_handlers.py @@ -5,6 +5,7 @@ from sentry_sdk import Hub from sentry_sdk._types import MYPY +from sentry_sdk.consts import OP if MYPY: @@ -50,7 +51,7 @@ def wrapper(*args, **kwargs): # type: (Any, Any) -> Any signal_name = _get_receiver_name(receiver) with hub.start_span( - op="django.signals", + op=OP.EVENT_DJANGO, description=signal_name, ) as span: span.set_data("signal", signal_name) diff --git a/sentry_sdk/integrations/django/templates.py b/sentry_sdk/integrations/django/templates.py index 2ff9d1b184..39279be4ce 100644 --- a/sentry_sdk/integrations/django/templates.py +++ b/sentry_sdk/integrations/django/templates.py @@ -3,6 +3,7 @@ from sentry_sdk import _functools, Hub from sentry_sdk._types import MYPY +from sentry_sdk.consts import OP if MYPY: from typing import Any @@ -66,7 +67,7 @@ def rendered_content(self): return real_rendered_content.fget(self) with hub.start_span( - op="django.template.render", + op=OP.TEMPLATE_RENDER, description=_get_template_name_description(self.template_name), ) as span: span.set_data("context", self.context_data) @@ -88,7 +89,7 @@ def render(request, template_name, context=None, *args, **kwargs): return real_render(request, template_name, context, *args, **kwargs) with hub.start_span( - op="django.template.render", + op=OP.TEMPLATE_RENDER, description=_get_template_name_description(template_name), ) as span: span.set_data("context", context) diff --git a/sentry_sdk/integrations/django/views.py b/sentry_sdk/integrations/django/views.py index 51f1abc8fb..37175ddbf9 100644 --- a/sentry_sdk/integrations/django/views.py +++ b/sentry_sdk/integrations/django/views.py @@ -1,3 +1,4 @@ +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub from sentry_sdk._types import MYPY from sentry_sdk import _functools @@ -62,7 +63,7 @@ def _wrap_sync_view(hub, callback): def sentry_wrapped_callback(request, *args, **kwargs): # type: (Any, *Any, **Any) -> Any with hub.start_span( - op="django.view", description=request.resolver_match.view_name + op=OP.VIEW_DJANGO, description=request.resolver_match.view_name ): return callback(request, *args, **kwargs) diff --git a/sentry_sdk/integrations/gcp.py b/sentry_sdk/integrations/gcp.py index 6025d38c45..a69637a409 100644 --- a/sentry_sdk/integrations/gcp.py +++ b/sentry_sdk/integrations/gcp.py @@ -1,6 +1,7 @@ from datetime import datetime, timedelta from os import environ import sys +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, Transaction @@ -82,7 +83,7 @@ def sentry_func(functionhandler, gcp_event, *args, **kwargs): headers = gcp_event.headers transaction = Transaction.continue_from_headers( headers, - op="serverless.function", + op=OP.FUNCTION_GCP, name=environ.get("FUNCTION_NAME", ""), source=TRANSACTION_SOURCE_COMPONENT, ) diff --git a/sentry_sdk/integrations/httpx.py b/sentry_sdk/integrations/httpx.py index 3d4bbf8300..2e9142d2b8 100644 --- a/sentry_sdk/integrations/httpx.py +++ b/sentry_sdk/integrations/httpx.py @@ -1,4 +1,5 @@ from sentry_sdk import Hub +from sentry_sdk.consts import OP from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.utils import logger @@ -41,7 +42,7 @@ def send(self, request, **kwargs): return real_send(self, request, **kwargs) with hub.start_span( - op="http", description="%s %s" % (request.method, request.url) + op=OP.HTTP_CLIENT, description="%s %s" % (request.method, request.url) ) as span: span.set_data("method", request.method) span.set_data("url", str(request.url)) @@ -73,7 +74,7 @@ async def send(self, request, **kwargs): return await real_send(self, request, **kwargs) with hub.start_span( - op="http", description="%s %s" % (request.method, request.url) + op=OP.HTTP_CLIENT, description="%s %s" % (request.method, request.url) ) as span: span.set_data("method", request.method) span.set_data("url", str(request.url)) diff --git a/sentry_sdk/integrations/redis.py b/sentry_sdk/integrations/redis.py index c27eefa3f6..aae5647f3d 100644 --- a/sentry_sdk/integrations/redis.py +++ b/sentry_sdk/integrations/redis.py @@ -1,6 +1,7 @@ from __future__ import absolute_import from sentry_sdk import Hub +from sentry_sdk.consts import OP from sentry_sdk.utils import capture_internal_exceptions, logger from sentry_sdk.integrations import Integration, DidNotEnable @@ -29,7 +30,9 @@ def sentry_patched_execute(self, *args, **kwargs): if hub.get_integration(RedisIntegration) is None: return old_execute(self, *args, **kwargs) - with hub.start_span(op="redis", description="redis.pipeline.execute") as span: + with hub.start_span( + op=OP.DB_REDIS, description="redis.pipeline.execute" + ) as span: with capture_internal_exceptions(): span.set_tag("redis.is_cluster", is_cluster) transaction = self.transaction if not is_cluster else False @@ -152,7 +155,7 @@ def sentry_patched_execute_command(self, name, *args, **kwargs): description = " ".join(description_parts) - with hub.start_span(op="redis", description=description) as span: + with hub.start_span(op=OP.DB_REDIS, description=description) as span: span.set_tag("redis.is_cluster", is_cluster) if name: span.set_tag("redis.command", name) diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py index 095ab357a7..8b174c46ef 100644 --- a/sentry_sdk/integrations/rq.py +++ b/sentry_sdk/integrations/rq.py @@ -1,6 +1,7 @@ from __future__ import absolute_import import weakref +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub from sentry_sdk.integrations import DidNotEnable, Integration @@ -61,7 +62,7 @@ def sentry_patched_perform_job(self, job, *args, **kwargs): transaction = Transaction.continue_from_headers( job.meta.get("_sentry_trace_headers") or {}, - op="rq.task", + op=OP.QUEUE_TASK_RQ, name="unknown RQ task", source=TRANSACTION_SOURCE_TASK, ) diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index 28993611e6..dffba5afd5 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -5,6 +5,7 @@ from sentry_sdk._compat import iteritems from sentry_sdk._types import MYPY +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations._wsgi_common import ( @@ -91,7 +92,7 @@ async def _create_span_call(*args, **kwargs): if integration is not None: middleware_name = args[0].__class__.__name__ with hub.start_span( - op="starlette.middleware", description=middleware_name + op=OP.MIDDLEWARE_STARLETTE, description=middleware_name ) as middleware_span: middleware_span.set_tag("starlette.middleware_name", middleware_name) diff --git a/sentry_sdk/integrations/stdlib.py b/sentry_sdk/integrations/stdlib.py index 9495d406dc..8790713a8e 100644 --- a/sentry_sdk/integrations/stdlib.py +++ b/sentry_sdk/integrations/stdlib.py @@ -2,6 +2,7 @@ import subprocess import sys import platform +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub from sentry_sdk.integrations import Integration @@ -78,7 +79,9 @@ def putrequest(self, method, url, *args, **kwargs): url, ) - span = hub.start_span(op="http", description="%s %s" % (method, real_url)) + span = hub.start_span( + op=OP.HTTP_CLIENT, description="%s %s" % (method, real_url) + ) span.set_data("method", method) span.set_data("url", real_url) @@ -183,7 +186,7 @@ def sentry_patched_popen_init(self, *a, **kw): env = None - with hub.start_span(op="subprocess", description=description) as span: + with hub.start_span(op=OP.SUBPROCESS, description=description) as span: for k, v in hub.iter_trace_propagation_headers(span): if env is None: @@ -211,7 +214,7 @@ def sentry_patched_popen_wait(self, *a, **kw): if hub.get_integration(StdlibIntegration) is None: return old_popen_wait(self, *a, **kw) - with hub.start_span(op="subprocess.wait") as span: + with hub.start_span(op=OP.SUBPROCESS_WAIT) as span: span.set_tag("subprocess.pid", self.pid) return old_popen_wait(self, *a, **kw) @@ -226,7 +229,7 @@ def sentry_patched_popen_communicate(self, *a, **kw): if hub.get_integration(StdlibIntegration) is None: return old_popen_communicate(self, *a, **kw) - with hub.start_span(op="subprocess.communicate") as span: + with hub.start_span(op=OP.SUBPROCESS_COMMUNICATE) as span: span.set_tag("subprocess.pid", self.pid) return old_popen_communicate(self, *a, **kw) diff --git a/sentry_sdk/integrations/tornado.py b/sentry_sdk/integrations/tornado.py index b4a639b136..a64f4f5b11 100644 --- a/sentry_sdk/integrations/tornado.py +++ b/sentry_sdk/integrations/tornado.py @@ -1,6 +1,7 @@ import weakref import contextlib from inspect import iscoroutinefunction +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.tracing import ( @@ -114,7 +115,7 @@ def _handle_request_impl(self): transaction = Transaction.continue_from_headers( self.request.headers, - op="http.server", + op=OP.HTTP_SERVER, # Like with all other integrations, this is our # fallback transaction in case there is no route. # sentry_urldispatcher_resolve is responsible for diff --git a/sentry_sdk/integrations/wsgi.py b/sentry_sdk/integrations/wsgi.py index 31ffe224ba..03ce665489 100644 --- a/sentry_sdk/integrations/wsgi.py +++ b/sentry_sdk/integrations/wsgi.py @@ -1,6 +1,7 @@ import sys from sentry_sdk._functools import partial +from sentry_sdk.consts import OP from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.utils import ( ContextVar, @@ -124,7 +125,7 @@ def __call__(self, environ, start_response): transaction = Transaction.continue_from_environ( environ, - op="http.server", + op=OP.HTTP_SERVER, name="generic WSGI request", source=TRANSACTION_SOURCE_ROUTE, ) diff --git a/sentry_sdk/tracing_utils.py b/sentry_sdk/tracing_utils.py index 80bbcc2d50..61d630321a 100644 --- a/sentry_sdk/tracing_utils.py +++ b/sentry_sdk/tracing_utils.py @@ -6,6 +6,7 @@ from numbers import Real import sentry_sdk +from sentry_sdk.consts import OP from sentry_sdk.utils import ( capture_internal_exceptions, @@ -189,7 +190,7 @@ def record_sql_queries( with capture_internal_exceptions(): hub.add_breadcrumb(message=query, category="query", data=data) - with hub.start_span(op="db", description=query) as span: + with hub.start_span(op=OP.DB, description=query) as span: for k, v in data.items(): span.set_data(k, v) yield span @@ -197,11 +198,11 @@ def record_sql_queries( def maybe_create_breadcrumbs_from_span(hub, span): # type: (sentry_sdk.Hub, Span) -> None - if span.op == "redis": + if span.op == OP.DB_REDIS: hub.add_breadcrumb( message=span.description, type="redis", category="redis", data=span._tags ) - elif span.op == "http": + elif span.op == OP.HTTP_CLIENT: hub.add_breadcrumb(type="http", category="httplib", data=span._data) elif span.op == "subprocess": hub.add_breadcrumb( diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index 458f55bf1a..f9fb50412a 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -21,6 +21,7 @@ from textwrap import dedent import pytest +from sentry_sdk.consts import OP boto3 = pytest.importorskip("boto3") @@ -360,7 +361,7 @@ def test_handler(event, context): (envelope,) = envelopes assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == "serverless.function" + assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_AWS_LAMBDA assert envelope["transaction"].startswith("test_function_") assert envelope["transaction_info"] == {"source": "component"} assert envelope["transaction"] in envelope["request"]["url"] @@ -389,7 +390,7 @@ def test_handler(event, context): (envelope,) = envelopes assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == "serverless.function" + assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_AWS_LAMBDA assert envelope["transaction"].startswith("test_function_") assert envelope["transaction_info"] == {"source": "component"} assert envelope["transaction"] in envelope["request"]["url"] @@ -476,7 +477,7 @@ def test_handler(event, context): error_event = events[0] assert error_event["level"] == "error" - assert error_event["contexts"]["trace"]["op"] == "serverless.function" + assert error_event["contexts"]["trace"]["op"] == OP.FUNCTION_AWS_LAMBDA function_name = error_event["extra"]["lambda"]["function_name"] assert function_name.startswith("test_function_") diff --git a/tests/integrations/boto3/test_s3.py b/tests/integrations/boto3/test_s3.py index 67376b55d4..7be104532b 100644 --- a/tests/integrations/boto3/test_s3.py +++ b/tests/integrations/boto3/test_s3.py @@ -1,4 +1,5 @@ from sentry_sdk import Hub +from sentry_sdk.consts import OP from sentry_sdk.integrations.boto3 import Boto3Integration from tests.integrations.boto3.aws_mock import MockResponse from tests.integrations.boto3 import read_fixture @@ -30,7 +31,7 @@ def test_basic(sentry_init, capture_events): assert event["type"] == "transaction" assert len(event["spans"]) == 1 (span,) = event["spans"] - assert span["op"] == "aws.request" + assert span["op"] == OP.HTTP_CLIENT assert span["description"] == "aws.s3.ListObjects" @@ -54,10 +55,10 @@ def test_streaming(sentry_init, capture_events): assert event["type"] == "transaction" assert len(event["spans"]) == 2 span1 = event["spans"][0] - assert span1["op"] == "aws.request" + assert span1["op"] == OP.HTTP_CLIENT assert span1["description"] == "aws.s3.GetObject" span2 = event["spans"][1] - assert span2["op"] == "aws.request.stream" + assert span2["op"] == OP.HTTP_CLIENT_STREAM assert span2["description"] == "aws.s3.GetObject" assert span2["parent_span_id"] == span1["span_id"] @@ -80,6 +81,6 @@ def test_streaming_close(sentry_init, capture_events): assert event["type"] == "transaction" assert len(event["spans"]) == 2 span1 = event["spans"][0] - assert span1["op"] == "aws.request" + assert span1["op"] == OP.HTTP_CLIENT span2 = event["spans"][1] - assert span2["op"] == "aws.request.stream" + assert span2["op"] == OP.HTTP_CLIENT_STREAM diff --git a/tests/integrations/celery/test_celery.py b/tests/integrations/celery/test_celery.py index 2c52031701..ad58bc9aba 100644 --- a/tests/integrations/celery/test_celery.py +++ b/tests/integrations/celery/test_celery.py @@ -1,6 +1,7 @@ import threading import pytest +from sentry_sdk.consts import OP pytest.importorskip("celery") @@ -174,7 +175,7 @@ def dummy_task(x, y): assert submission_event["spans"] == [ { "description": "dummy_task", - "op": "celery.submit", + "op": OP.QUEUE_SUBMIT_CELERY, "parent_span_id": submission_event["contexts"]["trace"]["span_id"], "same_process_as_parent": True, "span_id": submission_event["spans"][0]["span_id"], @@ -347,7 +348,7 @@ def dummy_task(self): submit_transaction["spans"] ), 4 # Because redis integration was auto enabled span = submit_transaction["spans"][0] - assert span["op"] == "celery.submit" + assert span["op"] == OP.QUEUE_SUBMIT_CELERY assert span["description"] == "dummy_task" event = events.read_event() diff --git a/tests/integrations/django/asgi/test_asgi.py b/tests/integrations/django/asgi/test_asgi.py index 2b3382b9b4..93f4f19c85 100644 --- a/tests/integrations/django/asgi/test_asgi.py +++ b/tests/integrations/django/asgi/test_asgi.py @@ -150,7 +150,7 @@ async def test_async_middleware_spans( settings.MIDDLEWARE = [ "django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.middleware.csrf.CsrfViewMiddleware", + "middleware.django.csrf.CsrfViewMiddleware", "tests.integrations.django.myapp.settings.TestMiddleware", ] asgi_application.load_middleware(is_async=True) @@ -177,12 +177,12 @@ async def test_async_middleware_spans( - op="http.server": description=null - op="django.signals": description="django.db.reset_queries" - op="django.signals": description="django.db.close_old_connections" - - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.__acall__" - - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.__acall__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.__acall__" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.__acall__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="django.view": description="async_message" + - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.__acall__" + - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.__acall__" + - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.__acall__" + - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__acall__" + - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_view" + - op="view.django": description="async_message" - op="django.signals": description="django.db.close_old_connections" - op="django.signals": description="django.core.cache.close_caches" - op="django.signals": description="django.core.handlers.base.reset_urlconf\"""" diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index a62f1bb073..ee139f15da 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -666,14 +666,14 @@ def test_render_spans(sentry_init, client, capture_events, render_span_tree): views_tests = [ ( reverse("template_test2"), - '- op="django.template.render": description="[user_name.html, ...]"', + '- op="template.render": description="[user_name.html, ...]"', ), ] if DJANGO_VERSION >= (1, 7): views_tests.append( ( reverse("template_test"), - '- op="django.template.render": description="user_name.html"', + '- op="template.render": description="user_name.html"', ), ) @@ -705,13 +705,13 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) - op="http.server": description=null - op="django.signals": description="django.db.reset_queries" - op="django.signals": description="django.db.close_old_connections" - - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" - - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.__call__" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="django.view": description="message"\ + - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" + - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" + - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.__call__" + - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" + - op="middleware.django": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" + - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_view" + - op="view.django": description="message"\ """ ) @@ -722,14 +722,14 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) - op="http.server": description=null - op="django.signals": description="django.db.reset_queries" - op="django.signals": description="django.db.close_old_connections" - - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.process_request" - - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.process_request" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.process_request" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="django.view": description="message" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.process_response" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_response" - - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.process_response"\ + - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.process_request" + - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.process_request" + - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.process_request" + - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_view" + - op="view.django": description="message" + - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.process_response" + - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_response" + - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.process_response"\ """ ) diff --git a/tests/integrations/gcp/test_gcp.py b/tests/integrations/gcp/test_gcp.py index 5f41300bcb..b66cbb9d6e 100644 --- a/tests/integrations/gcp/test_gcp.py +++ b/tests/integrations/gcp/test_gcp.py @@ -12,6 +12,8 @@ import os.path import os +from sentry_sdk.consts import OP + pytestmark = pytest.mark.skipif( not hasattr(tempfile, "TemporaryDirectory"), reason="need Python 3.2+" ) @@ -253,7 +255,7 @@ def cloud_function(functionhandler, event): ) assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == "serverless.function" + assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_GCP assert envelope["transaction"].startswith("Google Cloud function") assert envelope["transaction_info"] == {"source": "component"} assert envelope["transaction"] in envelope["request"]["url"] @@ -279,7 +281,7 @@ def cloud_function(functionhandler, event): ) assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == "serverless.function" + assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_GCP assert envelope["transaction"].startswith("Google Cloud function") assert envelope["transaction"] in envelope["request"]["url"] assert event["level"] == "error" diff --git a/tests/integrations/redis/test_redis.py b/tests/integrations/redis/test_redis.py index 4b3f2a7bb0..86f3726081 100644 --- a/tests/integrations/redis/test_redis.py +++ b/tests/integrations/redis/test_redis.py @@ -1,4 +1,5 @@ from sentry_sdk import capture_message, start_transaction +from sentry_sdk.consts import OP from sentry_sdk.integrations.redis import RedisIntegration from fakeredis import FakeStrictRedis @@ -46,7 +47,7 @@ def test_redis_pipeline(sentry_init, capture_events, is_transaction): (event,) = events (span,) = event["spans"] - assert span["op"] == "redis" + assert span["op"] == OP.DB_REDIS assert span["description"] == "redis.pipeline.execute" assert span["data"] == { "redis.commands": { diff --git a/tests/integrations/rediscluster/test_rediscluster.py b/tests/integrations/rediscluster/test_rediscluster.py index 62923cffae..a53766e27e 100644 --- a/tests/integrations/rediscluster/test_rediscluster.py +++ b/tests/integrations/rediscluster/test_rediscluster.py @@ -1,6 +1,7 @@ import pytest from sentry_sdk import capture_message from sentry_sdk.api import start_transaction +from sentry_sdk.consts import OP from sentry_sdk.integrations.redis import RedisIntegration import rediscluster @@ -65,7 +66,7 @@ def test_rediscluster_pipeline(sentry_init, capture_events): (event,) = events (span,) = event["spans"] - assert span["op"] == "redis" + assert span["op"] == OP.DB_REDIS assert span["description"] == "redis.pipeline.execute" assert span["data"] == { "redis.commands": { diff --git a/tests/integrations/rq/test_rq.py b/tests/integrations/rq/test_rq.py index 651bf22248..1d350fbad4 100644 --- a/tests/integrations/rq/test_rq.py +++ b/tests/integrations/rq/test_rq.py @@ -1,5 +1,6 @@ import pytest from fakeredis import FakeStrictRedis +from sentry_sdk.consts import OP from sentry_sdk.integrations.rq import RqIntegration import rq @@ -101,7 +102,7 @@ def test_transaction_with_error( error_event, envelope = events assert error_event["transaction"] == "tests.integrations.rq.test_rq.chew_up_shoes" - assert error_event["contexts"]["trace"]["op"] == "rq.task" + assert error_event["contexts"]["trace"]["op"] == OP.QUEUE_TASK_RQ assert error_event["exception"]["values"][0]["type"] == "Exception" assert ( error_event["exception"]["values"][0]["value"] @@ -136,7 +137,7 @@ def test_transaction_no_error( envelope = events[0] assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == "rq.task" + assert envelope["contexts"]["trace"]["op"] == OP.QUEUE_TASK_RQ assert envelope["transaction"] == "tests.integrations.rq.test_rq.do_trick" assert envelope["extra"]["rq-job"] == DictionaryContaining( { diff --git a/tests/integrations/starlette/test_starlette.py b/tests/integrations/starlette/test_starlette.py index 5908ebae52..19e11df632 100644 --- a/tests/integrations/starlette/test_starlette.py +++ b/tests/integrations/starlette/test_starlette.py @@ -6,6 +6,7 @@ import pytest from sentry_sdk import last_event_id, capture_exception +from sentry_sdk.consts import OP from sentry_sdk.integrations.asgi import SentryAsgiMiddleware try: @@ -540,7 +541,7 @@ def test_middleware_spans(sentry_init, capture_events): idx = 0 for span in transaction_event["spans"]: - if span["op"] == "starlette.middleware": + if span["op"] == OP.MIDDLEWARE_STARLETTE: assert span["description"] == expected[idx] assert span["tags"]["starlette.middleware_name"] == expected[idx] idx += 1 From 216285752bc02654bbef58dd5894ed3f6c65cdac Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 11:23:03 +0200 Subject: [PATCH 02/12] Fixed tests for Django --- tests/integrations/django/asgi/test_asgi.py | 10 +++++----- tests/integrations/django/test_basic.py | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/integrations/django/asgi/test_asgi.py b/tests/integrations/django/asgi/test_asgi.py index 93f4f19c85..ed05688493 100644 --- a/tests/integrations/django/asgi/test_asgi.py +++ b/tests/integrations/django/asgi/test_asgi.py @@ -175,15 +175,15 @@ async def test_async_middleware_spans( render_span_tree(transaction) == """\ - op="http.server": description=null - - op="django.signals": description="django.db.reset_queries" - - op="django.signals": description="django.db.close_old_connections" + - op="event.django": description="django.db.reset_queries" + - op="event.django": description="django.db.close_old_connections" - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.__acall__" - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.__acall__" - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.__acall__" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__acall__" - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_view" - op="view.django": description="async_message" - - op="django.signals": description="django.db.close_old_connections" - - op="django.signals": description="django.core.cache.close_caches" - - op="django.signals": description="django.core.handlers.base.reset_urlconf\"""" + - op="event.django": description="django.db.close_old_connections" + - op="event.django": description="django.core.cache.close_caches" + - op="event.django": description="django.core.handlers.base.reset_urlconf\"""" ) diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index ee139f15da..def2a52912 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -19,7 +19,7 @@ from sentry_sdk._compat import PY2 from sentry_sdk import capture_message, capture_exception, configure_scope from sentry_sdk.integrations.django import DjangoIntegration -from sentry_sdk.integrations.django.signals_handlers import _get_receiver_name +from sentry_sdk.integrations.event.django_handlers import _get_receiver_name from sentry_sdk.integrations.executing import ExecutingIntegration from tests.integrations.django.myapp.wsgi import application @@ -703,8 +703,8 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) render_span_tree(transaction) == """\ - op="http.server": description=null - - op="django.signals": description="django.db.reset_queries" - - op="django.signals": description="django.db.close_old_connections" + - op="event.django": description="django.db.reset_queries" + - op="event.django": description="django.db.close_old_connections" - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.__call__" @@ -720,8 +720,8 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) render_span_tree(transaction) == """\ - op="http.server": description=null - - op="django.signals": description="django.db.reset_queries" - - op="django.signals": description="django.db.close_old_connections" + - op="event.django": description="django.db.reset_queries" + - op="event.django": description="django.db.close_old_connections" - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.process_request" - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.process_request" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.process_request" @@ -748,10 +748,10 @@ def test_middleware_spans_disabled(sentry_init, client, capture_events): assert len(transaction["spans"]) == 2 - assert transaction["spans"][0]["op"] == "django.signals" + assert transaction["spans"][0]["op"] == "event.django" assert transaction["spans"][0]["description"] == "django.db.reset_queries" - assert transaction["spans"][1]["op"] == "django.signals" + assert transaction["spans"][1]["op"] == "event.django" assert transaction["spans"][1]["description"] == "django.db.close_old_connections" From 8a7fb27deb546dbc8167b9862d705744d778951c Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 11:29:31 +0200 Subject: [PATCH 03/12] Made ops in test hard coded to see when ops change --- tests/integrations/aws_lambda/test_aws.py | 7 +++---- tests/integrations/boto3/test_s3.py | 11 +++++------ tests/integrations/celery/test_celery.py | 5 ++--- tests/integrations/gcp/test_gcp.py | 6 ++---- tests/integrations/redis/test_redis.py | 3 +-- tests/integrations/rediscluster/test_rediscluster.py | 3 +-- tests/integrations/rq/test_rq.py | 5 ++--- tests/integrations/starlette/test_starlette.py | 3 +-- 8 files changed, 17 insertions(+), 26 deletions(-) diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index f9fb50412a..78c9770317 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -21,7 +21,6 @@ from textwrap import dedent import pytest -from sentry_sdk.consts import OP boto3 = pytest.importorskip("boto3") @@ -361,7 +360,7 @@ def test_handler(event, context): (envelope,) = envelopes assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_AWS_LAMBDA + assert envelope["contexts"]["trace"]["op"] == "function.aws.lambda" assert envelope["transaction"].startswith("test_function_") assert envelope["transaction_info"] == {"source": "component"} assert envelope["transaction"] in envelope["request"]["url"] @@ -390,7 +389,7 @@ def test_handler(event, context): (envelope,) = envelopes assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_AWS_LAMBDA + assert envelope["contexts"]["trace"]["op"] == "function.aws.lambda" assert envelope["transaction"].startswith("test_function_") assert envelope["transaction_info"] == {"source": "component"} assert envelope["transaction"] in envelope["request"]["url"] @@ -477,7 +476,7 @@ def test_handler(event, context): error_event = events[0] assert error_event["level"] == "error" - assert error_event["contexts"]["trace"]["op"] == OP.FUNCTION_AWS_LAMBDA + assert error_event["contexts"]["trace"]["op"] == "function.aws.lambda" function_name = error_event["extra"]["lambda"]["function_name"] assert function_name.startswith("test_function_") diff --git a/tests/integrations/boto3/test_s3.py b/tests/integrations/boto3/test_s3.py index 7be104532b..7f02d422a0 100644 --- a/tests/integrations/boto3/test_s3.py +++ b/tests/integrations/boto3/test_s3.py @@ -1,5 +1,4 @@ from sentry_sdk import Hub -from sentry_sdk.consts import OP from sentry_sdk.integrations.boto3 import Boto3Integration from tests.integrations.boto3.aws_mock import MockResponse from tests.integrations.boto3 import read_fixture @@ -31,7 +30,7 @@ def test_basic(sentry_init, capture_events): assert event["type"] == "transaction" assert len(event["spans"]) == 1 (span,) = event["spans"] - assert span["op"] == OP.HTTP_CLIENT + assert span["op"] == "http.client" assert span["description"] == "aws.s3.ListObjects" @@ -55,10 +54,10 @@ def test_streaming(sentry_init, capture_events): assert event["type"] == "transaction" assert len(event["spans"]) == 2 span1 = event["spans"][0] - assert span1["op"] == OP.HTTP_CLIENT + assert span1["op"] == "http.client" assert span1["description"] == "aws.s3.GetObject" span2 = event["spans"][1] - assert span2["op"] == OP.HTTP_CLIENT_STREAM + assert span2["op"] == "http.client.stream" assert span2["description"] == "aws.s3.GetObject" assert span2["parent_span_id"] == span1["span_id"] @@ -81,6 +80,6 @@ def test_streaming_close(sentry_init, capture_events): assert event["type"] == "transaction" assert len(event["spans"]) == 2 span1 = event["spans"][0] - assert span1["op"] == OP.HTTP_CLIENT + assert span1["op"] == "http.client" span2 = event["spans"][1] - assert span2["op"] == OP.HTTP_CLIENT_STREAM + assert span2["op"] == "http.client.stream" diff --git a/tests/integrations/celery/test_celery.py b/tests/integrations/celery/test_celery.py index ad58bc9aba..a2c8fa1594 100644 --- a/tests/integrations/celery/test_celery.py +++ b/tests/integrations/celery/test_celery.py @@ -1,7 +1,6 @@ import threading import pytest -from sentry_sdk.consts import OP pytest.importorskip("celery") @@ -175,7 +174,7 @@ def dummy_task(x, y): assert submission_event["spans"] == [ { "description": "dummy_task", - "op": OP.QUEUE_SUBMIT_CELERY, + "op": "queue.submit.celery", "parent_span_id": submission_event["contexts"]["trace"]["span_id"], "same_process_as_parent": True, "span_id": submission_event["spans"][0]["span_id"], @@ -348,7 +347,7 @@ def dummy_task(self): submit_transaction["spans"] ), 4 # Because redis integration was auto enabled span = submit_transaction["spans"][0] - assert span["op"] == OP.QUEUE_SUBMIT_CELERY + assert span["op"] == "queue.submit.celery" assert span["description"] == "dummy_task" event = events.read_event() diff --git a/tests/integrations/gcp/test_gcp.py b/tests/integrations/gcp/test_gcp.py index b66cbb9d6e..3ccdbd752a 100644 --- a/tests/integrations/gcp/test_gcp.py +++ b/tests/integrations/gcp/test_gcp.py @@ -12,8 +12,6 @@ import os.path import os -from sentry_sdk.consts import OP - pytestmark = pytest.mark.skipif( not hasattr(tempfile, "TemporaryDirectory"), reason="need Python 3.2+" ) @@ -255,7 +253,7 @@ def cloud_function(functionhandler, event): ) assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_GCP + assert envelope["contexts"]["trace"]["op"] == "function.gcp" assert envelope["transaction"].startswith("Google Cloud function") assert envelope["transaction_info"] == {"source": "component"} assert envelope["transaction"] in envelope["request"]["url"] @@ -281,7 +279,7 @@ def cloud_function(functionhandler, event): ) assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == OP.FUNCTION_GCP + assert envelope["contexts"]["trace"]["op"] == "function.gcp" assert envelope["transaction"].startswith("Google Cloud function") assert envelope["transaction"] in envelope["request"]["url"] assert event["level"] == "error" diff --git a/tests/integrations/redis/test_redis.py b/tests/integrations/redis/test_redis.py index 86f3726081..9a6d066e03 100644 --- a/tests/integrations/redis/test_redis.py +++ b/tests/integrations/redis/test_redis.py @@ -1,5 +1,4 @@ from sentry_sdk import capture_message, start_transaction -from sentry_sdk.consts import OP from sentry_sdk.integrations.redis import RedisIntegration from fakeredis import FakeStrictRedis @@ -47,7 +46,7 @@ def test_redis_pipeline(sentry_init, capture_events, is_transaction): (event,) = events (span,) = event["spans"] - assert span["op"] == OP.DB_REDIS + assert span["op"] == "db.redis" assert span["description"] == "redis.pipeline.execute" assert span["data"] == { "redis.commands": { diff --git a/tests/integrations/rediscluster/test_rediscluster.py b/tests/integrations/rediscluster/test_rediscluster.py index a53766e27e..6c7e5f90a4 100644 --- a/tests/integrations/rediscluster/test_rediscluster.py +++ b/tests/integrations/rediscluster/test_rediscluster.py @@ -1,7 +1,6 @@ import pytest from sentry_sdk import capture_message from sentry_sdk.api import start_transaction -from sentry_sdk.consts import OP from sentry_sdk.integrations.redis import RedisIntegration import rediscluster @@ -66,7 +65,7 @@ def test_rediscluster_pipeline(sentry_init, capture_events): (event,) = events (span,) = event["spans"] - assert span["op"] == OP.DB_REDIS + assert span["op"] == "db.redis" assert span["description"] == "redis.pipeline.execute" assert span["data"] == { "redis.commands": { diff --git a/tests/integrations/rq/test_rq.py b/tests/integrations/rq/test_rq.py index 1d350fbad4..b6aec29daa 100644 --- a/tests/integrations/rq/test_rq.py +++ b/tests/integrations/rq/test_rq.py @@ -1,6 +1,5 @@ import pytest from fakeredis import FakeStrictRedis -from sentry_sdk.consts import OP from sentry_sdk.integrations.rq import RqIntegration import rq @@ -102,7 +101,7 @@ def test_transaction_with_error( error_event, envelope = events assert error_event["transaction"] == "tests.integrations.rq.test_rq.chew_up_shoes" - assert error_event["contexts"]["trace"]["op"] == OP.QUEUE_TASK_RQ + assert error_event["contexts"]["trace"]["op"] == "queue.task.rq" assert error_event["exception"]["values"][0]["type"] == "Exception" assert ( error_event["exception"]["values"][0]["value"] @@ -137,7 +136,7 @@ def test_transaction_no_error( envelope = events[0] assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"]["op"] == OP.QUEUE_TASK_RQ + assert envelope["contexts"]["trace"]["op"] == "queue.task.rq" assert envelope["transaction"] == "tests.integrations.rq.test_rq.do_trick" assert envelope["extra"]["rq-job"] == DictionaryContaining( { diff --git a/tests/integrations/starlette/test_starlette.py b/tests/integrations/starlette/test_starlette.py index 19e11df632..24254b69ef 100644 --- a/tests/integrations/starlette/test_starlette.py +++ b/tests/integrations/starlette/test_starlette.py @@ -6,7 +6,6 @@ import pytest from sentry_sdk import last_event_id, capture_exception -from sentry_sdk.consts import OP from sentry_sdk.integrations.asgi import SentryAsgiMiddleware try: @@ -541,7 +540,7 @@ def test_middleware_spans(sentry_init, capture_events): idx = 0 for span in transaction_event["spans"]: - if span["op"] == OP.MIDDLEWARE_STARLETTE: + if span["op"] == "middleware.starlette": assert span["description"] == expected[idx] assert span["tags"]["starlette.middleware_name"] == expected[idx] idx += 1 From 05098d5935285caa7c580e79569ce3219a09e128 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 11:36:02 +0200 Subject: [PATCH 04/12] Fixed copy-paste error --- tests/integrations/django/test_basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index def2a52912..894aeccb10 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -19,7 +19,7 @@ from sentry_sdk._compat import PY2 from sentry_sdk import capture_message, capture_exception, configure_scope from sentry_sdk.integrations.django import DjangoIntegration -from sentry_sdk.integrations.event.django_handlers import _get_receiver_name +from sentry_sdk.integrations.django.signals_handlers import _get_receiver_name from sentry_sdk.integrations.executing import ExecutingIntegration from tests.integrations.django.myapp.wsgi import application From 55d7d25624f1d07221d18244f06cd5871d64d8b6 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 11:41:56 +0200 Subject: [PATCH 05/12] Fixed copy-paste error (again) --- tests/integrations/django/test_basic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index 894aeccb10..83c6ab6553 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -707,10 +707,10 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) - op="event.django": description="django.db.close_old_connections" - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" - - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.__call__" + - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.__call__" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" - - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_view" + - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - op="view.django": description="message"\ """ ) @@ -725,10 +725,10 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.process_request" - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.process_request" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.process_request" - - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_view" + - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - op="view.django": description="message" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.process_response" - - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_response" + - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_response" - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.process_response"\ """ ) From d788b187c38d1fdfc7fb4a00d504dd2a2b126069 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 11:50:36 +0200 Subject: [PATCH 06/12] Fixed copy-paste error (again2) --- tests/integrations/django/asgi/test_asgi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integrations/django/asgi/test_asgi.py b/tests/integrations/django/asgi/test_asgi.py index ed05688493..c52866fece 100644 --- a/tests/integrations/django/asgi/test_asgi.py +++ b/tests/integrations/django/asgi/test_asgi.py @@ -150,7 +150,7 @@ async def test_async_middleware_spans( settings.MIDDLEWARE = [ "django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", - "middleware.django.csrf.CsrfViewMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", "tests.integrations.django.myapp.settings.TestMiddleware", ] asgi_application.load_middleware(is_async=True) @@ -179,9 +179,9 @@ async def test_async_middleware_spans( - op="event.django": description="django.db.close_old_connections" - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.__acall__" - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.__acall__" - - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.__acall__" + - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.__acall__" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__acall__" - - op="middleware.django": description="middleware.django.csrf.CsrfViewMiddleware.process_view" + - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - op="view.django": description="async_message" - op="event.django": description="django.db.close_old_connections" - op="event.django": description="django.core.cache.close_caches" From d23b78a22dbd09352a8967e658c340ae480904f2 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 16:47:59 +0200 Subject: [PATCH 07/12] Using view.render instead of view.django --- sentry_sdk/consts.py | 2 +- sentry_sdk/integrations/django/asgi.py | 2 +- sentry_sdk/integrations/django/views.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 39ad7cec1d..919c1c5877 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -131,5 +131,5 @@ class OP: SUBPROCESS_WAIT = "subprocess.wait" SUBPROCESS_COMMUNICATE = "subprocess.communicate" TEMPLATE_RENDER = "template.render" - VIEW_DJANGO = "view.django" + VIEW_RENDER = "view.render" WEBSOCKET_SERVER = "websocket.server" diff --git a/sentry_sdk/integrations/django/asgi.py b/sentry_sdk/integrations/django/asgi.py index 2bdbab7249..5803a7e29b 100644 --- a/sentry_sdk/integrations/django/asgi.py +++ b/sentry_sdk/integrations/django/asgi.py @@ -90,7 +90,7 @@ async def sentry_wrapped_callback(request, *args, **kwargs): # type: (Any, *Any, **Any) -> Any with hub.start_span( - op=OP.VIEW_DJANGO, description=request.resolver_match.view_name + op=OP.VIEW_RENDER, description=request.resolver_match.view_name ): return await callback(request, *args, **kwargs) diff --git a/sentry_sdk/integrations/django/views.py b/sentry_sdk/integrations/django/views.py index 37175ddbf9..fdec84b086 100644 --- a/sentry_sdk/integrations/django/views.py +++ b/sentry_sdk/integrations/django/views.py @@ -63,7 +63,7 @@ def _wrap_sync_view(hub, callback): def sentry_wrapped_callback(request, *args, **kwargs): # type: (Any, *Any, **Any) -> Any with hub.start_span( - op=OP.VIEW_DJANGO, description=request.resolver_match.view_name + op=OP.VIEW_RENDER, description=request.resolver_match.view_name ): return callback(request, *args, **kwargs) From 165d9ef351cf9ca86e0c427fca30e2baaf480200 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 17:30:27 +0200 Subject: [PATCH 08/12] Fixed tests --- tests/integrations/django/asgi/test_asgi.py | 2 +- tests/integrations/django/test_basic.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integrations/django/asgi/test_asgi.py b/tests/integrations/django/asgi/test_asgi.py index c52866fece..70fd416188 100644 --- a/tests/integrations/django/asgi/test_asgi.py +++ b/tests/integrations/django/asgi/test_asgi.py @@ -182,7 +182,7 @@ async def test_async_middleware_spans( - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.__acall__" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__acall__" - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="view.django": description="async_message" + - op="view.render": description="async_message" - op="event.django": description="django.db.close_old_connections" - op="event.django": description="django.core.cache.close_caches" - op="event.django": description="django.core.handlers.base.reset_urlconf\"""" diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index 83c6ab6553..bb99b92f94 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -711,7 +711,7 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="view.django": description="message"\ + - op="view.render": description="message"\ """ ) @@ -726,7 +726,7 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree) - op="middleware.django": description="django.contrib.auth.middleware.AuthenticationMiddleware.process_request" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.process_request" - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="view.django": description="message" + - op="view.render": description="message" - op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.process_response" - op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_response" - op="middleware.django": description="django.contrib.sessions.middleware.SessionMiddleware.process_response"\ From 290b7ee1eb3bf0805e76de83ea8498f8059087eb Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 17:44:44 +0200 Subject: [PATCH 09/12] Trigger CI again. From 0a40cb20dd0ea7e57d1e12affd49544ba79d7879 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Thu, 6 Oct 2022 09:53:55 +0200 Subject: [PATCH 10/12] Use http.server instead of python specific asgi.server --- sentry_sdk/consts.py | 1 - sentry_sdk/integrations/asgi.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 919c1c5877..61c9db02d8 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -113,7 +113,6 @@ def _get_default_options(): class OP: - ASGI_SERVER = "asgi.server" DB = "db" DB_REDIS = "db.redis" EVENT_DJANGO = "event.django" diff --git a/sentry_sdk/integrations/asgi.py b/sentry_sdk/integrations/asgi.py index 90848752af..cfeaf4d298 100644 --- a/sentry_sdk/integrations/asgi.py +++ b/sentry_sdk/integrations/asgi.py @@ -167,7 +167,7 @@ async def _run_app(self, scope, callback): op="{}.server".format(ty), ) else: - transaction = Transaction(op=OP.ASGI_SERVER) + transaction = Transaction(op=OP.HTTP_SERVER) transaction.name = _DEFAULT_TRANSACTION_NAME transaction.source = TRANSACTION_SOURCE_ROUTE From 38afcf8684e48dd1e1290223b74e90c261981a9a Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Mon, 10 Oct 2022 08:57:14 +0200 Subject: [PATCH 11/12] Renamed aws lambda function op --- sentry_sdk/consts.py | 2 +- sentry_sdk/integrations/aws_lambda.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 61c9db02d8..f2d5649c5e 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -116,7 +116,7 @@ class OP: DB = "db" DB_REDIS = "db.redis" EVENT_DJANGO = "event.django" - FUNCTION_AWS_LAMBDA = "function.aws.lambda" + FUNCTION_AWS = "function.aws" FUNCTION_GCP = "function.gcp" HTTP_CLIENT = "http.client" HTTP_CLIENT_STREAM = "http.client.stream" diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 20e1a3eb3f..6017adfa7b 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -141,7 +141,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): headers = {} transaction = Transaction.continue_from_headers( headers, - op=OP.FUNCTION_AWS_LAMBDA, + op=OP.FUNCTION_AWS, name=aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT, ) From 8fa612997aba526c1146aea22b2ec6e0ff5e6dad Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Mon, 10 Oct 2022 14:31:48 +0200 Subject: [PATCH 12/12] Updated changelog --- CHANGELOG.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f661d0b2a..47c02117ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## 1.9.11 + +### Various fixes & improvements + +- Unified naming of span "op"s (#1643) by @antonpirker + + We have unified the strings of our span operations. See https://develop.sentry.dev/sdk/performance/span-operations/ + + **WARNING:** If you have dashboards defined that use `transaction.op` in their fields, conditions, aggregates or columns please check them before updating to this version of the SDK. + + Here a list of all the changes: + + | Old operation (`op`) | New Operation (`op`) | + | ------------------------ | ---------------------- | + | `asgi.server` | `http.server` | + | `aws.request` | `http.client` | + | `aws.request.stream` | `http.client.stream` | + | `celery.submit` | `queue.submit.celery` | + | `celery.task` | `queue.task.celery` | + | `django.middleware` | `middleware.django` | + | `django.signals` | `event.django` | + | `django.template.render` | `template.render` | + | `django.view` | `view.render` | + | `http` | `http.client` | + | `redis` | `db.redis` | + | `rq.task` | `queue.task.rq` | + | `serverless.function` | `function.aws` | + | `serverless.function` | `function.gcp` | + | `starlette.middleware` | `middleware.starlette` | + ## 1.9.10 ### Various fixes & improvements @@ -158,7 +188,7 @@ We can do better and in the future we will do our best to not break your code ag - fix: avoid sending empty Baggage header (#1507) by @intgr - fix: properly freeze Baggage object (#1508) by @intgr -- docs: fix simple typo, collecter -> collector (#1505) by @timgates42 +- docs: fix simple typo, collecter | collector (#1505) by @timgates42 ## 1.7.2