| import logging |
| import sys |
| import json |
| from typing import Any, Dict |
|
|
| class JSONFormatter(logging.Formatter): |
| """ |
| Formatter that outputs JSON strings after parsing the LogRecord. |
| """ |
| def format(self, record: logging.LogRecord) -> str: |
| log_record: Dict[str, Any] = { |
| "timestamp": self.formatTime(record, self.datefmt), |
| "level": record.levelname, |
| "message": record.getMessage(), |
| "module": record.module, |
| "funcName": record.funcName, |
| "lineNo": record.lineno, |
| } |
| |
| if record.exc_info: |
| log_record["exception"] = self.formatException(record.exc_info) |
| |
| return json.dumps(log_record) |
|
|
| def setup_logging(log_level: str = "INFO"): |
| """ |
| Setup structured logging. |
| """ |
| root_logger = logging.getLogger() |
| root_logger.setLevel(log_level) |
| |
| handler = logging.StreamHandler(sys.stdout) |
| formatter = JSONFormatter() |
| handler.setFormatter(formatter) |
| |
| root_logger.handlers = [] |
| root_logger.addHandler(handler) |
| |
| logging.getLogger("uvicorn.access").handlers = [] |
| logging.getLogger("uvicorn.access").propagate = True |
|
|