Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add origin to spans and transactions #3133

Merged
merged 20 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,13 @@ def get_baggage():
return None


def continue_trace(environ_or_headers, op=None, name=None, source=None):
# type: (Dict[str, Any], Optional[str], Optional[str], Optional[str]) -> Transaction
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
"""
Sets the propagation context from environment or headers and returns a transaction.
"""
return Scope.get_isolation_scope().continue_trace(
environ_or_headers, op, name, source
environ_or_headers, op, name, source, origin
)
3 changes: 3 additions & 0 deletions sentry_sdk/integrations/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@

class AioHttpIntegration(Integration):
identifier = "aiohttp"
origin = f"auto.http.{identifier}"

def __init__(self, transaction_style="handler_name"):
# type: (str) -> None
Expand Down Expand Up @@ -120,6 +121,7 @@ async def sentry_app_handle(self, request, *args, **kwargs):
# URL resolver did not find a route or died trying.
name="generic AIOHTTP request",
source=TRANSACTION_SOURCE_ROUTE,
origin=AioHttpIntegration.origin,
)
with sentry_sdk.start_transaction(
transaction,
Expand Down Expand Up @@ -206,6 +208,7 @@ async def on_request_start(session, trace_config_ctx, params):
op=OP.HTTP_CLIENT,
description="%s %s"
% (method, parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE),
origin=AioHttpIntegration.origin,
)
span.set_data(SPANDATA.HTTP_METHOD, method)
if parsed_url is not None:
Expand Down
5 changes: 4 additions & 1 deletion sentry_sdk/integrations/anthropic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

class AnthropicIntegration(Integration):
identifier = "anthropic"
origin = f"auto.ai.{identifier}"

def __init__(self, include_prompts=True):
# type: (AnthropicIntegration, bool) -> None
Expand Down Expand Up @@ -92,7 +93,9 @@ def _sentry_patched_create(*args, **kwargs):
model = kwargs.get("model")

span = sentry_sdk.start_span(
op=OP.ANTHROPIC_MESSAGES_CREATE, description="Anthropic messages create"
op=OP.ANTHROPIC_MESSAGES_CREATE,
description="Anthropic messages create",
origin=AnthropicIntegration.origin,
)
span.__enter__()

Expand Down
6 changes: 5 additions & 1 deletion sentry_sdk/integrations/arq.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

class ArqIntegration(Integration):
identifier = "arq"
origin = f"auto.queue.{identifier}"

@staticmethod
def setup_once():
Expand Down Expand Up @@ -76,7 +77,9 @@ async def _sentry_enqueue_job(self, function, *args, **kwargs):
if integration is None:
return await old_enqueue_job(self, function, *args, **kwargs)

with sentry_sdk.start_span(op=OP.QUEUE_SUBMIT_ARQ, description=function):
with sentry_sdk.start_span(
op=OP.QUEUE_SUBMIT_ARQ, description=function, origin=ArqIntegration.origin
):
return await old_enqueue_job(self, function, *args, **kwargs)

ArqRedis.enqueue_job = _sentry_enqueue_job
Expand All @@ -101,6 +104,7 @@ async def _sentry_run_job(self, job_id, score):
status="ok",
op=OP.QUEUE_TASK_ARQ,
source=TRANSACTION_SOURCE_TASK,
origin=ArqIntegration.origin,
)

with sentry_sdk.start_transaction(transaction):
Expand Down
17 changes: 14 additions & 3 deletions sentry_sdk/integrations/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,23 @@ def _looks_like_asgi3(app):


class SentryAsgiMiddleware:
__slots__ = ("app", "__call__", "transaction_style", "mechanism_type")
__slots__ = (
"app",
"__call__",
"transaction_style",
"mechanism_type",
"span_origin",
)

def __init__(
self,
app,
unsafe_context_data=False,
transaction_style="endpoint",
mechanism_type="asgi",
span_origin="manual",
):
# type: (Any, bool, str, str) -> None
# type: (Any, bool, str, str, str) -> None
"""
Instrument an ASGI application with Sentry. Provides HTTP/websocket
data to sent events and basic handling for exceptions bubbling up
Expand Down Expand Up @@ -124,6 +131,7 @@ def __init__(

self.transaction_style = transaction_style
self.mechanism_type = mechanism_type
self.span_origin = span_origin
self.app = app

if _looks_like_asgi3(app):
Expand Down Expand Up @@ -182,6 +190,7 @@ async def _run_app(self, scope, receive, send, asgi_version):
op="{}.server".format(ty),
name=transaction_name,
source=transaction_source,
origin=self.span_origin,
)
logger.debug(
"[ASGI] Created transaction (continuing trace): %s",
Expand All @@ -192,6 +201,7 @@ async def _run_app(self, scope, receive, send, asgi_version):
op=OP.HTTP_SERVER,
name=transaction_name,
source=transaction_source,
origin=self.span_origin,
)
logger.debug(
"[ASGI] Created transaction (new): %s", transaction
Expand All @@ -205,7 +215,8 @@ async def _run_app(self, scope, receive, send, asgi_version):
)

with sentry_sdk.start_transaction(
transaction, custom_sampling_context={"asgi_scope": scope}
transaction,
custom_sampling_context={"asgi_scope": scope},
):
logger.debug("[ASGI] Started transaction: %s", transaction)
try:
Expand Down
5 changes: 4 additions & 1 deletion sentry_sdk/integrations/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ async def _coro_creating_hub_and_span():

with sentry_sdk.isolation_scope():
with sentry_sdk.start_span(
op=OP.FUNCTION, description=get_name(coro)
op=OP.FUNCTION,
description=get_name(coro),
origin=AsyncioIntegration.origin,
):
try:
result = await coro
Expand Down Expand Up @@ -97,6 +99,7 @@ def _capture_exception():

class AsyncioIntegration(Integration):
identifier = "asyncio"
origin = f"auto.function.{identifier}"

@staticmethod
def setup_once():
Expand Down
25 changes: 19 additions & 6 deletions sentry_sdk/integrations/asyncpg.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

class AsyncPGIntegration(Integration):
identifier = "asyncpg"
origin = f"auto.db.{identifier}"
_record_params = False

def __init__(self, *, record_params: bool = False):
Expand Down Expand Up @@ -69,7 +70,14 @@ async def _inner(*args: Any, **kwargs: Any) -> T:
return await f(*args, **kwargs)

query = args[1]
with record_sql_queries(None, query, None, None, executemany=False) as span:
with record_sql_queries(
cursor=None,
query=query,
params_list=None,
paramstyle=None,
executemany=False,
span_origin=AsyncPGIntegration.origin,
) as span:
res = await f(*args, **kwargs)

with capture_internal_exceptions():
Expand Down Expand Up @@ -98,12 +106,13 @@ def _record(
param_style = "pyformat" if params_list else None

with record_sql_queries(
cursor,
query,
params_list,
param_style,
cursor=cursor,
query=query,
params_list=params_list,
paramstyle=param_style,
executemany=executemany,
record_cursor_repr=cursor is not None,
span_origin=AsyncPGIntegration.origin,
) as span:
yield span

Expand Down Expand Up @@ -154,7 +163,11 @@ async def _inner(*args: Any, **kwargs: Any) -> T:
user = kwargs["params"].user
database = kwargs["params"].database

with sentry_sdk.start_span(op=OP.DB, description="connect") as span:
with sentry_sdk.start_span(
op=OP.DB,
description="connect",
origin=AsyncPGIntegration.origin,
) as span:
span.set_data(SPANDATA.DB_SYSTEM, "postgresql")
addr = kwargs.get("addr")
if addr:
Expand Down
2 changes: 2 additions & 0 deletions sentry_sdk/integrations/aws_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs):
op=OP.FUNCTION_AWS,
name=aws_context.function_name,
source=TRANSACTION_SOURCE_COMPONENT,
origin=AwsLambdaIntegration.origin,
)
with sentry_sdk.start_transaction(
transaction,
Expand Down Expand Up @@ -178,6 +179,7 @@ def _drain_queue():

class AwsLambdaIntegration(Integration):
identifier = "aws_lambda"
origin = f"auto.function.{identifier}"

def __init__(self, timeout_warning=False):
# type: (bool) -> None
Expand Down
3 changes: 3 additions & 0 deletions sentry_sdk/integrations/boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

class Boto3Integration(Integration):
identifier = "boto3"
origin = f"auto.http.{identifier}"

@staticmethod
def setup_once():
Expand Down Expand Up @@ -69,6 +70,7 @@ def _sentry_request_created(service_id, request, operation_name, **kwargs):
span = sentry_sdk.start_span(
op=OP.HTTP_CLIENT,
description=description,
origin=Boto3Integration.origin,
)

with capture_internal_exceptions():
Expand Down Expand Up @@ -106,6 +108,7 @@ def _sentry_after_call(context, parsed, **kwargs):
streaming_span = span.start_child(
op=OP.HTTP_CLIENT_STREAM,
description=span.description,
origin=Boto3Integration.origin,
)

orig_read = body.read
Expand Down
8 changes: 6 additions & 2 deletions sentry_sdk/integrations/bottle.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

class BottleIntegration(Integration):
identifier = "bottle"
origin = f"auto.http.{identifier}"

transaction_style = ""

Expand Down Expand Up @@ -69,10 +70,13 @@ def setup_once():
@ensure_integration_enabled(BottleIntegration, old_app)
def sentry_patched_wsgi_app(self, environ, start_response):
# type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse
return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))(
environ, start_response
middleware = SentryWsgiMiddleware(
lambda *a, **kw: old_app(self, *a, **kw),
span_origin=BottleIntegration.origin,
)

return middleware(environ, start_response)

Bottle.__call__ = sentry_patched_wsgi_app

old_handle = Bottle._handle
Expand Down
18 changes: 15 additions & 3 deletions sentry_sdk/integrations/celery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@

class CeleryIntegration(Integration):
identifier = "celery"
origin = f"auto.queue.{identifier}"

def __init__(
self,
Expand Down Expand Up @@ -266,7 +267,11 @@ def apply_async(*args, **kwargs):
)

span_mgr = (
sentry_sdk.start_span(op=OP.QUEUE_SUBMIT_CELERY, description=task.name)
sentry_sdk.start_span(
op=OP.QUEUE_SUBMIT_CELERY,
description=task.name,
origin=CeleryIntegration.origin,
)
if not task_started_from_beat
else NoOpMgr()
) # type: Union[Span, NoOpMgr]
Expand Down Expand Up @@ -309,6 +314,7 @@ def _inner(*args, **kwargs):
op=OP.QUEUE_TASK_CELERY,
name="unknown celery task",
source=TRANSACTION_SOURCE_TASK,
origin=CeleryIntegration.origin,
)
transaction.name = task.name
transaction.set_status("ok")
Expand Down Expand Up @@ -362,7 +368,9 @@ def _inner(*args, **kwargs):
# type: (*Any, **Any) -> Any
try:
with sentry_sdk.start_span(
op=OP.QUEUE_PROCESS, description=task.name
op=OP.QUEUE_PROCESS,
description=task.name,
origin=CeleryIntegration.origin,
) as span:
_set_messaging_destination_name(task, span)

Expand Down Expand Up @@ -483,7 +491,11 @@ def sentry_publish(self, *args, **kwargs):
routing_key = kwargs.get("routing_key")
exchange = kwargs.get("exchange")

with sentry_sdk.start_span(op=OP.QUEUE_PUBLISH, description=task_name) as span:
with sentry_sdk.start_span(
op=OP.QUEUE_PUBLISH,
description=task_name,
origin=CeleryIntegration.origin,
) as span:
if task_id is not None:
span.set_data(SPANDATA.MESSAGING_MESSAGE_ID, task_id)

Expand Down
7 changes: 6 additions & 1 deletion sentry_sdk/integrations/clickhouse_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __getitem__(self, _):

class ClickhouseDriverIntegration(Integration):
identifier = "clickhouse_driver"
origin = f"auto.db.{identifier}"

@staticmethod
def setup_once() -> None:
Expand Down Expand Up @@ -81,7 +82,11 @@ def _inner(*args: P.args, **kwargs: P.kwargs) -> T:
query_id = args[2] if len(args) > 2 else kwargs.get("query_id")
params = args[3] if len(args) > 3 else kwargs.get("params")

span = sentry_sdk.start_span(op=OP.DB, description=query)
span = sentry_sdk.start_span(
op=OP.DB,
description=query,
origin=ClickhouseDriverIntegration.origin,
)

connection._sentry_span = span # type: ignore[attr-defined]

Expand Down
3 changes: 3 additions & 0 deletions sentry_sdk/integrations/cohere.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@

class CohereIntegration(Integration):
identifier = "cohere"
origin = f"auto.ai.{identifier}"

def __init__(self, include_prompts=True):
# type: (CohereIntegration, bool) -> None
Expand Down Expand Up @@ -141,6 +142,7 @@ def new_chat(*args, **kwargs):
span = sentry_sdk.start_span(
op=consts.OP.COHERE_CHAT_COMPLETIONS_CREATE,
description="cohere.client.Chat",
origin=CohereIntegration.origin,
)
span.__enter__()
try:
Expand Down Expand Up @@ -225,6 +227,7 @@ def new_embed(*args, **kwargs):
with sentry_sdk.start_span(
op=consts.OP.COHERE_EMBEDDINGS_CREATE,
description="Cohere Embedding Creation",
origin=CohereIntegration.origin,
) as span:
integration = sentry_sdk.get_client().get_integration(CohereIntegration)
if "texts" in kwargs and (
Expand Down
Loading
Loading