mirror of
https://github.com/ParisNeo/ollama_proxy_server.git
synced 2025-09-06 05:12:14 +00:00
Update logging_config.py
This commit is contained in:
@@ -4,7 +4,7 @@ Centralised logging configuration for the Ollama Proxy Server.
|
||||
|
||||
Features
|
||||
--------
|
||||
* Human‑readable console output by default.
|
||||
* Human‑readable console output by default (with proper millisecond timestamps).
|
||||
* Optional JSON output via the LOG_FORMAT env‑var (kept for backward‑compatibility).
|
||||
* All loggers (root, uvicorn, gunicorn, etc.) share the same configuration.
|
||||
* The `setup_logging()` helper can be called from any entry‑point (FastAPI,
|
||||
@@ -15,7 +15,6 @@ import logging
|
||||
import logging.config
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pythonjsonlogger import jsonlogger
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@@ -23,14 +22,14 @@ from pythonjsonlogger import jsonlogger
|
||||
# ----------------------------------------------------------------------
|
||||
class HumanReadableFormatter(logging.Formatter):
|
||||
"""
|
||||
Example output:
|
||||
2025-09-05 12:15:50,297 [ERROR] gunicorn.error – Worker (pid:590871) was sent SIGINT!
|
||||
Example output (note the millisecond precision):
|
||||
2025-09-05 15:35:22,123 [INFO] gunicorn.error – Starting gunicorn 23.0.0
|
||||
"""
|
||||
DEFAULT_FORMAT = "%(asctime)s [%(levelname)s] %(name)s – %(message)s"
|
||||
DEFAULT_DATEFMT = "%Y-%m-%d %H:%M:%S,%f"
|
||||
# %(asctime)s is generated by the base Formatter; we append milliseconds via %(msecs)03d
|
||||
DEFAULT_FORMAT = "%(asctime)s,%(msecs)03d [%(levelname)s] %(name)s – %(message)s"
|
||||
DEFAULT_DATEFMT = "%Y-%m-%d %H:%M:%S" # no %f here – we add ms ourselves
|
||||
|
||||
def __init__(self):
|
||||
# ``asctime`` already includes microseconds; we trim to milliseconds
|
||||
super().__init__(self.DEFAULT_FORMAT, self.DEFAULT_DATEFMT)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@@ -38,11 +37,11 @@ class HumanReadableFormatter(logging.Formatter):
|
||||
# ----------------------------------------------------------------------
|
||||
class JsonFormatter(jsonlogger.JsonFormatter):
|
||||
"""
|
||||
Emits the same fields that the original configuration emitted.
|
||||
Emits JSON logs similar to the original configuration.
|
||||
"""
|
||||
def add_fields(self, log_record, record, message_dict):
|
||||
super().add_fields(log_record, record, message_dict)
|
||||
# Ensure a numeric epoch timestamp like the previous version
|
||||
# Preserve a float epoch timestamp like the previous version
|
||||
if not log_record.get("timestamp"):
|
||||
log_record["timestamp"] = record.created
|
||||
# Normalise level name to upper‑case
|
||||
@@ -53,7 +52,7 @@ class JsonFormatter(jsonlogger.JsonFormatter):
|
||||
# ----------------------------------------------------------------------
|
||||
def _build_logging_config(log_level: str = "INFO") -> dict:
|
||||
"""
|
||||
Returns a ``dict`` compatible with ``logging.config.dictConfig``.
|
||||
Returns a dict compatible with ``logging.config.dictConfig``.
|
||||
``log_level`` can be any standard level name (case‑insensitive).
|
||||
"""
|
||||
level = log_level.upper()
|
||||
@@ -86,14 +85,17 @@ def _build_logging_config(log_level: str = "INFO") -> dict:
|
||||
"stream": "ext://sys.stdout",
|
||||
},
|
||||
},
|
||||
# ---------- ROOT LOGGER ----------
|
||||
# ------------------------------------------------------------------
|
||||
# ROOT LOGGER (required – this was missing before)
|
||||
# ------------------------------------------------------------------
|
||||
"root": {
|
||||
"level": level,
|
||||
"handlers": ["default"],
|
||||
},
|
||||
# ---------- OTHER LOGGERS ----------
|
||||
# ------------------------------------------------------------------
|
||||
# SPECIFIC LIBRARY LOGGERS (prevent duplicate handlers)
|
||||
# ------------------------------------------------------------------
|
||||
"loggers": {
|
||||
# Explicitly configure the popular libraries so they don’t add extra handlers
|
||||
"uvicorn.error": {"handlers": ["default"], "level": level, "propagate": False},
|
||||
"uvicorn.access": {"handlers": ["default"], "level": level, "propagate": False},
|
||||
"gunicorn.error": {"handlers": ["default"], "level": level, "propagate": False},
|
||||
|
Reference in New Issue
Block a user