65 lines
1.9 KiB
Python
65 lines
1.9 KiB
Python
"""
|
|
Demeter Server — Logging Configuration
|
|
|
|
Sets up structured logging with optional Loki integration.
|
|
Falls back to console-only logging if Loki is unreachable.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import sys
|
|
from typing import Optional
|
|
|
|
|
|
def setup_logging(loki_url: Optional[str] = None, debug: bool = False) -> None:
|
|
"""
|
|
Configure logging for the Demeter server.
|
|
|
|
Args:
|
|
loki_url: Loki push endpoint (e.g., "http://localhost:3100/loki/api/v1/push").
|
|
If None, logs go to console only.
|
|
debug: Enable DEBUG level logging.
|
|
"""
|
|
level = logging.DEBUG if debug else logging.INFO
|
|
|
|
# Root logger
|
|
root = logging.getLogger()
|
|
root.setLevel(level)
|
|
|
|
# Console handler
|
|
console = logging.StreamHandler(sys.stdout)
|
|
console.setLevel(level)
|
|
fmt = logging.Formatter(
|
|
"[%(asctime)s] %(levelname)-8s %(name)s — %(message)s",
|
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
)
|
|
console.setFormatter(fmt)
|
|
root.addHandler(console)
|
|
|
|
# Loki handler (optional)
|
|
if loki_url:
|
|
try:
|
|
import logging_loki
|
|
|
|
loki_handler = logging_loki.LokiHandler(
|
|
url=loki_url,
|
|
tags={"app": "demeter-server"},
|
|
version="1",
|
|
)
|
|
loki_handler.setLevel(level)
|
|
root.addHandler(loki_handler)
|
|
logging.getLogger(__name__).info("Loki logging enabled at %s", loki_url)
|
|
except ImportError:
|
|
logging.getLogger(__name__).warning(
|
|
"python-logging-loki not installed, Loki logging disabled"
|
|
)
|
|
except Exception as e:
|
|
logging.getLogger(__name__).warning(
|
|
"Failed to connect to Loki at %s: %s", loki_url, e
|
|
)
|
|
|
|
# Quiet noisy libraries
|
|
logging.getLogger("aiocoap").setLevel(logging.WARNING)
|
|
logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
|