Skip to content

feat: populate upstream nginx variables when ai-proxy uses cosocket transport#13317

Merged
nic-6443 merged 2 commits intoapache:masterfrom
nic-6443:nic/upstream-vars
Apr 30, 2026
Merged

feat: populate upstream nginx variables when ai-proxy uses cosocket transport#13317
nic-6443 merged 2 commits intoapache:masterfrom
nic-6443:nic/upstream-vars

Conversation

@nic-6443
Copy link
Copy Markdown
Member

@nic-6443 nic-6443 commented Apr 29, 2026

Description

When the ai-proxy plugin sends requests via cosocket (resty.http), nginx's upstream module is bypassed entirely, leaving $upstream_status, $upstream_addr, $upstream_response_time, $upstream_header_time, $upstream_connect_time, $upstream_response_length, $upstream_host, $upstream_scheme, and $upstream_uri empty or defaulted in access logs.

This uses the FFI functions from apisix-nginx-module 1.19.4 (push_upstream_state / update_upstream_state) to populate these variables from Lua after cosocket requests complete.

Changes

Transport layer (ai-transport/http.lua)

  • Capture timing info (connect_time, header_time, total time) during the HTTP lifecycle
  • Attach upstream metadata (addr, host, scheme, uri, timings) to the response object
  • Close cosocket on all error paths (connect failure, encode failure, request failure)

Plugin layer (ai-proxy/base.lua)

  • Call push_upstream_state() after getting a response (or on transport errors) to populate addr, status, connect_time, header_time
  • Call update_upstream_state() after body is fully consumed to populate response_time and response_length
  • Set upstream_uri, upstream_host, and upstream_scheme to reflect the actual LLM provider endpoint
  • Close cosocket on early return paths (429/5xx, missing body_reader)
  • Works for both ai-proxy and ai-proxy-multi

Runtime

  • Bump apisix-runtime to 1.3.5 (includes apisix-nginx-module 1.19.4)

Docs

  • Document the newly populated upstream variables in the ai-proxy access log section
  • Update the example access log entry to show populated values

Tests

  • t/plugin/ai-proxy-upstream-vars.t: New test validating upstream variable population (addr, status, response_time, uri, host) for streaming and non-streaming
  • Updated t/plugin/ai-proxy3.t: Adjusted access_log regex patterns to match populated upstream variables

…ransport

When the ai-proxy plugin sends requests via cosocket (resty.http), nginx's
upstream module is bypassed, leaving $upstream_status, $upstream_addr,
$upstream_response_time and other upstream variables empty in access logs.

This uses the FFI functions from apisix-nginx-module 1.19.4 to populate
these variables from Lua after cosocket requests complete:

- Capture timing info (connect_time, header_time, response_time) during
  the HTTP lifecycle in ai-transport/http.lua
- Call push_upstream_state() and update_upstream_state() in ai-proxy/base.lua
  to populate the upstream state struct
- Set upstream_host, upstream_scheme, and upstream_uri to reflect the actual
  LLM provider endpoint (not the client's Host header)
- Close cosocket on error paths to prevent connection leaks
- Bump apisix-runtime to 1.3.5 (includes apisix-nginx-module 1.19.4)
Copilot AI review requested due to automatic review settings April 29, 2026 07:22
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Apr 29, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ensures standard Nginx upstream variables are populated for ai-proxy requests sent via cosocket (resty.http), so access logs (and any log consumers) can report upstream address/status/timings even though Nginx’s upstream module is bypassed.

Changes:

  • Capture upstream metadata + timings in ai-transport/http.lua and propagate them via the response object (and via an error metadata return value on failures).
  • Populate Nginx upstream state/vars from ai-proxy/base.lua using resty.apisix.upstream (push on response/error; update after body consumption).
  • Update docs and tests to reflect/log newly populated upstream variables; bump APISIX runtime.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apisix/plugins/ai-transport/http.lua Captures connect/header timing and attaches upstream metadata to the cosocket response (and returns metadata on failure).
apisix/plugins/ai-proxy/base.lua Pushes/updates upstream state for access logging and sets $upstream_scheme/$upstream_host/$upstream_uri based on the provider endpoint.
t/plugin/ai-proxy3.t Updates access_log regex expectations to include upstream addr/status and the upstream URL variables.
t/plugin/ai-proxy-upstream-vars.t Adds a new test intended to validate upstream variable population for streaming and non-streaming.
docs/en/latest/plugins/ai-proxy.md Documents upstream variables being populated and updates the access-log example.
.requirements Bumps APISIX_RUNTIME to 1.3.5.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apisix/plugins/ai-transport/http.lua
Comment thread t/plugin/ai-proxy-upstream-vars.t
Comment thread docs/en/latest/plugins/ai-proxy.md
…onse_time

Now that nginx upstream variables are populated natively via FFI,
the custom apisix_upstream_response_time variable is no longer needed.
Use the standard $upstream_response_time instead.
Copy link
Copy Markdown
Contributor

@Baoyuantop Baoyuantop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description declares upstream_response_length, but it doesn't appear to be implemented in the code?

@nic-6443 nic-6443 merged commit bda084d into apache:master Apr 30, 2026
24 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants