github.com/suedadam/up@v0.1.12/http/logs/logs.go (about)

     1  // Package logs provides HTTP request and response logging.
     2  package logs
     3  
     4  import (
     5  	"net/http"
     6  	"time"
     7  
     8  	"github.com/apex/log"
     9  
    10  	"github.com/apex/up"
    11  	"github.com/apex/up/internal/logs"
    12  )
    13  
    14  // TODO: optional verbose mode with req/res header etc?
    15  
    16  // log context.
    17  var ctx = logs.Plugin("logs")
    18  
    19  // response wrapper.
    20  type response struct {
    21  	http.ResponseWriter
    22  	written int
    23  	code    int
    24  }
    25  
    26  // Write implementation.
    27  func (r *response) Write(b []byte) (int, error) {
    28  	n, err := r.ResponseWriter.Write(b)
    29  	r.written += n
    30  	return n, err
    31  }
    32  
    33  // WriteHeader implementation.
    34  func (r *response) WriteHeader(code int) {
    35  	r.code = code
    36  	r.ResponseWriter.WriteHeader(code)
    37  }
    38  
    39  // New logs handler.
    40  func New(c *up.Config, next http.Handler) (http.Handler, error) {
    41  	if c.Logs.Disable {
    42  		return next, nil
    43  	}
    44  
    45  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    46  		start := time.Now()
    47  		res := &response{ResponseWriter: w, code: 200}
    48  
    49  		next.ServeHTTP(res, r)
    50  
    51  		c := ctx.WithFields(log.Fields{
    52  			"stage":    r.Header.Get("X-Stage"),
    53  			"id":       r.Header.Get("X-Request-Id"),
    54  			"method":   r.Method,
    55  			"path":     r.URL.Path,
    56  			"query":    r.URL.Query().Encode(),
    57  			"duration": int(time.Since(start) / time.Millisecond),
    58  			"size":     res.written,
    59  			"ip":       r.RemoteAddr,
    60  			"status":   res.code,
    61  		})
    62  
    63  		switch {
    64  		case res.code >= 500:
    65  			c.Error("response")
    66  		case res.code >= 400:
    67  			c.Warn("response")
    68  		default:
    69  			c.Info("response")
    70  		}
    71  	})
    72  
    73  	return h, nil
    74  }