Spaces:
Sleeping
Sleeping
| import logging | |
| import sys | |
| import json | |
| from datetime import datetime, timezone | |
| class _JSONFormatter(logging.Formatter): | |
| def format(self, record: logging.LogRecord) -> str: | |
| log: dict = { | |
| "timestamp": datetime.now(timezone.utc).isoformat(), | |
| "level": record.levelname, | |
| "logger": record.name, | |
| "message": record.getMessage(), | |
| } | |
| if record.exc_info: | |
| log["exception"] = self.formatException(record.exc_info) | |
| extra = { | |
| k: v | |
| for k, v in record.__dict__.items() | |
| if k not in logging.LogRecord.__dict__ | |
| and k | |
| not in ( | |
| "message", | |
| "asctime", | |
| "args", | |
| "exc_info", | |
| "exc_text", | |
| "stack_info", | |
| "lineno", | |
| "funcName", | |
| "created", | |
| "msecs", | |
| "relativeCreated", | |
| "thread", | |
| "threadName", | |
| "processName", | |
| "process", | |
| "taskName", | |
| ) | |
| } | |
| if extra: | |
| log["context"] = extra | |
| return json.dumps(log) | |
| def get_logger(name: str) -> logging.Logger: | |
| logger = logging.getLogger(name) | |
| logger.propagate = False # always set — prevents duplicate lines via root logger | |
| if not logger.handlers: | |
| handler = logging.StreamHandler(sys.stdout) | |
| handler.setFormatter(_JSONFormatter()) | |
| logger.addHandler(handler) | |
| logger.setLevel(logging.INFO) | |
| return logger | |