Open lwwgo opened 1 year ago
This functionality looks orthogonal to the purpose of ReverseProxy (you could just as easily wrap it in middleware that will do the tracking for you, eg https://pkg.go.dev/github.com/felixge/httpsnoop). Additionally, a per-proxy count doesn't appear to be very useful, most people seem to want a per handler count.
CC @neild @bradfitz
This functionality looks orthogonal to the purpose of ReverseProxy (you could just as easily wrap it in middleware that will do the tracking for you, eg https://pkg.go.dev/github.com/felixge/httpsnoop). Additionally, a per-proxy count doesn't appear to be very useful, most people seem to want a per handler count.
thanks for your response. felixge/httpsnoop package:
// myH is your app's http handler, perhaps a http.ServeMux or similar.
var myH http.Handler
// wrappedH wraps myH in order to log every request.
wrappedH := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
m := httpsnoop.CaptureMetrics(myH, w, r) // This line is block, when header contains "Transfer-Encoding: chunked"
log.Printf(
"%s %s (code=%d dt=%s written=%d)",
r.Method,
r.URL,
m.Code,
m.Duration,
m.Written,
)
})
http.ListenAndServe(":8080", wrappedH)
It does not work, when ReverseProxy is used for proxying live streaming by http-flv format and backend http server response data by chunk mode, in other words, Transfer-Encoding: chunked. Unfortunately, CaptureMetrics() does not return any statistics until the live stream is closed. Obviously, felixge/httpsnoop package is ineffective for live stream proxy. I need a golang packet with real-time statistics of forwarding traffic. Do you have other solutions? @seankhliao Thanks.
As @seankhliao says, this seems orthogonal to ReverseProxy
. You could as easily want to track bytes sent by some other handler.
You should be able to build this with a middleware handler that wraps the http.ResponseWriter
. Something like:
type CountingResponseWriter struct {
http.ResponseWriter
Count int
}
func (c *CountingResponseWriter) Write(p []byte) (n int, err error) {
n, err = c.ResponseWriter.Write(p)
c.Count += n // apply locking as needed
return n, err
}
func (c *CountingResponseWriter) Unwrap() http.ResponseWriter { return c.ResponseWriter }
demo code:
goal:get the length of proxy had sent data, it is successful, but it is block when response is live streaming, because io.ReadAll() can not read EOF or error from streaming。The stream has always existed and has no end。
Design: