package middleware import ( "bytes" "net/http" "time" "edge-infra.dev/pkg/lib/fog" "github.com/gin-gonic/gin" "github.com/go-logr/logr" ) // requestMiddleware is an object that holds a gin response writer for http responses, as well as the logger and request body information type requestMiddleware struct { gin.ResponseWriter logger logr.Logger body *bytes.Buffer } // RequestLogger is middleware that sends contextual information to fog's middleware logger func RequestLogger(l logr.Logger) gin.HandlerFunc { return func(c *gin.Context) { if c.FullPath() == "/health" || c.Request.Method == http.MethodOptions { c.Next() return } entry := &requestMiddleware{ ResponseWriter: c.Writer, body: bytes.NewBufferString(""), } opID := fog.OperationID(c.Request.Context()) entry.logger = l.WithValues(fog.OperationFields(opID)...) entry.logger = l.WithValues("ip", c.ClientIP()) c.Request = c.Request.Clone(fog.IntoContext(c.Request.Context(), l)) t := time.Now() c.Next() //only log request if status is not 200 if c.Writer.Status() != 200 { middlewareContext := &fog.MiddlewareContext{ Request: c.Request, Status: c.Writer.Status(), Size: c.Writer.Size(), Body: entry.body, Time: time.Since(t), } fog.MiddlewareLogger(l, middlewareContext) } } } func SetRequestContext() gin.HandlerFunc { return func(c *gin.Context) { // Add random operation id to context ctx := fog.SetOperationContext(c.Request.Context()) c.Request = c.Request.WithContext(ctx) c.Next() } }