Use ochttp.Handler to measure server response size. Use http.ServeContent method to serve content.
What did you expect to see?
I expected that server response body size would be measured in the ochttp.ServerResponseBytes stat.
What did you see instead?
Response body size is not measured (metric value stays at 0).
Additional context
http.ServeContent uses io.Copy, passing it io.LimitedReader as the source. This triggers the code path in which io.Copy uses ReadFrom(io.Reader) to do the copy.
When wrapping the http.ResponseWriter, ochttp.trackingResponseWriter uses the underlying http.ResponseWriter as io.ReaderFrom. This means that responses served by the ReadFrom(io.Reader) are not measured, because the call to ReadFrom(io.Reader) bypasses ochttp.trackingResponseWriter.
Program to reproduce below. It also shows that implementing io.ReaderFrom fixes the issue (naive implementation).
What version of OpenCensus are you using?
v0.22.4
What version of Go are you using?
1.14
What did you do?
Use
ochttp.Handler
to measure server response size. Usehttp.ServeContent
method to serve content.What did you expect to see?
I expected that server response body size would be measured in the
ochttp.ServerResponseBytes
stat.What did you see instead?
Response body size is not measured (metric value stays at 0).
Additional context
http.ServeContent
usesio.Copy
, passing itio.LimitedReader
as the source. This triggers the code path in whichio.Copy
usesReadFrom(io.Reader)
to do the copy. When wrapping thehttp.ResponseWriter
,ochttp.trackingResponseWriter
uses the underlyinghttp.ResponseWriter
asio.ReaderFrom
. This means that responses served by theReadFrom(io.Reader)
are not measured, because the call toReadFrom(io.Reader)
bypassesochttp.trackingResponseWriter
.Program to reproduce below. It also shows that implementing
io.ReaderFrom
fixes the issue (naive implementation).output: