I tried both share_all_vars and the header idea. Unfortunately neither of those actually work.
Even with ngx.location.capture('/bar', {share_all_vars = true}), I don't see upstream variables being set. Are those variables not shared?
After reading the definition of this variable, i found this variable has the flag NGX_HTTP_VAR_NOCACHEABLE, every time we call ngx.var.upstream_response_time,
the get_handler will be triggered, so we cannot get the subrequest's $upstream_response_time value.
If I set upstream response time as a header "more_set_headers 'Upstream_time: $upstream_response_time';", it results in a really strange value e.g. Upstream_time: 1507915223.173 while its recorded in access log correctly as -
"127.0.0.1 - - [13/Oct/2017:10:20:23 -0700] "GET /bar HTTP/1.1" 200 14 "-" "curl/7.54.0" "-" "0.086" "0.086""
The get_handler of $upstream_response_time calculates the value from the r->upstream->state->response_time, the response_time will be assigned with the current time when connecting to the upstream for the first time and it will be updated when finaizing the request. That's why you see the value "1507915223.173."
There is a compromise way that we can add a body_filter_by_lua hook and check the ngx.arg[2], when it is true, save the $upstream_response_time to our custom varible like "$my_upstream_response_time". I have written a simple configuration and it seems to work.
server {
listen 8081;
server_name localhost;
location / {
content_by_lua_block {
local res = ngx.location.capture("/proxy", { share_all_vars = true })
ngx.say(ngx.var.my_upstream_response_time)
}
}
location /proxy {
set $my_upstream_response_time "";
proxy_pass http://127.0.0.1:8082/;
body_filter_by_lua_block {
if ngx.arg[2] == true then
ngx.var.my_upstream_response_time = ngx.var.upstream_response_time
end
}
}
}
server {
listen 8082;
server_name _;
location / {
return 200 "Plain";
}
}