From 6722ae3a835702073682e020d8736140fc04538e Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Mon, 22 Feb 2021 11:57:21 -0700 Subject: reverseproxy: Add duration/latency placeholders (close #4012) (#4013) * reverseproxy: Add duration/latency placeholders (close #4012) (and #2268) Adds 4 placeholders, one is actually outside reverse proxy though: {http.request.duration} is how long since the server decoded the HTTP request (headers). {http.reverse_proxy.upstream.latency} is how long it took a proxy upstream to write the response header. {http.reverse_proxy.upstream.duration} is total time proxying to the upstream, including writing response body to client. {http.reverse_proxy.duration} is total time spent proxying, including selecting an upstream and retries. Obviously, most of these are only useful at the end of a request, like when writing response headers or logs. See also: https://caddy.community/t/any-equivalent-of-request-time-and-upstream-header-time-from-nginx/11418 * Add new placeholders to documentation --- modules/caddyhttp/replacer.go | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'modules/caddyhttp/replacer.go') diff --git a/modules/caddyhttp/replacer.go b/modules/caddyhttp/replacer.go index 5a0efce..d0767f0 100644 --- a/modules/caddyhttp/replacer.go +++ b/modules/caddyhttp/replacer.go @@ -36,6 +36,7 @@ import ( "path" "strconv" "strings" + "time" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddytls" @@ -52,6 +53,8 @@ func NewTestReplacer(req *http.Request) *caddy.Replacer { } func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.ResponseWriter) { + SetVar(req.Context(), "start_time", time.Now()) + httpVars := func(key string) (interface{}, bool) { if req != nil { // query string parameters @@ -140,6 +143,9 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo return dir, true case "http.request.uri.query": return req.URL.RawQuery, true + case "http.request.duration": + start := GetVar(req.Context(), "start_time").(time.Time) + return time.Since(start), true case "http.request.body": if req.Body == nil { return "", true -- cgit v1.2.3