"""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), )