Skip to content
A helper for collecting and emitting metadata throughout a request lifecycle.
Go
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.build.yml CI (#2) Aug 20, 2019
.gitignore
LICENSE
README.md
data.go
data_test.go
go.mod Remove dependency on go-cmp (#3) Aug 27, 2019
go.sum

README.md

ctxdata GoDoc builds.sr.ht status

A helper for collecting and emitting metadata throughout a request lifecycle.

When a new request arrives in your program, HTTP server, etc., use the New constructor with the incoming request's context to construct a new, empty Data.

func handler(w http.ResponseWriter, r *http.Request) {
    ctx, d := ctxdata.New(r.Context())

Use the returned context for all further operations on that request.

    otherHandler(w, r.WithContext(ctx))
    result, err := process(ctx, r.Header.Get("X-My-Key"))
    // etc.

Whenever you want to add metadata to the request Data, use the From helper to fetch the Data from the context, and call whatever method is appropriate.

func otherHandler(w http.ResponseWriter, r *http.Request) {
    d := ctxdata.From(r.Context())
    d.Set("user", r.URL.Query().Get("user"))
    d.Set("corrleation_id", r.Header.Get("X-Correlation-ID"))
    // ...
}

func process(ctx context.Context, key string) {
    begin := time.Now()
    // ...
    ctxdata.From(ctx).Set("process_duration", time.Since(begin).String())
}

At the end of the request, all of the metadata collected throughout the request's lifecycle will be available.

    fmt.Fprintln(w, "OK")
    
    for k, v := range d {
        log.Printf("%s: %s", k, v)
    }
}

Here is an example middleware that writes a so-called wide event in JSON to the dst at the end of each request.

func logMiddleware(next http.Handler, dst io.Writer) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx, d := ctxdata.New(r.Context())
        defer func() { json.NewEncoder(dst).Encode(d.GetAll()) }()
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}
You can’t perform that action at this time.