Skip to content

Commit a139626

Browse files
feat(sqlalchemy): Support span streaming
1 parent 22fc6a6 commit a139626

4 files changed

Lines changed: 915 additions & 357 deletions

File tree

sentry_sdk/integrations/sqlalchemy.py

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
ensure_integration_enabled,
77
parse_version,
88
)
9+
from sentry_sdk.traces import StreamedSpan, SpanStatus
910

1011
try:
1112
from sqlalchemy.engine import Engine # type: ignore
@@ -20,6 +21,7 @@
2021
from typing import Any
2122
from typing import ContextManager
2223
from typing import Optional
24+
from typing import Union
2325

2426
from sentry_sdk.tracing import Span
2527

@@ -96,7 +98,10 @@ def _handle_error(context: "Any", *args: "Any") -> None:
9698
span: "Optional[Span]" = getattr(execution_context, "_sentry_sql_span", None)
9799

98100
if span is not None:
99-
span.set_status(SPANSTATUS.INTERNAL_ERROR)
101+
if isinstance(span, StreamedSpan):
102+
span.status = SpanStatus.ERROR
103+
else:
104+
span.set_status(SPANSTATUS.INTERNAL_ERROR)
100105

101106
# _after_cursor_execute does not get called for crashing SQL stmts. Judging
102107
# from SQLAlchemy codebase it does seem like any error coming into this
@@ -132,29 +137,53 @@ def _get_db_system(name: str) -> "Optional[str]":
132137
return None
133138

134139

135-
def _set_db_data(span: "Span", conn: "Any") -> None:
140+
def _set_db_data(span: "Union[Span, StreamedSpan]", conn: "Any") -> None:
136141
db_system = _get_db_system(conn.engine.name)
137-
if db_system is not None:
138-
span.set_data(SPANDATA.DB_SYSTEM, db_system)
139-
140-
try:
141-
driver = conn.dialect.driver
142-
if driver:
143-
span.set_data(SPANDATA.DB_DRIVER_NAME, driver)
144-
except Exception:
145-
pass
142+
if isinstance(span, StreamedSpan):
143+
if db_system is not None:
144+
span.set_attribute(SPANDATA.DB_SYSTEM, db_system)
145+
146+
try:
147+
driver = conn.dialect.driver
148+
if driver:
149+
span.set_attribute(SPANDATA.DB_DRIVER_NAME, driver)
150+
except Exception:
151+
pass
152+
else:
153+
if db_system is not None:
154+
span.set_data(SPANDATA.DB_SYSTEM, db_system)
155+
156+
try:
157+
driver = conn.dialect.driver
158+
if driver:
159+
span.set_data(SPANDATA.DB_DRIVER_NAME, driver)
160+
except Exception:
161+
pass
146162

147163
if conn.engine.url is None:
148164
return
149165

150-
db_name = conn.engine.url.database
151-
if db_name is not None:
152-
span.set_data(SPANDATA.DB_NAME, db_name)
153-
154-
server_address = conn.engine.url.host
155-
if server_address is not None:
156-
span.set_data(SPANDATA.SERVER_ADDRESS, server_address)
157-
158-
server_port = conn.engine.url.port
159-
if server_port is not None:
160-
span.set_data(SPANDATA.SERVER_PORT, server_port)
166+
if isinstance(span, StreamedSpan):
167+
db_name = conn.engine.url.database
168+
if db_name is not None:
169+
span.set_attribute(SPANDATA.DB_NAME, db_name)
170+
171+
server_address = conn.engine.url.host
172+
if server_address is not None:
173+
span.set_attribute(SPANDATA.SERVER_ADDRESS, server_address)
174+
175+
server_port = conn.engine.url.port
176+
if server_port is not None:
177+
span.set_attribute(SPANDATA.SERVER_PORT, server_port)
178+
else:
179+
db_name = conn.engine.url.database
180+
if db_name is not None:
181+
span.set_data(SPANDATA.DB_NAME, db_name)
182+
183+
server_address = conn.engine.url.host
184+
if server_address is not None:
185+
span.set_data(SPANDATA.SERVER_ADDRESS, server_address)
186+
187+
server_port = conn.engine.url.port
188+
if server_port is not None:
189+
span.set_data(SPANDATA.SERVER_PORT, server_port)

tests/integrations/django/asgi/test_asgi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,9 @@ async def test_async_middleware_spans(
292292

293293
(transaction,) = events
294294

295+
assert transaction["type"] == "transaction"
295296
assert (
296-
render_span_tree(transaction)
297+
render_span_tree(transaction["spans"], transaction["contexts"]["trace"])
297298
== """\
298299
- op="http.server": description=null
299300
- op="event.django": description="django.db.reset_queries"

0 commit comments

Comments
 (0)