try to fix logging

This commit is contained in:
Ross
2026-06-03 20:48:00 +01:00
parent 2e854c43b6
commit 3d445fe12e
7 changed files with 194 additions and 53 deletions
+91
View File
@@ -0,0 +1,91 @@
from __future__ import annotations
import logging
import os
import sys
from pathlib import Path
from django.conf import settings
from loguru import logger
_CONFIGURED = False
def _is_truthy(value: str | None) -> bool:
if value is None:
return False
return value.lower() in {"1", "true", "yes", "on"}
def _get_stdout_level() -> str:
env_level = os.environ.get("LOGURU_STDOUT_LEVEL")
if env_level:
return env_level
debug_flag = os.environ.get("DEBUG")
if debug_flag is None:
try:
debug_flag = "1" if getattr(settings, "DEBUG", False) else "0"
except Exception:
debug_flag = "0"
return "DEBUG" if _is_truthy(debug_flag) else "INFO"
def _get_log_file_path() -> Path:
override = os.environ.get("LOGURU_FILE")
if override:
return Path(override)
try:
logging_config = getattr(settings, "LOGGING", None) or {}
handler = (logging_config.get("handlers") or {}).get("file") or {}
filename = handler.get("filename")
if filename:
path = Path(filename)
if path.is_absolute():
return path
return Path(getattr(settings, "BASE_DIR", Path.cwd())) / path
except Exception:
pass
try:
return Path(getattr(settings, "BASE_DIR", Path.cwd())) / "log.txt"
except Exception:
return Path.cwd() / "log.txt"
def configure_loguru() -> Path:
global _CONFIGURED
if _CONFIGURED:
return _get_log_file_path()
log_file_path = _get_log_file_path()
log_file_path.parent.mkdir(parents=True, exist_ok=True)
stdout_level = _get_stdout_level()
log_format = "[{time:DD/MMM/YYYY HH:mm:ss}] {level} [{name}:{line}] {message}"
logger.remove()
logger.add(
sys.stdout,
level=stdout_level,
enqueue=True,
backtrace=False,
diagnose=False,
format=log_format,
)
logger.add(
str(log_file_path),
level="DEBUG",
enqueue=True,
backtrace=True,
diagnose=False,
format=log_format + "\n{exception}",
rotation="10 MB",
retention="10 days",
)
logging.root.setLevel(logging.DEBUG)
_CONFIGURED = True
logger.debug("Loguru logging configured with stdout and file sinks (stdout={})", stdout_level)
return log_file_path
+16
View File
@@ -3,6 +3,22 @@ from __future__ import annotations
import pytest
from django.urls import reverse
from rad import logging_setup
def test_loguru_uses_django_file_handler_path(settings, tmp_path, monkeypatch):
monkeypatch.setattr(logging_setup, "_CONFIGURED", False)
settings.BASE_DIR = str(tmp_path)
settings.LOGGING = {
"handlers": {
"file": {
"filename": "log.txt",
}
}
}
assert logging_setup._get_log_file_path() == tmp_path / "log.txt"
@pytest.mark.django_db
def test_logs_view_filters_by_date_and_can_reset_log_file(client, admin_user, monkeypatch, tmp_path):
+3 -51
View File
@@ -1,60 +1,12 @@
"""
WSGI config for rad project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""
"""WSGI config for rad project."""
import os
from django.core.wsgi import get_wsgi_application
from loguru import logger
import sys
from pathlib import Path
import logging
# Configure Loguru sinks early so app imports see consistent logging.
# Log to stdout (so `docker logs` shows messages) and to a file at
# `/var/log/rad/app.log` for persistent collection / host tailing.
try:
# ensure directory exists
log_dir = Path("/var/log/rad")
log_dir.mkdir(parents=True, exist_ok=True)
# Determine stdout level: allow overriding with LOGURU_STDOUT_LEVEL env var,
# otherwise expose DEBUG when DEBUG env var is truthy, fall back to INFO.
raw_debug = os.environ.get("DEBUG", "0")
env_level = os.environ.get("LOGURU_STDOUT_LEVEL")
if env_level:
stdout_level = env_level
else:
stdout_level = "DEBUG" if raw_debug.lower() in ("1", "true", "yes") else "INFO"
# Add stdout sink (if not already added by other code)
logger.remove() # remove default handlers to avoid duplicate lines
logger.add(sys.stdout, level=stdout_level, enqueue=True, backtrace=False, diagnose=False)
# Add rotating file sink for persistence in container. Use JSON lines
# (serialize=True) to make logs easy to query in Loki/Grafana.
logger.add(
str(log_dir / "app.log"),
rotation="10 MB",
retention="10 days",
level="DEBUG",
enqueue=True,
serialize=True,
)
logger.debug("Loguru logging configured with stdout and file sinks (stdout=%s)", stdout_level)
logging.root.setLevel(logging.DEBUG)
except Exception:
# Best-effort only — don't crash WSGI startup if logging can't be configured
try:
logger.add(sys.stderr, level="DEBUG", enqueue=True, backtrace=False, diagnose=False)
except Exception:
pass
logger.debug("Failed to configure Loguru logging sinks, continuing without file logging")
from .logging_setup import configure_loguru
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rad.settings")
configure_loguru()
application = get_wsgi_application()