You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
from logging.handlers import RotatingFileHandler
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from iti.config import BaseConfig
|
|
|
|
|
|
class SafeFormatter(logging.Formatter):
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
for key in ("trace_id", "request_id", "actor_type", "actor_id", "response_code"):
|
|
if not hasattr(record, key):
|
|
setattr(record, key, "-")
|
|
return super().format(record)
|
|
|
|
|
|
def configure_logging(config: BaseConfig) -> None:
|
|
level = getattr(logging, config.log_level.upper(), logging.INFO)
|
|
formatter = SafeFormatter(
|
|
"%(asctime)s %(levelname)s %(name)s "
|
|
"trace=%(trace_id)s actor=%(actor_type)s:%(actor_id)s code=%(response_code)s - %(message)s"
|
|
)
|
|
|
|
root_logger = logging.getLogger("iti")
|
|
root_logger.setLevel(level)
|
|
root_logger.handlers.clear()
|
|
root_logger.propagate = False
|
|
|
|
console_handler = logging.StreamHandler()
|
|
console_handler.setLevel(level)
|
|
console_handler.setFormatter(formatter)
|
|
root_logger.addHandler(console_handler)
|
|
|
|
error_logger = logging.getLogger("iti.error")
|
|
error_logger.setLevel(logging.ERROR)
|
|
error_logger.handlers.clear()
|
|
error_logger.propagate = False
|
|
|
|
if config.log_file_enabled:
|
|
log_dir = Path(config.log_dir)
|
|
log_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
app_handler = RotatingFileHandler(
|
|
log_dir / "app.log",
|
|
encoding="utf-8",
|
|
maxBytes=config.log_max_bytes,
|
|
backupCount=config.log_backup_count,
|
|
)
|
|
app_handler.setLevel(level)
|
|
app_handler.setFormatter(formatter)
|
|
root_logger.addHandler(app_handler)
|
|
|
|
error_handler = RotatingFileHandler(
|
|
log_dir / "error.log",
|
|
encoding="utf-8",
|
|
maxBytes=config.log_max_bytes,
|
|
backupCount=config.log_backup_count,
|
|
)
|
|
error_handler.setLevel(logging.ERROR)
|
|
error_handler.setFormatter(formatter)
|
|
root_logger.addHandler(error_handler)
|
|
error_logger.addHandler(error_handler)
|
|
|
|
|
|
def log_extra(request: Any | None = None) -> dict[str, Any]:
|
|
if request is None:
|
|
return {
|
|
"trace_id": "-",
|
|
"request_id": "-",
|
|
"actor_type": "-",
|
|
"actor_id": "-",
|
|
"response_code": "-",
|
|
}
|
|
actor = getattr(request.state, "actor", None)
|
|
principal = getattr(request.state, "principal", None)
|
|
return {
|
|
"trace_id": getattr(request.state, "trace_id", "-"),
|
|
"request_id": getattr(request.state, "request_id", "-"),
|
|
"actor_type": getattr(actor, "type", None) or ("user" if principal else "-"),
|
|
"actor_id": getattr(actor, "id", None) or getattr(principal, "id", "-"),
|
|
"response_code": getattr(request.state, "response_code", "-"),
|
|
}
|