...

Source file src/edge-infra.dev/pkg/edge/iam/middleware/request_logger.go

Documentation: edge-infra.dev/pkg/edge/iam/middleware

     1  package middleware
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/http"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/gin-gonic/gin"
    11  	"github.com/go-logr/logr"
    12  
    13  	"edge-infra.dev/pkg/lib/fog"
    14  )
    15  
    16  // TODO: should make use of fog.MiddlewareLogger once it is able to log.WithValues the request properly (see pkg/edge/api/middleware/request.go)
    17  func RequestLogger(log logr.Logger) gin.HandlerFunc {
    18  	return func(c *gin.Context) {
    19  		if !shouldHandle(c) {
    20  			c.Next()
    21  			return
    22  		}
    23  
    24  		// log the request
    25  		opID := fog.OperationID(c.Request.Context())
    26  		reqMsg := fmt.Sprintf("[%s] - [req]: %s %s", opID[:8], c.Request.Method, c.Request.URL.String())
    27  
    28  		reqLog := log.WithValues(fog.OperationFields(opID)...)
    29  		reqLog.Info(reqMsg)
    30  
    31  		t := time.Now()
    32  		c.Next()
    33  
    34  		resLog := log.WithValues(fog.OperationFields(opID)...)
    35  
    36  		// log the response
    37  		status := c.Writer.Status()
    38  		logmsg := fmt.Sprintf("[%s] - [res]: %s %s %d (%s)", opID[:8], c.Request.Method, c.Request.URL.Path, status, http.StatusText(status))
    39  
    40  		fields := map[string]interface{}{
    41  			"requestMethod": c.Request.Method,
    42  			"requestUrl":    c.Request.URL.String(),
    43  			"remoteIp":      c.Request.RemoteAddr,
    44  			"referer":       c.Request.Referer(),
    45  			"latency":       time.Since(t).String(),
    46  			"status":        status,
    47  			"userAgent":     c.Request.UserAgent(),
    48  			"responseSize":  c.Writer.Size(),
    49  		}
    50  
    51  		if status < 500 {
    52  			resLog.Info(logmsg, "httpRequest", fields)
    53  		} else {
    54  			resLog.Error(errors.New(http.StatusText(status)), logmsg, "httpRequest", fields)
    55  		}
    56  	}
    57  }
    58  
    59  // shouldHandle returns false if we don't want to log the current request
    60  func shouldHandle(c *gin.Context) bool {
    61  	if c.FullPath() == "/ready" || c.FullPath() == "/live" {
    62  		return false
    63  	}
    64  
    65  	if c.Request.Method == http.MethodOptions {
    66  		return false
    67  	}
    68  
    69  	if !shouldLogRequest(c.Request.URL.String()) {
    70  		return false
    71  	}
    72  
    73  	return true
    74  }
    75  
    76  func shouldLogRequest(url string) bool {
    77  	blacklist := []string{".js", ".css", ".ico", ".json", ".png"}
    78  
    79  	for _, suffix := range blacklist {
    80  		if strings.HasSuffix(url, suffix) {
    81  			return false
    82  		}
    83  	}
    84  
    85  	urls := []string{"/.well-known/", "/static/", "/metrics"}
    86  	for _, item := range urls {
    87  		if strings.Contains(url, item) {
    88  			return false
    89  		}
    90  	}
    91  
    92  	return true
    93  }
    94  

View as plain text