Files

55 lines
1.8 KiB
Python

"""结构化日志:JSON 行日志,含时间、级别、服务、任务 id、事件。
只用标准库 logging。日志绝不写任何密钥、API key、环境变量值:
调用方只传任务 id、状态、事件名这类非敏感字段。
"""
import json
import logging
import sys
import time
class JsonFormatter(logging.Formatter):
"""把每条记录格式化成一行 JSON,方便后续按字段过滤聚合。"""
def format(self, record):
payload = {
"ts": time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(record.created)),
"level": record.levelname,
"service": "cloud-control-plane",
"logger": record.name,
"message": record.getMessage(),
}
for key in ("task_id", "project_id", "event", "status"):
if hasattr(record, key):
payload[key] = getattr(record, key)
if record.exc_info and record.exc_info[0] is not None:
payload["error_type"] = record.exc_info[0].__name__
return json.dumps(payload, ensure_ascii=False)
def setup_logging(level=logging.INFO, stream=None):
"""配置根 logger 为 JSON 行日志;重复调用不重复加 handler。"""
handler = logging.StreamHandler(stream or sys.stderr)
handler.setFormatter(JsonFormatter())
root = logging.getLogger()
root.handlers = [handler]
root.setLevel(level)
return root
def get_logger(name="cloud"):
return logging.getLogger(name)
def log_event(logger, event, task_id=None, project_id=None, status=None,
message=None):
"""记一条结构化事件日志;message 默认就是事件名。"""
logger.info(message or event, extra={
"event": event,
"task_id": task_id,
"project_id": project_id,
"status": status,
})