chore(logging): stream backend logs to console + instrument dispatch/notify
This commit is contained in:
54
backend/app/core/logging.py
Normal file
54
backend/app/core/logging.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
|
||||
def _level() -> str:
|
||||
return (os.environ.get("LOG_LEVEL") or os.environ.get("UVICORN_LOG_LEVEL") or "INFO").upper()
|
||||
|
||||
|
||||
def configure_logging() -> None:
|
||||
"""Configure app logging to stream to stdout.
|
||||
|
||||
Uvicorn already logs requests, but we want our app/integrations logs to be visible
|
||||
in the same console stream.
|
||||
"""
|
||||
|
||||
level = getattr(logging, _level(), logging.INFO)
|
||||
|
||||
root = logging.getLogger()
|
||||
root.setLevel(level)
|
||||
|
||||
# Avoid duplicate handlers (e.g., when autoreload imports twice)
|
||||
if not any(isinstance(h, logging.StreamHandler) for h in root.handlers):
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setLevel(level)
|
||||
formatter = logging.Formatter(
|
||||
fmt="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
|
||||
datefmt="%Y-%m-%dT%H:%M:%SZ",
|
||||
)
|
||||
handler.setFormatter(formatter)
|
||||
root.addHandler(handler)
|
||||
|
||||
# Make common noisy loggers respect our level
|
||||
for name in [
|
||||
"uvicorn",
|
||||
"uvicorn.error",
|
||||
"uvicorn.access",
|
||||
"sqlalchemy.engine",
|
||||
"httpx",
|
||||
"requests",
|
||||
]:
|
||||
logging.getLogger(name).setLevel(level)
|
||||
|
||||
|
||||
def log_kv(logger: logging.Logger, msg: str, **kv: Any) -> None:
|
||||
# Lightweight key-value logging without requiring JSON logging.
|
||||
if kv:
|
||||
suffix = " ".join(f"{k}={v!r}" for k, v in kv.items())
|
||||
logger.info(f"{msg} | {suffix}")
|
||||
else:
|
||||
logger.info(msg)
|
||||
Reference in New Issue
Block a user