datasette-sentry/datasette_sentry.py
from datasette import hookimplfrom sentry_sdk.integrations.asgi import SentryAsgiMiddlewareimport sentry_sdk@hookimpldef asgi_wrapper(datasette):config = datasette.plugin_config("datasette-sentry") or {}dsn = config.get("dsn")if dsn is not None:kwargs = dict(dsn=dsn)if config.get("capture_events"):kwargs["transport"] = CaptureTransport(datasette)if config.get("sample_rate") is not None:kwargs["sample_rate"] = config["sample_rate"]if config.get("enable_tracing"):kwargs["enable_tracing"] = Truekwargs["traces_sample_rate"] = (config["traces_sample_rate"] if "traces_sample_rate" in config else 1.0)sentry_sdk.init(**kwargs)def wrap_with_class(app):if dsn is None:return appelse:return SentryAsgiMiddleware(app)return wrap_with_class@hookimpldef handle_exception(exception):sentry_sdk.capture_exception(exception)class CaptureTransport(sentry_sdk.transport.Transport):"Transport that captures events in a list, mainly for testing"def __init__(self, datasette):self.datasette = datasetteself.datasette._datasette_sentry_events = []self.datasette._datasette_sentry_envelopes = []def capture_event(self, event):self.datasette._datasette_sentry_events.append(event)def capture_envelope(self, envelope):self.datasette._datasette_sentry_envelopes.append(envelope)