root: add middleware to properly report websocket connection to sentry

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-04-27 16:21:44 +02:00
parent 69af788b0f
commit e9e0992dce
2 changed files with 22 additions and 2 deletions

View File

@ -5,6 +5,7 @@ from aioredis.errors import ConnectionClosedError, ReplyError
from billiard.exceptions import WorkerLostError from billiard.exceptions import WorkerLostError
from botocore.client import ClientError from botocore.client import ClientError
from celery.exceptions import CeleryError from celery.exceptions import CeleryError
from channels.middleware import BaseMiddleware
from channels_redis.core import ChannelFull from channels_redis.core import ChannelFull
from django.core.exceptions import SuspiciousOperation, ValidationError from django.core.exceptions import SuspiciousOperation, ValidationError
from django.db import InternalError, OperationalError, ProgrammingError from django.db import InternalError, OperationalError, ProgrammingError
@ -14,12 +15,28 @@ from ldap3.core.exceptions import LDAPException
from redis.exceptions import ConnectionError as RedisConnectionError from redis.exceptions import ConnectionError as RedisConnectionError
from redis.exceptions import RedisError, ResponseError from redis.exceptions import RedisError, ResponseError
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
from sentry_sdk import Hub
from sentry_sdk.tracing import Transaction
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from websockets.exceptions import WebSocketException from websockets.exceptions import WebSocketException
from authentik.lib.utils.reflection import class_to_path
LOGGER = get_logger() LOGGER = get_logger()
class SentryWSMiddleware(BaseMiddleware):
"""Sentry Websocket middleweare to set the transaction name based on
consumer class path"""
async def __call__(self, scope, receive, send):
transaction: Optional[Transaction] = Hub.current.scope.transaction
class_path = class_to_path(self.inner.consumer_class)
if transaction:
transaction.name = class_path
return await self.inner(scope, receive, send)
class SentryIgnoredException(Exception): class SentryIgnoredException(Exception):
"""Base Class for all errors that are suppressed, and not sent to sentry.""" """Base Class for all errors that are suppressed, and not sent to sentry."""

View File

@ -2,10 +2,13 @@
from channels.auth import AuthMiddlewareStack from channels.auth import AuthMiddlewareStack
from django.urls import path from django.urls import path
from authentik.lib.sentry import SentryWSMiddleware
from authentik.outposts.channels import OutpostConsumer from authentik.outposts.channels import OutpostConsumer
from authentik.root.messages.consumer import MessageConsumer from authentik.root.messages.consumer import MessageConsumer
websocket_urlpatterns = [ websocket_urlpatterns = [
path("ws/outpost/<uuid:pk>/", OutpostConsumer.as_asgi()), path("ws/outpost/<uuid:pk>/", SentryWSMiddleware(OutpostConsumer.as_asgi())),
path("ws/client/", AuthMiddlewareStack(MessageConsumer.as_asgi())), path(
"ws/client/", AuthMiddlewareStack(SentryWSMiddleware(MessageConsumer.as_asgi()))
),
] ]