初始化
This commit is contained in:
67
tg_bridge/http_logging.py
Normal file
67
tg_bridge/http_logging.py
Normal 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
|
||||
Reference in New Issue
Block a user