Files
dy/backend/utils/log_limits.py
T
2026-07-28 15:04:17 +08:00

102 lines
2.8 KiB
Python

"""Bound diagnostic payloads without changing live message processing."""
from __future__ import annotations
import json
import os
from typing import Any
TRUNCATION_MARKER = "\n...[日志内容过长,已截断]"
_MESSAGE_FIELDS = (
"type",
"url",
"uri",
"text",
"name",
"width",
"height",
"duration",
"sticker_id",
"mime_type",
)
def _env_limit(name: str, default: int, minimum: int, maximum: int) -> int:
try:
value = int(os.getenv(name, str(default)) or default)
except (TypeError, ValueError):
value = default
return max(minimum, min(maximum, value))
def truncate_text(value: Any, limit: int) -> str:
text = "" if value is None else str(value)
if len(text) <= limit:
return text
keep = max(0, limit - len(TRUNCATION_MARKER))
return text[:keep] + TRUNCATION_MARKER
def bound_system_log_detail(value: Any) -> str:
return truncate_text(
value,
_env_limit("KEFU_SYSTEM_LOG_MAX_CHARS", 4096, 512, 65536),
)
def _compact_media_message(value: Any) -> Any:
if not isinstance(value, dict):
return truncate_text(value, 2048)
compact: dict[str, Any] = {}
for key in _MESSAGE_FIELDS:
if key not in value:
continue
item = value[key]
compact[key] = truncate_text(item, 2048) if isinstance(item, str) else item
compact["_log_truncated"] = True
return compact
def bound_message_log_content(value: Any) -> str:
"""Keep a valid compact media JSON payload when a log entry is oversized."""
limit = _env_limit("KEFU_MESSAGE_LOG_MAX_CHARS", 16384, 2048, 262144)
text = "" if value is None else str(value)
if len(text) <= limit:
return text
try:
parsed = json.loads(text)
except (TypeError, ValueError, json.JSONDecodeError):
return truncate_text(text, limit)
if isinstance(parsed, dict) and parsed.get("type"):
compact = _compact_media_message(parsed)
elif isinstance(parsed, dict) and isinstance(parsed.get("messages"), list):
compact = {
"messages": [
_compact_media_message(item)
for item in parsed["messages"][:20]
],
"_log_truncated": True,
}
else:
return truncate_text(text, limit)
encoded = json.dumps(compact, ensure_ascii=False, separators=(",", ":"))
return encoded if len(encoded) <= limit else truncate_text(encoded, limit)
def bound_raw_message_log_content(value: Any) -> str:
return truncate_text(
value,
_env_limit("KEFU_RAW_MESSAGE_LOG_MAX_CHARS", 32768, 4096, 262144),
)
def bound_error_log_content(value: Any) -> str:
return truncate_text(
value,
_env_limit("KEFU_ERROR_LOG_MAX_CHARS", 4096, 512, 65536),
)