Skip to content

Commit 5496a45

Browse files
Merge branch 'master' into webb/disable-django-spans
2 parents a674e17 + 8417165 commit 5496a45

File tree

9 files changed

+366
-9
lines changed

9 files changed

+366
-9
lines changed

sentry_sdk/integrations/django/asgi.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ async def sentry_wrapped_callback(request, *args, **kwargs):
180180
if sentry_scope.profile is not None:
181181
sentry_scope.profile.update_active_thread_id()
182182

183+
integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
184+
if not integration or not integration.middleware_spans:
185+
return await callback(request, *args, **kwargs)
186+
183187
with sentry_sdk.start_span(
184188
op=OP.VIEW_RENDER,
185189
name=request.resolver_match.view_name,

sentry_sdk/integrations/django/views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def sentry_patched_make_view_atomic(self, *args, **kwargs):
4949
# efficient way to wrap views (or build a cache?)
5050

5151
integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
52-
if integration is not None and integration.middleware_spans:
52+
if integration is not None:
5353
is_async_view = (
5454
iscoroutinefunction is not None
5555
and wrap_async_view is not None
@@ -86,6 +86,10 @@ def sentry_wrapped_callback(request, *args, **kwargs):
8686
if sentry_scope.profile is not None:
8787
sentry_scope.profile.update_active_thread_id()
8888

89+
integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
90+
if not integration or not integration.middleware_spans:
91+
return callback(request, *args, **kwargs)
92+
8993
with sentry_sdk.start_span(
9094
op=OP.VIEW_RENDER,
9195
name=request.resolver_match.view_name,

sentry_sdk/integrations/langgraph.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,23 @@ def _set_usage_data(span, messages):
349349
)
350350

351351

352+
def _set_response_model_name(span, messages):
353+
# type: (sentry_sdk.tracing.Span, Any) -> None
354+
if len(messages) == 0:
355+
return
356+
357+
last_message = messages[-1]
358+
response_metadata = last_message.get("response_metadata")
359+
if response_metadata is None:
360+
return
361+
362+
model_name = response_metadata.get("model_name")
363+
if model_name is None:
364+
return
365+
366+
set_data_normalized(span, SPANDATA.GEN_AI_RESPONSE_MODEL, model_name)
367+
368+
352369
def _set_response_attributes(span, input_messages, result, integration):
353370
# type: (Any, Optional[List[Any]], Any, LanggraphIntegration) -> None
354371
parsed_response_messages = _parse_langgraph_messages(result)
@@ -358,6 +375,7 @@ def _set_response_attributes(span, input_messages, result, integration):
358375
return
359376

360377
_set_usage_data(span, new_messages)
378+
_set_response_model_name(span, new_messages)
361379

362380
if not (should_send_default_pii() and integration.include_prompts):
363381
return

sentry_sdk/integrations/starlette.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,19 +144,23 @@ def _enable_span_for_middleware(middleware_class):
144144
async def _create_span_call(app, scope, receive, send, **kwargs):
145145
# type: (Any, Dict[str, Any], Callable[[], Awaitable[Dict[str, Any]]], Callable[[Dict[str, Any]], Awaitable[None]], Any) -> None
146146
integration = sentry_sdk.get_client().get_integration(StarletteIntegration)
147-
if integration is None or not integration.middleware_spans:
147+
if integration is None:
148148
return await old_call(app, scope, receive, send, **kwargs)
149149

150-
middleware_name = app.__class__.__name__
151-
152150
# Update transaction name with middleware name
153151
name, source = _get_transaction_from_middleware(app, scope, integration)
152+
154153
if name is not None:
155154
sentry_sdk.get_current_scope().set_transaction_name(
156155
name,
157156
source=source,
158157
)
159158

159+
if not integration.middleware_spans:
160+
return await old_call(app, scope, receive, send, **kwargs)
161+
162+
middleware_name = app.__class__.__name__
163+
160164
with sentry_sdk.start_span(
161165
op=OP.MIDDLEWARE_STARLETTE,
162166
name=middleware_name,

sentry_sdk/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ def get_default_release():
154154
"CODEBUILD_RESOLVED_SOURCE_VERSION",
155155
"CIRCLE_SHA1",
156156
"GAE_DEPLOYMENT_ID",
157+
"K_REVISION",
157158
):
158159
release = os.environ.get(var)
159160
if release:

tests/integrations/django/asgi/test_asgi.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,19 +118,25 @@ async def test_async_views(sentry_init, capture_events, application):
118118

119119
@pytest.mark.parametrize("application", APPS)
120120
@pytest.mark.parametrize("endpoint", ["/sync/thread_ids", "/async/thread_ids"])
121+
@pytest.mark.parametrize("middleware_spans", [False, True])
121122
@pytest.mark.asyncio
122123
@pytest.mark.forked
123124
@pytest.mark.skipif(
124125
django.VERSION < (3, 1), reason="async views have been introduced in Django 3.1"
125126
)
126127
async def test_active_thread_id(
127-
sentry_init, capture_envelopes, teardown_profiling, endpoint, application
128+
sentry_init,
129+
capture_envelopes,
130+
teardown_profiling,
131+
endpoint,
132+
application,
133+
middleware_spans,
128134
):
129135
with mock.patch(
130136
"sentry_sdk.profiler.transaction_profiler.PROFILE_MINIMUM_SAMPLES", 0
131137
):
132138
sentry_init(
133-
integrations=[DjangoIntegration()],
139+
integrations=[DjangoIntegration(middleware_spans=middleware_spans)],
134140
traces_sample_rate=1.0,
135141
profiles_sample_rate=1.0,
136142
)

tests/integrations/fastapi/test_fastapi.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ def dummy_traces_sampler(sampling_context):
469469
client.get(request_url)
470470

471471

472+
@pytest.mark.parametrize("middleware_spans", [False, True])
472473
@pytest.mark.parametrize(
473474
"request_url,transaction_style,expected_transaction_name,expected_transaction_source",
474475
[
@@ -488,6 +489,7 @@ def dummy_traces_sampler(sampling_context):
488489
)
489490
def test_transaction_name_in_middleware(
490491
sentry_init,
492+
middleware_spans,
491493
request_url,
492494
transaction_style,
493495
expected_transaction_name,
@@ -500,8 +502,12 @@ def test_transaction_name_in_middleware(
500502
sentry_init(
501503
auto_enabling_integrations=False, # Make sure that httpx integration is not added, because it adds tracing information to the starlette test clients request.
502504
integrations=[
503-
StarletteIntegration(transaction_style=transaction_style),
504-
FastApiIntegration(transaction_style=transaction_style),
505+
StarletteIntegration(
506+
transaction_style=transaction_style, middleware_spans=middleware_spans
507+
),
508+
FastApiIntegration(
509+
transaction_style=transaction_style, middleware_spans=middleware_spans
510+
),
505511
],
506512
traces_sample_rate=1.0,
507513
)

0 commit comments

Comments
 (0)