Spaces:
Sleeping
Sleeping
File size: 2,124 Bytes
087643a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # Structured JSON logs, one line per request - lets me grep/jq for stuff
# later ("how many /ask requests hit the guardrail today") instead of
# re-running things to find out.
from __future__ import annotations
import json
import logging
import sys
import time
import uuid
from contextlib import contextmanager
class _JsonFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str:
payload = {
"timestamp": self.formatTime(record, "%Y-%m-%dT%H:%M:%S"),
"level": record.levelname,
"message": record.getMessage(),
}
# extra={...} fields ride along here instead of needing a custom
# formatter per call site
for key, value in getattr(record, "extra_fields", {}).items():
payload[key] = value
return json.dumps(payload)
def configure_logging() -> logging.Logger:
logger = logging.getLogger("rap_doclayout")
if logger.handlers:
# avoid double handlers on repeated calls (app reload, test imports)
return logger
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(_JsonFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)
return logger
@contextmanager
def log_request(logger: logging.Logger, endpoint: str, **fields):
"""Logs one line per request with latency, success or failure either
way.
Usage:
with log_request(logger, "/detect") as ctx:
...
ctx["detection_count"] = len(detections)
"""
request_id = uuid.uuid4().hex[:12]
started = time.perf_counter()
ctx = {"request_id": request_id, "endpoint": endpoint, **fields}
error: Exception | None = None
try:
yield ctx
except Exception as exc:
error = exc
raise
finally:
ctx["latency_ms"] = round((time.perf_counter() - started) * 1000, 2)
if error is not None:
ctx["error"] = str(error)
logger.error("request failed", extra={"extra_fields": ctx})
else:
logger.info("request completed", extra={"extra_fields": ctx})
|