Skip to content

Commit

Permalink
fix #1 . add request ID middleware (#3)
Browse files Browse the repository at this point in the history
* fix #1 . add request ID middleware
  • Loading branch information
mbobakov authored and AndersonQ committed Oct 19, 2019
1 parent c96393c commit ae80ac8
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 2 deletions.
1 change: 1 addition & 0 deletions constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ const (
LogKeyURLPath = "_url_path"
LogKeyUserAgent = "_user_agent"
LogKeyResquestDuration = "_request_duration_ms"
LogKeyResquestID = "_request_id"
LogKeyHTTPStatus = "_http_status"
)
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/AndersonQ/go-skeleton
require (
github.com/caarlos0/env v3.5.0+incompatible
github.com/go-chi/chi v4.0.2+incompatible
github.com/google/uuid v1.1.1
github.com/newrelic/go-agent v2.7.0+incompatible
github.com/rs/zerolog v1.14.3
github.com/stretchr/testify v1.3.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs=
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/newrelic/go-agent v2.7.0+incompatible h1:T5tJ9nNY1bXBfLUTCEZRuBLPT0f9+mE1jd4EaNoN5Zs=
github.com/newrelic/go-agent v2.7.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func main() {

func initRouter(cfg config.Config, newrelicApp newrelic.Application, logger zerolog.Logger) *chi.Mux {
router := chi.NewRouter()
// TODO(Anderson): create a tracking ID middleware
router.Use(middlewares.RequestIDHandler)
router.Use(hlog.NewHandler(logger))
router.Use(middleware.StripSlashes)
router.Use(middleware.Compress(flate.BestSpeed))
Expand Down
2 changes: 1 addition & 1 deletion middlewares/middlewares.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ func RequestLogWrapper(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// TODO: Use a clock abstraction instead of time.Now()
startTime := time.Now()

logger := zerolog.Ctx(r.Context()).With().
Str(constants.LogKeyHTTPMethod, r.Method).
Str(constants.LogKeyURLPath, r.URL.Path).
Str(constants.LogKeyUserAgent, r.UserAgent()).
Str(constants.LogKeyRemoteAddr, r.RemoteAddr).
Str(constants.LogKeyResquestID, requestIDFromContext(r.Context())).
Logger()

ww := statusResponseWriter{w: w}
Expand Down
41 changes: 41 additions & 0 deletions middlewares/request_id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package middlewares

import (
"context"
"net/http"

"github.com/google/uuid"
)

type reqIDCtx int

const reqIDContexKey reqIDCtx = reqIDCtx(0)

// requestIDContext creates a context with request id
func requestIDContext(ctx context.Context, rid string) context.Context {
return context.WithValue(ctx, reqIDContexKey, rid)
}

// requestIDFromContext returns the request id from context
func requestIDFromContext(ctx context.Context) string {
rid, ok := ctx.Value(reqIDContexKey).(string)
if !ok {
return ""
}
return rid
}

// RequestIDHandler sets unique request id.
// If header `X-Request-ID` is already present in the request, that is considered the
// request id. Otherwise, generates a new unique ID.
func RequestIDHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rid := r.Header.Get("X-Request-ID")
if rid == "" {
rid = uuid.New().String()
r.Header.Set("X-Request-ID", rid)

This comment has been minimized.

Copy link
@RaVbaker

RaVbaker Oct 27, 2019

@mbobakov @AndersonQ shouldn't here be used the responseWriter w instead of Request ?

This comment has been minimized.

Copy link
@RaVbaker

RaVbaker Oct 27, 2019

plus the header should be set for the passthrough as returned one every time not only if wasn't set in the beginning imho.

This comment has been minimized.

Copy link
@AndersonQ

AndersonQ Oct 27, 2019

Owner

You're right! I missed that.
If you want you can submit the PR. Or I'll fix it later.

}
ctx := requestIDContext(r.Context(), rid)
h.ServeHTTP(w, r.WithContext(ctx))
})
}

0 comments on commit ae80ac8

Please sign in to comment.