hello! curious what's the best approach to attach the size of the response body to our telemetry data for an issue i'm trying to debug. i see as 39cc924 that the body is this function io.pedestal.http.response/stream-xform
this was what i originally tried
{:name ::custom-trace-metrics
:leave (fn [context]
(when-let [body (get-in context [:response :body])]
(when-let [len (cond
(bytes? body) (alength body)
(string? body) (alength (String/.getBytes body)))]
(span/add-span-data! {:attributes {:http.response.bytes len}})))
context)}One of the types of response body is a function; this function is passed an OutputStream, and is responsible for writing the actual response to it. That's very opaque, of course. The stream-form (really, stream-xform/fn) is a wrapper that converts a result collection to an output format, typically JSON, and writes the JSON stream out.
So it would be better if whatever attached the body, set the Content-Length header as well, if it knows ahead of time how big the content stream is going to be.
http://pedestal.io/pedestal/0.8/reference/response-bodies.html -- there's a lot of possible returns types.
I've had to touch on all of these in my latest rounds of refactoring.
we are using io.pedestal.http/json-body to format the response. are you saying that it would be ideal for this function to set Content-Length in addition to Content-Type?
That would be ideal for your use case, but could be costly otherwise ... it would be necessary to run the entire streaming operation twice; once to determine the length, and again to generate the content. Alternately, it could be changed to simply create a String or ByteBuffer of the content ... but that requires potentially more memory than writing to an OuputStream. There's always trade-offs.
When I say "it could be changed" I mean your could swap out the default Pedestal interceptor for this, with one of your own that could, perhaps, do the encoding to a String and (if this makes sense) emit the metric in one go.
that makes sense, thanks!