caddy配置codex的API接口样例

域名 {

    log {
        output file /var/log/caddy/cch-access.log {
            roll_size 100MiB
            roll_keep 10
            roll_keep_for 720h
        }
        format json
    }

    log_append <codex_request_id {http.request.header.X-Client-Request-Id}
    log_append <codex_thread_id {http.request.header.Thread-Id}
    log_append <codex_subagent {http.request.header.X-Openai-Subagent}

    reverse_proxy 127.0.0.1:端口 {
        header_up X-Real-IP {remote_host}

        stream_close_delay 15m

        transport http {
            dial_timeout 5s
            keepalive 120s
            keepalive_interval 30s
            keepalive_idle_conns 256
            keepalive_idle_conns_per_host 256
            compression off
        }
    }

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Frame-Options "DENY"
        X-Content-Type-Options "nosniff"
        -Server
    }
}

直接查看最近的 Codex 499/取消请求

如果 Caddy 用 systemd 启动,执行:

sudo journalctl -u caddy \
  --since "24 hours ago" \
  --no-pager \
  -o cat |
jq -c '
select(
  .logger == "http.handlers.reverse_proxy"
  and .msg == "aborting with incomplete response"
  and .request.uri == "/v1/responses"
  and ((.error // "") | contains("context canceled"))
) |
{
  time: (.ts | todateiso8601),
  duration: .duration,
  client_ip: .request.client_ip,
  uri: .request.uri,
  request_id: (.request.headers["X-Client-Request-Id"][0] // ""),
  thread_id: (.request.headers["Thread-Id"][0] // ""),
  subagent: (.request.headers["X-Openai-Subagent"][0] // ""),
  user_agent: (.request.headers["User-Agent"][0] // ""),
  error: .error
}'

会得到类似:

{
  "time":"2026-08-27T05:47:44Z",
  "duration":49.535,
  "client_ip":"180.190.114.41",
  "uri":"/v1/responses",
  "request_id":"01a041bf-fb57-7010-bbd3-bf1db88918ec",
  "thread_id":"01a041bf-fb57-7010-bbd3-bf1db88918ec",
  "subagent":"collab_spawn",
  "user_agent":"codex-tui/0.149.1 ...",
  "error":"reading: context canceled"
}

实时监控 499

如果你想一边运行 Codex,一边等 499 出现:

sudo journalctl -u caddy -f -o cat |
jq --unbuffered -c '
select(
  .logger == "http.handlers.reverse_proxy"
  and .msg == "aborting with incomplete response"
  and .request.uri == "/v1/responses"
  and ((.error // "") | contains("context canceled"))
) |
{
  time: (.ts | todateiso8601),
  duration: .duration,
  request_id: (.request.headers["X-Client-Request-Id"][0] // ""),
  thread_id: (.request.headers["Thread-Id"][0] // ""),
  subagent: (.request.headers["X-Openai-Subagent"][0] // ""),
  error: .error
}'