diff --git a/authentik/lib/sentry.py b/authentik/lib/sentry.py index 59eb2dd83..c65c96ddd 100644 --- a/authentik/lib/sentry.py +++ b/authentik/lib/sentry.py @@ -18,13 +18,22 @@ from redis.exceptions import ConnectionError as RedisConnectionError from redis.exceptions import RedisError, ResponseError from rest_framework.exceptions import APIException from sentry_sdk import Hub +from sentry_sdk import init as sentry_sdk_init +from sentry_sdk.api import set_tag +from sentry_sdk.integrations.celery import CeleryIntegration +from sentry_sdk.integrations.django import DjangoIntegration +from sentry_sdk.integrations.redis import RedisIntegration +from sentry_sdk.integrations.threading import ThreadingIntegration from sentry_sdk.tracing import Transaction from structlog.stdlib import get_logger from websockets.exceptions import WebSocketException -from authentik.lib.utils.reflection import class_to_path +from authentik import __version__, get_build_hash +from authentik.lib.config import CONFIG +from authentik.lib.utils.reflection import class_to_path, get_env LOGGER = get_logger() +SENTRY_DSN = "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8" class SentryWSMiddleware(BaseMiddleware): @@ -43,6 +52,36 @@ class SentryIgnoredException(Exception): """Base Class for all errors that are suppressed, and not sent to sentry.""" +def sentry_init(**sentry_init_kwargs): + """Configure sentry SDK""" + sentry_env = CONFIG.y("error_reporting.environment", "customer") + kwargs = { + "traces_sample_rate": float(CONFIG.y("error_reporting.sample_rate", 0.5)), + "environment": sentry_env, + "send_default_pii": CONFIG.y_bool("error_reporting.send_pii", False), + } + kwargs.update(**sentry_init_kwargs) + # pylint: disable=abstract-class-instantiated + sentry_sdk_init( + dsn=SENTRY_DSN, + integrations=[ + DjangoIntegration(transaction_style="function_name"), + CeleryIntegration(), + RedisIntegration(), + ThreadingIntegration(propagate_hub=True), + ], + before_send=before_send, + release=f"authentik@{__version__}", + **kwargs + ) + set_tag("authentik.build_hash", get_build_hash("tagged")) + set_tag("authentik.env", get_env()) + set_tag("authentik.component", "backend") + LOGGER.info( + "Error reporting is enabled", + env=kwargs["environment"], + ) + def before_send(event: dict, hint: dict) -> Optional[dict]: """Check if error is database error, and ignore if so""" # pylint: disable=no-name-in-module @@ -108,6 +147,6 @@ def before_send(event: dict, hint: dict) -> Optional[dict]: ]: return None LOGGER.debug("sending event to sentry", exc=exc_value, source_logger=event.get("logger", None)) - if settings.DEBUG or settings.TEST: + if settings.DEBUG: return None return event diff --git a/authentik/root/settings.py b/authentik/root/settings.py index 22d5dd805..53d3c1c8a 100644 --- a/authentik/root/settings.py +++ b/authentik/root/settings.py @@ -11,18 +11,13 @@ from urllib.parse import quote_plus import structlog from celery.schedules import crontab -from sentry_sdk import init as sentry_init -from sentry_sdk.api import set_tag -from sentry_sdk.integrations.celery import CeleryIntegration -from sentry_sdk.integrations.django import DjangoIntegration -from sentry_sdk.integrations.redis import RedisIntegration -from sentry_sdk.integrations.threading import ThreadingIntegration +from sentry_sdk import set_tag -from authentik import ENV_GIT_HASH_KEY, __version__, get_build_hash +from authentik import ENV_GIT_HASH_KEY, __version__ from authentik.core.middleware import structlog_add_request_id from authentik.lib.config import CONFIG from authentik.lib.logging import add_process_id -from authentik.lib.sentry import before_send +from authentik.lib.sentry import sentry_init from authentik.lib.utils.reflection import get_env from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BACKEND_LDAP @@ -357,34 +352,13 @@ CELERY_RESULT_BACKEND = ( ) # Sentry integration -SENTRY_DSN = "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8" - env = get_env() _ERROR_REPORTING = CONFIG.y_bool("error_reporting.enabled", False) if _ERROR_REPORTING: - # pylint: disable=abstract-class-instantiated - sentry_init( - dsn=SENTRY_DSN, - integrations=[ - DjangoIntegration(transaction_style="function_name"), - CeleryIntegration(), - RedisIntegration(), - ThreadingIntegration(propagate_hub=True), - ], - before_send=before_send, - release=f"authentik@{__version__}", - traces_sample_rate=float(CONFIG.y("error_reporting.sample_rate", 0.5)), - environment=CONFIG.y("error_reporting.environment", "customer"), - send_default_pii=CONFIG.y_bool("error_reporting.send_pii", False), - ) - set_tag("authentik.build_hash", get_build_hash("tagged")) - set_tag("authentik.env", env) - set_tag("authentik.component", "backend") + sentry_env = CONFIG.y("error_reporting.environment", "customer") + sentry_init() set_tag("authentik.uuid", sha512(str(SECRET_KEY).encode("ascii")).hexdigest()[:16]) - j_print( - "Error reporting is enabled", - env=CONFIG.y("error_reporting.environment", "customer"), - ) + # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.1/howto/static-files/ diff --git a/authentik/root/test_runner.py b/authentik/root/test_runner.py index 7b0ab7870..806c3c0b6 100644 --- a/authentik/root/test_runner.py +++ b/authentik/root/test_runner.py @@ -4,6 +4,7 @@ from argparse import ArgumentParser from django.conf import settings from authentik.lib.config import CONFIG +from authentik.lib.sentry import sentry_init from tests.e2e.utils import get_docker_tag @@ -32,6 +33,11 @@ class PytestTestRunner: # pragma: no cover "outposts.container_image_base", f"ghcr.io/goauthentik/dev-%(type)s:{get_docker_tag()}", ) + sentry_init( + sample_rate=1.0, + environment="testing", + send_default_pii=True, + ) @classmethod def add_arguments(cls, parser: ArgumentParser):