初始化

This commit is contained in:
van
2026-04-23 22:06:19 +08:00
commit e9823c2261
26 changed files with 840 additions and 0 deletions

67
tg_bridge/http_logging.py Normal file
View File

@@ -0,0 +1,67 @@
"""HTTP 访问日志与转发内容摘要(可配置是否打出正文预览)。"""
from __future__ import annotations
import logging
import os
import time
from collections.abc import Callable
from typing import Any
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response
access_logger = logging.getLogger("tg_bridge.access")
def log_preview_max_chars() -> int:
"""环境变量 BRIDGE_LOG_PREVIEW_CHARS>0 时在业务日志中附带截断后的正文/回复预览;未设置或 0 则只打长度。"""
raw = os.environ.get("BRIDGE_LOG_PREVIEW_CHARS", "").strip()
if not raw:
return 0
try:
return max(0, int(raw))
except ValueError:
return 0
def preview_for_log(text: str | None, max_chars: int) -> str:
if not text or max_chars <= 0:
return ""
s = text.replace("\r", "").replace("\n", "\\n")
if len(s) <= max_chars:
return s
return s[:max_chars] + "..."
class AccessLogMiddleware(BaseHTTPMiddleware):
"""记录每条 HTTP 请求的方法、路径、状态码与耗时(不含鉴权头与 Body"""
async def dispatch(self, request: Request, call_next: Callable[[Request], Any]) -> Response:
start = time.perf_counter()
client = request.client.host if request.client else "-"
path = request.url.path
method = request.method
try:
response = await call_next(request)
except Exception:
elapsed_ms = (time.perf_counter() - start) * 1000
access_logger.exception(
'%s "%s %s" 未捕获异常 %.1fms',
client,
method,
path,
elapsed_ms,
)
raise
elapsed_ms = (time.perf_counter() - start) * 1000
access_logger.info(
'%s "%s %s" %s %.1fms',
client,
method,
path,
response.status_code,
elapsed_ms,
)
return response