rebuild(stage-2): establish runtime and persistence foundations

This commit is contained in:
leefer
2026-07-30 01:02:04 +08:00
parent b3ba840d4e
commit d969d2c092
26 changed files with 865 additions and 33 deletions
+79
View File
@@ -0,0 +1,79 @@
from __future__ import annotations
import json
import logging
import re
from datetime import datetime
from logging.handlers import RotatingFileHandler
from pathlib import Path
from typing import Any
from zoneinfo import ZoneInfo
SENSITIVE_KEYS = (
"api_key",
"authorization",
"cookie",
"password",
"refresh_token",
"secret",
"token",
)
SENSITIVE_VALUE_PATTERN = re.compile(
r"(?i)\b(api[_-]?key|authorization|password|refresh[_-]?token|secret|token)"
r"\s*[:=]\s*[^\s,;]+"
)
BEARER_PATTERN = re.compile(r"(?i)\bbearer\s+[a-z0-9._~+/-]{8,}")
SHANGHAI_TIMEZONE = ZoneInfo("Asia/Shanghai")
def redact(value: Any) -> Any:
if isinstance(value, dict):
return {
str(key): "[REDACTED]" if _is_sensitive(str(key)) else redact(item)
for key, item in value.items()
}
if isinstance(value, (list, tuple)):
return [redact(item) for item in value]
if isinstance(value, str):
safe = SENSITIVE_VALUE_PATTERN.sub(lambda match: f"{match.group(1)}=[REDACTED]", value)
return BEARER_PATTERN.sub("Bearer [REDACTED]", safe)
return value
def _is_sensitive(key: str) -> bool:
normalized = key.lower().replace("-", "_")
return any(marker in normalized for marker in SENSITIVE_KEYS)
class JsonFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str:
payload: dict[str, Any] = {
"timestamp": datetime.now(SHANGHAI_TIMEZONE).isoformat(timespec="milliseconds"),
"level": record.levelname.lower(),
"logger": record.name,
"message": record.getMessage(),
}
for field in ("request_id", "event", "context"):
if hasattr(record, field):
payload[field] = redact(getattr(record, field))
if record.exc_info:
payload["exception"] = record.exc_info[0].__name__
return json.dumps(redact(payload), ensure_ascii=False, separators=(",", ":"))
def configure_logging(level: str, log_file: Path | None) -> None:
handlers: list[logging.Handler] = [logging.StreamHandler()]
if log_file is not None:
log_file.parent.mkdir(parents=True, exist_ok=True)
handlers.append(
RotatingFileHandler(
log_file,
maxBytes=10 * 1024 * 1024,
backupCount=3,
encoding="utf-8",
)
)
formatter = JsonFormatter()
for handler in handlers:
handler.setFormatter(formatter)
logging.basicConfig(level=level, handlers=handlers, force=True)