This is an automated email from the ASF dual-hosted git repository.
nic-6443 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 694fd352a1 fix(ext-plugin-post-resp): set upstream_addr and
upstream_response_time for loggers (#13940)
694fd352a1 is described below
commit 694fd352a15ec5ef0b34d1e9ece5e55e9daa2bfd
Author: Mohammad Izzraff Janius
<[email protected]>
AuthorDate: Thu Sep 17 15:41:53 2026 +0900
fix(ext-plugin-post-resp): set upstream_addr and upstream_response_time for
loggers (#13940)
---
apisix/plugins/ext-plugin-post-resp.lua | 18 +++++
t/plugin/ext-plugin/response.t | 129 ++++++++++++++++++++++++++++++++
2 files changed, 147 insertions(+)
diff --git a/apisix/plugins/ext-plugin-post-resp.lua
b/apisix/plugins/ext-plugin-post-resp.lua
index 40d3ca450c..12a743cdf7 100644
--- a/apisix/plugins/ext-plugin-post-resp.lua
+++ b/apisix/plugins/ext-plugin-post-resp.lua
@@ -141,6 +141,20 @@ local function send_response(ctx, res, code)
end
+-- The body is read lazily, by send_response or by the runner's RespBody
+-- request, so only time spent waiting on the upstream socket is added to
+-- upstream_response_time. Runner and client time stays in apisix_latency.
+local function timed_body_reader(ctx, reader)
+ return function(...)
+ local start_time = ngx.now()
+ local chunk, err = reader(...)
+ ctx.var.upstream_response_time = ctx.var.upstream_response_time
+ + ngx.now() - start_time
+ return chunk, err
+ end
+end
+
+
function _M.check_schema(conf)
return core.schema.check(_M.schema, conf)
end
@@ -148,12 +162,16 @@ end
function _M.before_proxy(conf, ctx)
local http_obj = http.new()
+ local start_time = ngx.now()
local res, err = get_response(ctx, http_obj)
+ ctx.var.upstream_addr = ctx.picked_server.host .. ":" ..
ctx.picked_server.port
+ ctx.var.upstream_response_time = ngx.now() - start_time
if not res or err then
core.log.error("failed to request: ", err or "")
close(http_obj)
return 502
end
+ res.body_reader = timed_body_reader(ctx, res.body_reader)
ctx.runner_ext_response = res
core.log.info("response info, status: ", res.status)
diff --git a/t/plugin/ext-plugin/response.t b/t/plugin/ext-plugin/response.t
index d8a2be2a56..482d197541 100644
--- a/t/plugin/ext-plugin/response.t
+++ b/t/plugin/ext-plugin/response.t
@@ -430,3 +430,132 @@ GET /plugin_proxy_rewrite_args?aaa=bbb&ccc=ddd
uri: /plugin_proxy_rewrite_args
aaa: bbb
ccc: ddd
+
+
+
+=== TEST 17: add route with http-logger to check upstream vars
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin")
+
+ local code, message = t.test('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "uri": "/*",
+ "plugins": {
+ "ext-plugin-post-resp": {
+ },
+ "http-logger": {
+ "uri": "http://127.0.0.1:1980/log",
+ "batch_max_size": 1
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(message)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 18: upstream and upstream_latency are logged
+--- request
+GET /hello
+--- error_code: 200
+--- response_body
+hello world
+--- error_log eval
+qr/request log: .*"upstream":"127\.0\.0\.1:1980".*"upstream_latency":\d+/
+
+
+
+=== TEST 19: add route whose upstream sends headers first and the body later
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin")
+ local code, message = t.test('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "uri": "/hello",
+ "plugins": {
+ "proxy-rewrite": {"uri": "/delayed_body"},
+ "ext-plugin-post-resp": {},
+ "http-logger": {
+ "uri": "http://127.0.0.1:1980/log",
+ "batch_max_size": 1
+ }
+ },
+ "upstream": {
+ "nodes": {"127.0.0.1:1984": 1},
+ "type": "roundrobin"
+ }
+ }]]
+ )
+ if code >= 300 then ngx.status = code end
+ ngx.say(message)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 20: upstream_latency includes the body delay (body streamed to client)
+--- config
+ location /delayed_body {
+ content_by_lua_block {
+ ngx.print("head")
+ ngx.flush(true)
+ ngx.sleep(0.5)
+ ngx.say("tail")
+ }
+ }
+--- request
+GET /hello
+--- response_body
+headtail
+--- error_log eval
+qr/"upstream_latency":[4-9]\d\d\b/
+
+
+
+=== TEST 21: upstream_latency excludes runner time (body read for the runner)
+--- config
+ location /delayed_body {
+ content_by_lua_block {
+ ngx.print("head")
+ ngx.flush(true)
+ ngx.sleep(1)
+ ngx.say("tail")
+ }
+ }
+--- extra_stream_config
+ server {
+ listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
+
+ content_by_lua_block {
+ ngx.sleep(0.2)
+ local ext = require("lib.ext-plugin")
+ ext.go({extra_info = {{type = "respbody", result = "headtail\n"}}})
+ }
+ }
+--- request
+GET /hello
+--- response_body
+headtail
+--- error_log eval
+qr/"upstream_latency":[3-9]\d\d\b/