# Use middleware to log time it takes client to receive response

**URL:** https://discourse.julialang.org/t/use-middleware-to-log-time-it-takes-client-to-receive-response/91250
**Category:** Web Stack
**Tags:** question, profiling
**Created:** [December 5, 2022, 9:58am UTC](https://discourse.julialang.org/t/use-middleware-to-log-time-it-takes-client-to-receive-response/91250 "2022-12-05T09:58:48Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [December 5, 2022, 9:58am UTC](https://discourse.julialang.org/t/use-middleware-to-log-time-it-takes-client-to-receive-response/91250/1 "2022-12-05T09:58:48Z")

</div>

I’m trying to understand how to use [`HTTP.jl`’s middleware](https://juliaweb.github.io/HTTP.jl/stable/server/#HTTP.Middleware) to log the amount of time between two distinct events:

1. The server started sending the response
2. The client received it

The following MWE doesn’t accomplish this, but might serve as a good starting point:

```julia
using HTTP, Random

const times = UInt64[]

function get_durations(times)
    calculating, sending = round.(diff(times) ./ 10^9, digits = 4)
    @info "durations:" calculating sending
    empty!(times)
end

function log_time(handler)
    return function(req)
        ret = handler(req)
        push!(times, time_ns()) # log time to send data?
        get_durations(times)
        return ret
    end
end

function handler(req)
    push!(times, time_ns()) # log starting time
    data = randstring(1_000_000)
    push!(times, time_ns()) # log time to calculate data
    return HTTP.Response(200, data)
end

HTTP.serve(log_time(handler))

```

Maybe this is simply impossible…?

---

<div class="post-metadata">

### Author: ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)
#### Post date: [December 5, 2022, 3:12pm UTC](https://discourse.julialang.org/t/use-middleware-to-log-time-it-takes-client-to-receive-response/91250/2 "2022-12-05T15:12:36Z")

</div>

> [@yakir12](#):
>
> The client received it

Generally you can’t know this during request handling. There may be intervening servers, such as reverse proxies. If you control the client, maybe have the client send back a timestamp after receiving the response.

---

<div class="post-metadata">

### Author: ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)
#### Post date: [December 6, 2022, 5:21pm UTC](https://discourse.julialang.org/t/use-middleware-to-log-time-it-takes-client-to-receive-response/91250/3 "2022-12-06T17:21:39Z")

</div>

Yeah, I agree. We could potentially add an “eventing system” to HTTP.jl on both client and server side so you could hook into various checkpoints, but even then, you would need to even both client _and_ server to really get what you’re after here.

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [December 7, 2022, 7:46am UTC](https://discourse.julialang.org/t/use-middleware-to-log-time-it-takes-client-to-receive-response/91250/4 "2022-12-07T07:46:17Z")

</div>

@christopher-dG came up with a really good suggestion, and it’s to use a modified `streamhandler` (original copied from [HTTP.jl/Handlers.jl at master · JuliaWeb/HTTP.jl · GitHub](https://github.com/JuliaWeb/HTTP.jl/blob/master/src/Handlers.jl#L53-L64)), for example:

```julia
function streamhandler_with_timings(handler)
    return function(stream::HTTP.Stream)
        request::HTTP.Request = stream.message
        request.body = read(stream)
        closeread(stream)
        request.response::HTTP.Response = handler(request)
        request.response.request = request
        @time begin
            startwrite(stream)
            write(stream, request.response.body)
        end # done sending
        return
    end
end

```

What do you think about that?

---

<div class="post-metadata">

### Author: ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)
#### Post date: [December 7, 2022, 6:24pm UTC](https://discourse.julialang.org/t/use-middleware-to-log-time-it-takes-client-to-receive-response/91250/5 "2022-12-07T18:24:05Z")

</div>

This doesn’t address the issue raised above. The client doesn’t necessarily receive the response when the server has finished writing. It depends on your use case and client/server configuration whether it is good enough.
