diff --git a/server/config/settings/base.py b/server/config/settings/base.py index a1c631bf..43e3d770 100644 --- a/server/config/settings/base.py +++ b/server/config/settings/base.py @@ -8,7 +8,7 @@ import structlog from environs import Env from vbv_lernwelt.core.constants import DEFAULT_RICH_TEXT_FEATURES -from vbv_lernwelt.core.utils import structlog_add_app_info +from vbv_lernwelt.core.utils import structlog_add_app_info, structlog_add_to_message SERVER_ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent APPS_DIR = SERVER_ROOT_DIR / "vbv_lernwelt" @@ -427,36 +427,16 @@ if IT_DJANGO_LOGGING_CONF == "IT_DJANGO_LOGGING_CONF_CONSOLE_COLOR": cache_logger_on_first_use=True, ) else: - shared_processors = [ - structlog.threadlocal.merge_threadlocal, - structlog.stdlib.add_log_level, - structlog.stdlib.add_logger_name, - structlog_add_app_info, - structlog.processors.TimeStamper(fmt="iso"), - structlog.processors.CallsiteParameterAdder(), - ] - LOGGING = { "version": 1, "disable_existing_loggers": True, "formatters": { "json": { - "()": structlog.stdlib.ProcessorFormatter, - "processors": [ - structlog.stdlib.ProcessorFormatter.remove_processors_meta, - structlog.processors.JSONRenderer(), - ], - "foreign_pre_chain": shared_processors, + "()": "pythonjsonlogger.jsonlogger.JsonFormatter", + "format": "%(asctime)s %(levelname)s %(process)d %(thread)d %(name)s %(lineno)d %(funcName)s %(message)s", }, }, "handlers": { - "file": { - "class": "concurrent_log_handler.ConcurrentRotatingFileHandler", - "filename": f"{SERVER_ROOT_DIR}/log/myservice.log", - "maxBytes": 1024 * 1024 * 100, - "backupCount": 50, - "formatter": "json", - }, "console": { "level": "DEBUG", "class": "logging.StreamHandler", @@ -465,30 +445,36 @@ else: }, "loggers": { "": { - "handlers": ["console", "file"], + "handlers": ["console"], "level": "INFO", }, "django": { - "handlers": ["console", "file"], + "handlers": ["console"], "level": "WARNING", "propagate": False, }, "vbv_lernwelt": { - "handlers": ["console", "file"], + "handlers": ["console"], "level": "DEBUG", "propagate": False, }, "sentry_sdk": { "level": "ERROR", - "handlers": ["console", "file"], + "handlers": ["console"], "propagate": False, }, }, } structlog.configure( - processors=shared_processors - + [ + processors=[ + structlog.stdlib.filter_by_level, + structlog.threadlocal.merge_threadlocal, + structlog_add_app_info, + structlog.processors.StackInfoRenderer(), + structlog.processors.format_exc_info, + structlog.processors.UnicodeDecoder(), + structlog_add_to_message, structlog.stdlib.ProcessorFormatter.wrap_for_formatter, ], context_class=dict, diff --git a/server/vbv_lernwelt/core/utils.py b/server/vbv_lernwelt/core/utils.py index 8291ac53..d9426215 100644 --- a/server/vbv_lernwelt/core/utils.py +++ b/server/vbv_lernwelt/core/utils.py @@ -8,15 +8,33 @@ from structlog.types import EventDict def structlog_add_app_info( - logger: logging.Logger, method_name: str, event_dict: EventDict + _: logging.Logger, __: str, event_dict: EventDict ) -> EventDict: event_dict["django_app"] = "vbv_lernwelt" - event_dict["APP_ENVIRONMENT"] = settings.APP_ENVIRONMENT + event_dict["app_environment"] = settings.APP_ENVIRONMENT event_dict["django_app_dev_mode"] = f"vbv_lernwelt_{settings.APP_ENVIRONMENT}" return event_dict +def structlog_add_to_message( + _: logging.Logger, __: str, event_dict: EventDict +) -> EventDict: + """ + The *event_dict* is added as dict ``message``. + + This allows you to defer formatting to `logging`. + """ + return { + "message": event_dict, + **{ + kw: event_dict.pop(kw) + for kw in ("exc_info", "stack_info", "stackLevel") + if kw in event_dict + }, + } + + def structlog_inject_context_dict(test, level, event_dict): """ Add the structlog context dict to log events generated by the stdlib logging library.