From f008beec4df2bf87481aa62edc33d28c3fdc6522 Mon Sep 17 00:00:00 2001 From: 8ga Date: Wed, 15 Oct 2025 14:45:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=2020251011.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 20251011.md | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/20251011.md b/20251011.md index d360578..bb977e5 100644 --- a/20251011.md +++ b/20251011.md @@ -4,6 +4,178 @@ vllm在处理请求时,调用了 get_structured_output_key 函数,在处理 structured_outputs 参数时,由于不满足所有的情况,导致了抛出**No valid structured output parameter found**异常,该异常未被 EngineCore 捕获导致引擎崩溃,APIServer 发现引擎死了,自己也退出了进程。 +## 使用抓包工具 tshark 监控 http 请求 + +### 在合适的目录下执行下面的命令,tshark 需要 root 权限,请使用 root 账号执行 + +##### 安装 tshark(已执行完毕) +``` +sudo apt-get install tshark +``` + +##### 创建一个 shell 脚本 +``` +vim hook_vllm_gpt-oss-120b.sh +``` +脚本内容如下: +``` +#!/bin/bash + +# ======================================== +# 监控本地 v1/chat/completions 接口的 HTTP 请求与响应 +# 仅保留最近 20 条日志(含流式响应,如 SSE) +# 使用 tshark + TCP 流跟踪 +# ======================================== + +# 配置 +INTERFACE="lo" # 本地回环接口 +PORT="8000" # 修改成 vllm 启动 gpt-oss-120b 使用的端口号 +ENDPOINT="/v1/chat/completions" +LOG_FILE="/tmp/chat_completions.log" # 这里是存储最近20条请求日志的文件,根据实际情况修改存储路径 +TEMP_LOG="/tmp/chat_completions.tmp" # 根据实际情况修改,建议与请求日志放在同一个目录下,方便后续删除 +PID_FILE="/tmp/hook_vllm_gpt-oss-120b.pid" # 根据实际情况修改,建议与请求日志放在同一个目录下,方便后续删除 + +# 检查是否已运行 +if [ -f "$PID_FILE" ]; then + if ps -p $(cat "$PID_FILE") > /dev/null 2>&1; then + echo "【错误】监控脚本已在运行 (PID: $(cat $PID_FILE))" + exit 1 + else + rm -f "$PID_FILE" + fi +fi + +# 记录 PID +echo $$ > "$PID_FILE" + +# 清空日志 +> "$LOG_FILE" + +echo "✅ 开始监控 http://127.0.0.1:$PORT$ENDPOINT" +echo "📝 日志将保存到: $LOG_FILE" +echo "⏳ 仅保留最近 20 条,按 Ctrl+C 停止" + +# 信号处理:清理 PID 文件 +trap 'rm -f "$PID_FILE"; echo "⏹️ 监控已停止"; exit 0' SIGINT SIGTERM + +# 使用 tshark 跟踪 TCP 流 +sudo tshark \ + -i "$INTERFACE" \ + -f "tcp port $PORT and host 127.0.0.1" \ + -q \ + -z "follow,tcp,ascii" \ + 2>/dev/null | \ +stdbuf -oL awk -v endpoint="$ENDPOINT" -v log="$LOG_FILE" -v temp="$TEMP" ' +BEGIN { + RS = "\n\n" + ORS = "" + in_request = 0 + buffer = "" + count = 0 +} + +# 分割流,识别每条 TCP 流 +{ + if (match($0, /GET|POST|PUT|DELETE|HTTP/) && index($0, endpoint)) { + # 提取时间戳(tshark 输出第一行包含时间) + if (match($0, /Following.*on port [0-9]+$/)) { + ts = substr($0, RSTART, RLENGTH) + gsub(/.*on/, "on", ts) + } else { + ts = "unknown time" + } + + # 提取请求行和头 + split($0, lines, /\n/) + for (i=1; i<=length(lines); i++) { + if (lines[i] ~ /(GET|POST|PUT|DELETE)/ && index(lines[i], endpoint)) { + request_line = lines[i] + } + if (lines[i] ~ /Content-Type:/ || lines[i] ~ /Authorization:/ || lines[i] ~ /User-Agent:/) { + headers = headers "\n " lines[i] + } + } + + # 提取请求体(通常在空行后) + body = "" + in_body = 0 + for (i=1; i<=length(lines); i++) { + if (lines[i] == "" || lines[i] ~ /HTTP\/[0-9.]/) { + in_body = 1 + continue + } + if (in_body && lines[i] !~ /(No response found|Following)/) { + body = body lines[i] "\n" + } + } + + # 提取响应部分(HTTP/ 开头) + response = "" + for (i=1; i<=length(lines); i++) { + if (lines[i] ~ /^HTTP\// && i > 1) { + for (j=i; j<=length(lines); j++) { + if (lines[j] !~ /Following/) { + response = response lines[j] "\n" + } + } + break + } + } + + # 构造日志条目 + entry = "========================================\n" + entry = entry "🕒 " ts "\n" + entry = entry "📤 请求: " request_line "\n" + if (headers != "") { + entry = entry "📎 头部:\n" headers "\n" + } + if (body != "") { + entry = entry "📦 请求体:\n" body "\n" + } + if (response != "") { + entry = entry "📥 响应:\n" response "\n" + } + entry = entry "========================================\n\n" + + # 写入日志并保留最近 20 条 + cmd = "echo -e \"" entry "\" >> " log " && tail -n 200 " log " > " temp " && mv " temp " " log + system(cmd) + + # 重置 + headers = "" + body = "" + response = "" + } +} +' + +# 正常退出时清理 +rm -f "$PID_FILE" +``` + +##### 赋予执行权限 +``` +chmod +x hook_vllm_gpt-oss-120b.sh +``` + +##### 后台运行脚本 +``` +nohup ./hook_vllm_gpt-oss-120b.sh > /dev/null 2>&1 & +``` + +##### 查看请求日志 + +修改成实际路径 +``` +tail -f /tmp/chat_completions.log +``` + +##### 停止脚本 + +``` +pkill -f hook_vllm_gpt-oss-120b.sh +``` + ### 函数 get_structured_output_key 实现 #### 分支:release/v0.11.0