Skip to content

0xPolygon/requestid

Repository files navigation

RequestId

Go pkg to propagate a Request-Id header across multiple services.

  • Enables simple tracing capabilities and log grouping.
  • The value can be exposed to end-users in case of an error.
  • The value is a typeid — a Crockford base32-encoded UUIDv7 with a req_ prefix (e.g. req_01kqzn7yhbe37rw9n6aam5nb2j). It is k-sortable and you can extract the embedded timestamp.
  • Unlike OTEL, this package doesn't trace spans or metrics, doesn't require any backend and doesn't pull in large dependencies (gRPC).

Forked from https://github.com/go-chi/traceid.

Example: HTTP middleware

package main

import (
	"github.com/0xPolygon/requestid"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/go-chi/httplog/v2"
)

func main() {
	r := chi.NewRouter()

	r.Use(requestid.Middleware)
	r.Use(httplog.RequestLogger(logger()))
	r.Use(middleware.Recoverer)

	r.Use(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			ctx := r.Context()

			// Log requestId to request logger.
			id := requestid.FromContext(r.Context())
			httplog.LogEntrySetField(ctx, "requestId", slog.StringValue(id)) // "req_01kqzn7yhbe37rw9n6aam5nb2j"

			next.ServeHTTP(w, r.WithContext(ctx))
		})
	})
}

See example/main.go.

Example: Send HTTP request with Request-Id header

import (
	"github.com/0xPolygon/requestid"
)

func main() {
	// Set Request-Id in context, if not already set from a parent ctx.
	ctx := requestid.NewContext(context.Background())

	// Make a request with the Request-Id header.
	req, _ := http.NewRequestWithContext(ctx, "GET", "http://localhost:3333/proxy", nil)
	requestid.SetHeader(ctx, req)

	resp, err := http.DefaultClient.Do(req)
	// ...
}

Example: Set Request-Id header on all outgoing HTTP requests globally

import (
	"github.com/0xPolygon/requestid"
	"github.com/go-chi/transport"
)

func main() {
	http.DefaultTransport = transport.Chain(
		http.DefaultTransport,
		transport.SetHeader("User-Agent", "my-app/v1.0.0"),
		requestid.Transport,
	)

	// This will automatically send the Request-Id header.
	req, _ := http.NewRequest("GET", "http://localhost:3333/proxy", nil)
	_, _ = http.DefaultClient.Do(req)
}

Get time from Request-Id value

$ go run github.com/0xPolygon/requestid/cmd/requestid req_01kqzn7yhbe37rw9n6aam5nb2j
2024-03-05 14:56:57.477 +0100 CET

You can also mint a new Request-Id:

$ go run github.com/0xPolygon/requestid/cmd/requestid
req_01kqzn7yhbe37rw9n6aam5nb2j

License

Copyright (c) 2024 https://github.com/go-chi authors Copyright (c) 2026 PT Services DMCC

Licensed under either:

as your option.

The SPDX license identifier for this project is MIT OR Apache-2.0.

About

requestid propagates Request-Id header across multiple services

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages