from __future__ import absolute_import from sentry_sdk._types import MYPY from sentry_sdk.hub import Hub from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.tracing import record_sql_queries try: from sqlalchemy.engine import Engine # type: ignore from sqlalchemy.event import listen # type: ignore from sqlalchemy import __version__ as SQLALCHEMY_VERSION # type: ignore except ImportError: raise DidNotEnable("SQLAlchemy not installed.") if MYPY: from typing import Any from typing import ContextManager from typing import Optional from sentry_sdk.tracing import Span class SqlalchemyIntegration(Integration): identifier = "sqlalchemy" @staticmethod def setup_once(): # type: () -> None try: version = tuple(map(int, SQLALCHEMY_VERSION.split("b")[0].split("."))) except (TypeError, ValueError): raise DidNotEnable( "Unparsable SQLAlchemy version: {}".format(SQLALCHEMY_VERSION) ) if version < (1, 2): raise DidNotEnable("SQLAlchemy 1.2 or newer required.") listen(Engine, "before_cursor_execute", _before_cursor_execute) listen(Engine, "after_cursor_execute", _after_cursor_execute) listen(Engine, "handle_error", _handle_error) def _before_cursor_execute( conn, cursor, statement, parameters, context, executemany, *args ): # type: (Any, Any, Any, Any, Any, bool, *Any) -> None hub = Hub.current if hub.get_integration(SqlalchemyIntegration) is None: return ctx_mgr = record_sql_queries( hub, cursor, statement, parameters, paramstyle=context and context.dialect and context.dialect.paramstyle or None, executemany=executemany, ) conn._sentry_sql_span_manager = ctx_mgr span = ctx_mgr.__enter__() if span is not None: conn._sentry_sql_span = span def _after_cursor_execute(conn, cursor, statement, *args): # type: (Any, Any, Any, *Any) -> None ctx_mgr = getattr( conn, "_sentry_sql_span_manager", None ) # type: ContextManager[Any] if ctx_mgr is not None: conn._sentry_sql_span_manager = None ctx_mgr.__exit__(None, None, None) def _handle_error(context, *args): # type: (Any, *Any) -> None conn = context.connection span = getattr(conn, "_sentry_sql_span", None) # type: Optional[Span] if span is not None: span.set_status("internal_error") # _after_cursor_execute does not get called for crashing SQL stmts. Judging # from SQLAlchemy codebase it does seem like any error coming into this # handler is going to be fatal. ctx_mgr = getattr( conn, "_sentry_sql_span_manager", None ) # type: ContextManager[Any] if ctx_mgr is not None: conn._sentry_sql_span_manager = None ctx_mgr.__exit__(None, None, None)
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
__pycache__ | Folder | 0755 |
|
|
django | Folder | 0755 |
|
|
spark | Folder | 0755 |
|
|
__init__.py | File | 6.36 KB | 0644 |
|
_wsgi_common.py | File | 4.65 KB | 0644 |
|
aiohttp.py | File | 7.77 KB | 0644 |
|
argv.py | File | 945 B | 0644 |
|
asgi.py | File | 8.17 KB | 0644 |
|
atexit.py | File | 1.79 KB | 0644 |
|
aws_lambda.py | File | 12.64 KB | 0644 |
|
beam.py | File | 5.53 KB | 0644 |
|
boto3.py | File | 3.64 KB | 0644 |
|
bottle.py | File | 6.04 KB | 0644 |
|
celery.py | File | 8.91 KB | 0644 |
|
chalice.py | File | 4.47 KB | 0644 |
|
dedupe.py | File | 1.14 KB | 0644 |
|
excepthook.py | File | 2.14 KB | 0644 |
|
executing.py | File | 1.98 KB | 0644 |
|
falcon.py | File | 6.64 KB | 0644 |
|
flask.py | File | 7.25 KB | 0644 |
|
gcp.py | File | 7.21 KB | 0644 |
|
gnu_backtrace.py | File | 2.84 KB | 0644 |
|
logging.py | File | 7.4 KB | 0644 |
|
modules.py | File | 1.36 KB | 0644 |
|
pure_eval.py | File | 4.41 KB | 0644 |
|
pyramid.py | File | 6.91 KB | 0644 |
|
redis.py | File | 3 KB | 0644 |
|
rq.py | File | 4.68 KB | 0644 |
|
sanic.py | File | 7.53 KB | 0644 |
|
serverless.py | File | 1.92 KB | 0644 |
|
sqlalchemy.py | File | 2.87 KB | 0644 |
|
stdlib.py | File | 7.18 KB | 0644 |
|
threading.py | File | 2.79 KB | 0644 |
|
tornado.py | File | 6.84 KB | 0644 |
|
trytond.py | File | 1.69 KB | 0644 |
|
wsgi.py | File | 10.13 KB | 0644 |
|