logging: improve logging [AUTH-68]
This commit is contained in:
parent
8831e1d946
commit
f93b438e9d
|
@ -19,6 +19,7 @@ from django.utils import timezone
|
|||
from django.views.debug import SafeExceptionReporterFilter
|
||||
from geoip2.models import ASN, City
|
||||
from guardian.utils import get_anonymous_user
|
||||
from rest_framework import serializers
|
||||
|
||||
from authentik.blueprints.v1.common import YAMLTag
|
||||
from authentik.core.models import User
|
||||
|
@ -186,3 +187,17 @@ def sanitize_dict(source: dict[Any, Any]) -> dict[Any, Any]:
|
|||
if new_value is not ...:
|
||||
final_dict[key] = new_value
|
||||
return final_dict
|
||||
|
||||
|
||||
class LogSerializer(serializers.Serializer):
|
||||
timestamp = serializers.DateTimeField()
|
||||
log_level = serializers.CharField()
|
||||
message = serializers.CharField()
|
||||
attributes = serializers.JSONField(default=dict)
|
||||
|
||||
def to_representation(self, instance):
|
||||
data = super().to_representation(instance)
|
||||
data["attributes"] = {
|
||||
k: v for k, v in instance.items() if k not in ["timestamp", "log_level", "message"]
|
||||
}
|
||||
return data
|
||||
|
|
|
@ -6,6 +6,7 @@ from structlog.stdlib import get_logger
|
|||
from structlog.testing import capture_logs
|
||||
|
||||
from authentik import __version__, get_build_hash
|
||||
from authentik.events.utils import LogSerializer
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.sentry import SentryIgnoredException
|
||||
from authentik.outposts.models import (
|
||||
|
@ -59,26 +60,17 @@ class BaseController:
|
|||
self.logger = get_logger()
|
||||
self.deployment_ports = []
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
def up(self):
|
||||
"""Called by scheduled task to reconcile deployment/service/etc"""
|
||||
raise NotImplementedError
|
||||
|
||||
def up_with_logs(self) -> list[str]:
|
||||
"""Call .up() but capture all log output and return it."""
|
||||
with capture_logs() as logs:
|
||||
self.up()
|
||||
return [x["event"] for x in logs]
|
||||
|
||||
def down(self):
|
||||
"""Handler to delete everything we've created"""
|
||||
raise NotImplementedError
|
||||
return [LogSerializer(data=log).data for log in logs]
|
||||
|
||||
def down_with_logs(self) -> list[str]:
|
||||
"""Call .down() but capture all log output and return it."""
|
||||
with capture_logs() as logs:
|
||||
self.down()
|
||||
return [x["event"] for x in logs]
|
||||
return [LogSerializer(data=log).data for log in logs]
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
|
|
@ -12,6 +12,7 @@ from structlog.testing import capture_logs
|
|||
from urllib3.exceptions import HTTPError
|
||||
from yaml import dump_all
|
||||
|
||||
from authentik.events.utils import LogSerializer
|
||||
from authentik.outposts.controllers.base import BaseClient, BaseController, ControllerException
|
||||
from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler
|
||||
from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler
|
||||
|
@ -78,18 +79,6 @@ class KubernetesController(BaseController):
|
|||
PrometheusServiceMonitorReconciler.reconciler_name(),
|
||||
]
|
||||
|
||||
def up(self):
|
||||
try:
|
||||
for reconcile_key in self.reconcile_order:
|
||||
reconciler_cls = self.reconcilers.get(reconcile_key)
|
||||
if not reconciler_cls:
|
||||
continue
|
||||
reconciler = reconciler_cls(self)
|
||||
reconciler.up()
|
||||
|
||||
except (OpenApiException, HTTPError, ServiceConnectionInvalid) as exc:
|
||||
raise ControllerException(str(exc)) from exc
|
||||
|
||||
def up_with_logs(self) -> list[str]:
|
||||
try:
|
||||
all_logs = []
|
||||
|
@ -103,24 +92,11 @@ class KubernetesController(BaseController):
|
|||
continue
|
||||
reconciler = reconciler_cls(self)
|
||||
reconciler.up()
|
||||
all_logs += [f"{reconcile_key.title()}: {x['event']}" for x in logs]
|
||||
all_logs += [LogSerializer(data=log).data for log in logs]
|
||||
return all_logs
|
||||
except (OpenApiException, HTTPError, ServiceConnectionInvalid) as exc:
|
||||
raise ControllerException(str(exc)) from exc
|
||||
|
||||
def down(self):
|
||||
try:
|
||||
for reconcile_key in self.reconcile_order:
|
||||
reconciler_cls = self.reconcilers.get(reconcile_key)
|
||||
if not reconciler_cls:
|
||||
continue
|
||||
reconciler = reconciler_cls(self)
|
||||
self.logger.debug("Tearing down object", name=reconcile_key)
|
||||
reconciler.down()
|
||||
|
||||
except (OpenApiException, HTTPError, ServiceConnectionInvalid) as exc:
|
||||
raise ControllerException(str(exc)) from exc
|
||||
|
||||
def down_with_logs(self) -> list[str]:
|
||||
try:
|
||||
all_logs = []
|
||||
|
@ -134,7 +110,7 @@ class KubernetesController(BaseController):
|
|||
continue
|
||||
reconciler = reconciler_cls(self)
|
||||
reconciler.down()
|
||||
all_logs += [f"{reconcile_key.title()}: {x['event']}" for x in logs]
|
||||
all_logs += [LogSerializer(data=log).data for log in logs]
|
||||
return all_logs
|
||||
except (OpenApiException, HTTPError, ServiceConnectionInvalid) as exc:
|
||||
raise ControllerException(str(exc)) from exc
|
||||
|
|
|
@ -16,7 +16,7 @@ from authentik.api.decorators import permission_required
|
|||
from authentik.core.api.applications import user_app_cache_key
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import CacheSerializer, MetaNameSerializer, TypeCreateSerializer
|
||||
from authentik.events.utils import sanitize_dict
|
||||
from authentik.events.utils import LogSerializer
|
||||
from authentik.lib.utils.reflection import all_subclasses
|
||||
from authentik.policies.api.exec import PolicyTestResultSerializer, PolicyTestSerializer
|
||||
from authentik.policies.models import Policy, PolicyBinding
|
||||
|
@ -163,11 +163,6 @@ class PolicyViewSet(
|
|||
proc = PolicyProcess(PolicyBinding(policy=policy), p_request, None)
|
||||
with capture_logs() as logs:
|
||||
result = proc.execute()
|
||||
log_messages = []
|
||||
for log in logs:
|
||||
if log.get("process", "") == "PolicyProcess":
|
||||
continue
|
||||
log_messages.append(sanitize_dict(log))
|
||||
result.log_messages = log_messages
|
||||
result.log_messages = [LogSerializer(data=log).data for log in logs]
|
||||
response = PolicyTestResultSerializer(result)
|
||||
return Response(response.data)
|
||||
|
|
Reference in a new issue