Skip to content

Commit 0f36dce

Browse files
antonpirkerarjenzorgdoc
authored andcommitted
Add origin to spans and transactions (getsentry#3133)
API for adding origin to spans and transactions. Updating all our integrations to send a origin.
1 parent 9855980 commit 0f36dce

File tree

102 files changed

+1899
-135
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+1899
-135
lines changed

sentry_sdk/api.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,13 @@ def get_baggage():
378378
return None
379379

380380

381-
def continue_trace(environ_or_headers, op=None, name=None, source=None):
382-
# type: (Dict[str, Any], Optional[str], Optional[str], Optional[str]) -> Transaction
381+
def continue_trace(
382+
environ_or_headers, op=None, name=None, source=None, origin="manual"
383+
):
384+
# type: (Dict[str, Any], Optional[str], Optional[str], Optional[str], str) -> Transaction
383385
"""
384386
Sets the propagation context from environment or headers and returns a transaction.
385387
"""
386388
return Scope.get_isolation_scope().continue_trace(
387-
environ_or_headers, op, name, source
389+
environ_or_headers, op, name, source, origin
388390
)

sentry_sdk/integrations/aiohttp.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363

6464
class AioHttpIntegration(Integration):
6565
identifier = "aiohttp"
66+
origin = f"auto.http.{identifier}"
6667

6768
def __init__(self, transaction_style="handler_name"):
6869
# type: (str) -> None
@@ -120,6 +121,7 @@ async def sentry_app_handle(self, request, *args, **kwargs):
120121
# URL resolver did not find a route or died trying.
121122
name="generic AIOHTTP request",
122123
source=TRANSACTION_SOURCE_ROUTE,
124+
origin=AioHttpIntegration.origin,
123125
)
124126
with sentry_sdk.start_transaction(
125127
transaction,
@@ -206,6 +208,7 @@ async def on_request_start(session, trace_config_ctx, params):
206208
op=OP.HTTP_CLIENT,
207209
description="%s %s"
208210
% (method, parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE),
211+
origin=AioHttpIntegration.origin,
209212
)
210213
span.set_data(SPANDATA.HTTP_METHOD, method)
211214
if parsed_url is not None:

sentry_sdk/integrations/anthropic.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
class AnthropicIntegration(Integration):
3232
identifier = "anthropic"
33+
origin = f"auto.ai.{identifier}"
3334

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

9495
span = sentry_sdk.start_span(
95-
op=OP.ANTHROPIC_MESSAGES_CREATE, description="Anthropic messages create"
96+
op=OP.ANTHROPIC_MESSAGES_CREATE,
97+
description="Anthropic messages create",
98+
origin=AnthropicIntegration.origin,
9699
)
97100
span.__enter__()
98101

sentry_sdk/integrations/arq.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
class ArqIntegration(Integration):
4141
identifier = "arq"
42+
origin = f"auto.queue.{identifier}"
4243

4344
@staticmethod
4445
def setup_once():
@@ -76,7 +77,9 @@ async def _sentry_enqueue_job(self, function, *args, **kwargs):
7677
if integration is None:
7778
return await old_enqueue_job(self, function, *args, **kwargs)
7879

79-
with sentry_sdk.start_span(op=OP.QUEUE_SUBMIT_ARQ, description=function):
80+
with sentry_sdk.start_span(
81+
op=OP.QUEUE_SUBMIT_ARQ, description=function, origin=ArqIntegration.origin
82+
):
8083
return await old_enqueue_job(self, function, *args, **kwargs)
8184

8285
ArqRedis.enqueue_job = _sentry_enqueue_job
@@ -101,6 +104,7 @@ async def _sentry_run_job(self, job_id, score):
101104
status="ok",
102105
op=OP.QUEUE_TASK_ARQ,
103106
source=TRANSACTION_SOURCE_TASK,
107+
origin=ArqIntegration.origin,
104108
)
105109

106110
with sentry_sdk.start_transaction(transaction):

sentry_sdk/integrations/asgi.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,23 @@ def _looks_like_asgi3(app):
8282

8383

8484
class SentryAsgiMiddleware:
85-
__slots__ = ("app", "__call__", "transaction_style", "mechanism_type")
85+
__slots__ = (
86+
"app",
87+
"__call__",
88+
"transaction_style",
89+
"mechanism_type",
90+
"span_origin",
91+
)
8692

8793
def __init__(
8894
self,
8995
app,
9096
unsafe_context_data=False,
9197
transaction_style="endpoint",
9298
mechanism_type="asgi",
99+
span_origin="manual",
93100
):
94-
# type: (Any, bool, str, str) -> None
101+
# type: (Any, bool, str, str, str) -> None
95102
"""
96103
Instrument an ASGI application with Sentry. Provides HTTP/websocket
97104
data to sent events and basic handling for exceptions bubbling up
@@ -124,6 +131,7 @@ def __init__(
124131

125132
self.transaction_style = transaction_style
126133
self.mechanism_type = mechanism_type
134+
self.span_origin = span_origin
127135
self.app = app
128136

129137
if _looks_like_asgi3(app):
@@ -182,6 +190,7 @@ async def _run_app(self, scope, receive, send, asgi_version):
182190
op="{}.server".format(ty),
183191
name=transaction_name,
184192
source=transaction_source,
193+
origin=self.span_origin,
185194
)
186195
logger.debug(
187196
"[ASGI] Created transaction (continuing trace): %s",
@@ -192,6 +201,7 @@ async def _run_app(self, scope, receive, send, asgi_version):
192201
op=OP.HTTP_SERVER,
193202
name=transaction_name,
194203
source=transaction_source,
204+
origin=self.span_origin,
195205
)
196206
logger.debug(
197207
"[ASGI] Created transaction (new): %s", transaction
@@ -205,7 +215,8 @@ async def _run_app(self, scope, receive, send, asgi_version):
205215
)
206216

207217
with sentry_sdk.start_transaction(
208-
transaction, custom_sampling_context={"asgi_scope": scope}
218+
transaction,
219+
custom_sampling_context={"asgi_scope": scope},
209220
):
210221
logger.debug("[ASGI] Started transaction: %s", transaction)
211222
try:

sentry_sdk/integrations/asyncio.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ async def _coro_creating_hub_and_span():
4545

4646
with sentry_sdk.isolation_scope():
4747
with sentry_sdk.start_span(
48-
op=OP.FUNCTION, description=get_name(coro)
48+
op=OP.FUNCTION,
49+
description=get_name(coro),
50+
origin=AsyncioIntegration.origin,
4951
):
5052
try:
5153
result = await coro
@@ -97,6 +99,7 @@ def _capture_exception():
9799

98100
class AsyncioIntegration(Integration):
99101
identifier = "asyncio"
102+
origin = f"auto.function.{identifier}"
100103

101104
@staticmethod
102105
def setup_once():

sentry_sdk/integrations/asyncpg.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
class AsyncPGIntegration(Integration):
3131
identifier = "asyncpg"
32+
origin = f"auto.db.{identifier}"
3233
_record_params = False
3334

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

7172
query = args[1]
72-
with record_sql_queries(None, query, None, None, executemany=False) as span:
73+
with record_sql_queries(
74+
cursor=None,
75+
query=query,
76+
params_list=None,
77+
paramstyle=None,
78+
executemany=False,
79+
span_origin=AsyncPGIntegration.origin,
80+
) as span:
7381
res = await f(*args, **kwargs)
7482

7583
with capture_internal_exceptions():
@@ -98,12 +106,13 @@ def _record(
98106
param_style = "pyformat" if params_list else None
99107

100108
with record_sql_queries(
101-
cursor,
102-
query,
103-
params_list,
104-
param_style,
109+
cursor=cursor,
110+
query=query,
111+
params_list=params_list,
112+
paramstyle=param_style,
105113
executemany=executemany,
106114
record_cursor_repr=cursor is not None,
115+
span_origin=AsyncPGIntegration.origin,
107116
) as span:
108117
yield span
109118

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

157-
with sentry_sdk.start_span(op=OP.DB, description="connect") as span:
166+
with sentry_sdk.start_span(
167+
op=OP.DB,
168+
description="connect",
169+
origin=AsyncPGIntegration.origin,
170+
) as span:
158171
span.set_data(SPANDATA.DB_SYSTEM, "postgresql")
159172
addr = kwargs.get("addr")
160173
if addr:

sentry_sdk/integrations/aws_lambda.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs):
139139
op=OP.FUNCTION_AWS,
140140
name=aws_context.function_name,
141141
source=TRANSACTION_SOURCE_COMPONENT,
142+
origin=AwsLambdaIntegration.origin,
142143
)
143144
with sentry_sdk.start_transaction(
144145
transaction,
@@ -178,6 +179,7 @@ def _drain_queue():
178179

179180
class AwsLambdaIntegration(Integration):
180181
identifier = "aws_lambda"
182+
origin = f"auto.function.{identifier}"
181183

182184
def __init__(self, timeout_warning=False):
183185
# type: (bool) -> None

sentry_sdk/integrations/boto3.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
class Boto3Integration(Integration):
3232
identifier = "boto3"
33+
origin = f"auto.http.{identifier}"
3334

3435
@staticmethod
3536
def setup_once():
@@ -69,6 +70,7 @@ def _sentry_request_created(service_id, request, operation_name, **kwargs):
6970
span = sentry_sdk.start_span(
7071
op=OP.HTTP_CLIENT,
7172
description=description,
73+
origin=Boto3Integration.origin,
7274
)
7375

7476
with capture_internal_exceptions():
@@ -106,6 +108,7 @@ def _sentry_after_call(context, parsed, **kwargs):
106108
streaming_span = span.start_child(
107109
op=OP.HTTP_CLIENT_STREAM,
108110
description=span.description,
111+
origin=Boto3Integration.origin,
109112
)
110113

111114
orig_read = body.read

sentry_sdk/integrations/bottle.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
class BottleIntegration(Integration):
4242
identifier = "bottle"
43+
origin = f"auto.http.{identifier}"
4344

4445
transaction_style = ""
4546

@@ -69,10 +70,13 @@ def setup_once():
6970
@ensure_integration_enabled(BottleIntegration, old_app)
7071
def sentry_patched_wsgi_app(self, environ, start_response):
7172
# type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse
72-
return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))(
73-
environ, start_response
73+
middleware = SentryWsgiMiddleware(
74+
lambda *a, **kw: old_app(self, *a, **kw),
75+
span_origin=BottleIntegration.origin,
7476
)
7577

78+
return middleware(environ, start_response)
79+
7680
Bottle.__call__ = sentry_patched_wsgi_app
7781

7882
old_handle = Bottle._handle

sentry_sdk/integrations/celery/__init__.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
class CeleryIntegration(Integration):
6060
identifier = "celery"
61+
origin = f"auto.queue.{identifier}"
6162

6263
def __init__(
6364
self,
@@ -266,7 +267,11 @@ def apply_async(*args, **kwargs):
266267
)
267268

268269
span_mgr = (
269-
sentry_sdk.start_span(op=OP.QUEUE_SUBMIT_CELERY, description=task.name)
270+
sentry_sdk.start_span(
271+
op=OP.QUEUE_SUBMIT_CELERY,
272+
description=task.name,
273+
origin=CeleryIntegration.origin,
274+
)
270275
if not task_started_from_beat
271276
else NoOpMgr()
272277
) # type: Union[Span, NoOpMgr]
@@ -309,6 +314,7 @@ def _inner(*args, **kwargs):
309314
op=OP.QUEUE_TASK_CELERY,
310315
name="unknown celery task",
311316
source=TRANSACTION_SOURCE_TASK,
317+
origin=CeleryIntegration.origin,
312318
)
313319
transaction.name = task.name
314320
transaction.set_status("ok")
@@ -362,7 +368,9 @@ def _inner(*args, **kwargs):
362368
# type: (*Any, **Any) -> Any
363369
try:
364370
with sentry_sdk.start_span(
365-
op=OP.QUEUE_PROCESS, description=task.name
371+
op=OP.QUEUE_PROCESS,
372+
description=task.name,
373+
origin=CeleryIntegration.origin,
366374
) as span:
367375
_set_messaging_destination_name(task, span)
368376

@@ -483,7 +491,11 @@ def sentry_publish(self, *args, **kwargs):
483491
routing_key = kwargs.get("routing_key")
484492
exchange = kwargs.get("exchange")
485493

486-
with sentry_sdk.start_span(op=OP.QUEUE_PUBLISH, description=task_name) as span:
494+
with sentry_sdk.start_span(
495+
op=OP.QUEUE_PUBLISH,
496+
description=task_name,
497+
origin=CeleryIntegration.origin,
498+
) as span:
487499
if task_id is not None:
488500
span.set_data(SPANDATA.MESSAGING_MESSAGE_ID, task_id)
489501

sentry_sdk/integrations/clickhouse_driver.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def __getitem__(self, _):
4141

4242
class ClickhouseDriverIntegration(Integration):
4343
identifier = "clickhouse_driver"
44+
origin = f"auto.db.{identifier}"
4445

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

84-
span = sentry_sdk.start_span(op=OP.DB, description=query)
85+
span = sentry_sdk.start_span(
86+
op=OP.DB,
87+
description=query,
88+
origin=ClickhouseDriverIntegration.origin,
89+
)
8590

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

sentry_sdk/integrations/cohere.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
class CohereIntegration(Integration):
6868
identifier = "cohere"
69+
origin = f"auto.ai.{identifier}"
6970

7071
def __init__(self, include_prompts=True):
7172
# type: (CohereIntegration, bool) -> None
@@ -141,6 +142,7 @@ def new_chat(*args, **kwargs):
141142
span = sentry_sdk.start_span(
142143
op=consts.OP.COHERE_CHAT_COMPLETIONS_CREATE,
143144
description="cohere.client.Chat",
145+
origin=CohereIntegration.origin,
144146
)
145147
span.__enter__()
146148
try:
@@ -225,6 +227,7 @@ def new_embed(*args, **kwargs):
225227
with sentry_sdk.start_span(
226228
op=consts.OP.COHERE_EMBEDDINGS_CREATE,
227229
description="Cohere Embedding Creation",
230+
origin=CohereIntegration.origin,
228231
) as span:
229232
integration = sentry_sdk.get_client().get_integration(CohereIntegration)
230233
if "texts" in kwargs and (

0 commit comments

Comments
 (0)