diff --git a/commonctx/contextkey.go b/commonctx/contextkey.go new file mode 100644 index 0000000..05078b7 --- /dev/null +++ b/commonctx/contextkey.go @@ -0,0 +1,10 @@ +package commonctx + +// contextkey is a string type that will be used to define standard key used for values in context. +type contextkey string + +//nolint:exported // keeping the enum simple and readable. +const ( + ContextKey_MainLogger contextkey = "mainLogger" + ContextKey_RequestID contextkey = "requestID" +) diff --git a/commonctx/logger.go b/commonctx/logger.go index e58e8ee..e1c4313 100644 --- a/commonctx/logger.go +++ b/commonctx/logger.go @@ -6,22 +6,40 @@ import ( "github.com/sirupsen/logrus" ) -const LoggerKey = "mainLogger" - +// AddMainLogger will add the provided logrus entry as the main logger in context. func AddMainLogger(ctx context.Context, logger *logrus.Entry) context.Context { - return context.WithValue(ctx, LoggerKey, logger) + return context.WithValue(ctx, ContextKey_MainLogger, logger) } +// GetLogger retrieve logger from the context. func GetLogger(ctx context.Context) *logrus.Entry { - if log := ctx.Value(LoggerKey); log != nil { + if log := ctx.Value(ContextKey_MainLogger); log != nil { return log.(*logrus.Entry) } return nil } +// GetContextAndLoggerWithField will add a key and value field to the logger, update the context, and return the new logger. +func GetContextAndLoggerWithField(ctx context.Context, key string, value interface{}) (context.Context, *logrus.Entry) { + if log := ctx.Value(ContextKey_MainLogger); log != nil { + log, ok := log.(*logrus.Entry) + if !ok { + panic("invalid logger in context") + } + log = log.WithField(key, value) + ctx = AddMainLogger(ctx, log) + return ctx, log + } + return ctx, nil +} + +// GetContextAndLoggerWithFields will add provided fields to the logger, update the context, and return the new logger. func GetContextAndLoggerWithFields(ctx context.Context, fields logrus.Fields) (context.Context, *logrus.Entry) { - if log := ctx.Value(LoggerKey); log != nil { - log := log.(*logrus.Entry) + if log := ctx.Value(ContextKey_MainLogger); log != nil { + log, ok := log.(*logrus.Entry) + if !ok { + panic("invalid logger in context") + } log = log.WithFields(fields) ctx = AddMainLogger(ctx, log) return ctx, log diff --git a/commonctx/request_id.go b/commonctx/request_id.go new file mode 100644 index 0000000..fbb1213 --- /dev/null +++ b/commonctx/request_id.go @@ -0,0 +1,18 @@ +package commonctx + +import ( + "context" +) + +// AddRequestID will add the provided requestID in the context. +func AddRequestID(ctx context.Context, requestID string) context.Context { + return context.WithValue(ctx, ContextKey_RequestID, requestID) +} + +// GetRequestID retrieve a requestID from the context. +func GetRequestID(ctx context.Context) *string { + if requestID := ctx.Value(ContextKey_RequestID); requestID != nil { + return requestID.(*string) + } + return nil +} diff --git a/go.mod b/go.mod index 69ed367..6867b76 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/gemnasium/logrus-graylog-hook/v3 v3.1.0 + github.com/google/uuid v1.3.0 github.com/juju/errors v1.0.0 github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible github.com/sirupsen/logrus v1.9.0 diff --git a/go.sum b/go.sum index 019753b..4887311 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM= diff --git a/log/utils.go b/log/utils.go index 1acf6ed..462d280 100644 --- a/log/utils.go +++ b/log/utils.go @@ -7,7 +7,7 @@ import ( "github.com/sirupsen/logrus" ) -// list of common environment variables +// list of common environment variables. var commonEnvs = []string{"APP_NAME", "APP_VERSION"} // AddCommonFieldsFromEnv will analyze "common" environment variable and will add those diff --git a/middleware/recovery.go b/middleware/recovery.go index 82a71fc..64f4872 100644 --- a/middleware/recovery.go +++ b/middleware/recovery.go @@ -54,6 +54,7 @@ func NewRecoveryMiddleware(h http.Handler, recoveryFunc recoveryFuncSignature) h w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusInternalServerError) + //nolint:errcheck,gosec // we already are in a bad case scenario... w.Write([]byte( fmt.Sprintf("{\"code\":%d,\"message\":\"An error happened during the execution of your request.\"}", http.StatusInternalServerError), )) diff --git a/middleware/request_id.go b/middleware/request_id.go index c1c1fe2..290d57c 100644 --- a/middleware/request_id.go +++ b/middleware/request_id.go @@ -3,6 +3,7 @@ package middleware import ( "net/http" + "git.dev.m-and-m.ovh/mderasse/gocommon/commonctx" "github.com/google/uuid" ) @@ -19,7 +20,9 @@ func (rm *requestIDMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) requestID = uuid.New().String() } - // XXX: Add request_id to the context, push the context to r & edit logger middleware to add the request_id as fields + // add requestID to context and update request + ctx := commonctx.AddRequestID(r.Context(), requestID) + r = r.WithContext(ctx) // add the request ID to the response query w.Header().Set(requestIDHeaderKey, requestID)