mirror of
https://github.com/micromdm/micromdm/
synced 2026-06-19 10:35:45 +08:00
- Added the concept of a "trace id", a unique ID which gets associated with every log/request by default. Will eventually use opentelemetry/opentracing, or perhaps something better... Still very alpha quality + lots of dependencies/API surface to bring in. For the purpose of MicroMDM, a unique identifier per request is fine. - Added HTTP logging middleware.
76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
package log
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
|
|
"github.com/felixge/httpsnoop"
|
|
)
|
|
|
|
// HTTP returns an HTTP logging middleware using the provided base logger.
|
|
func HTTP(l Logger) func(http.Handler) http.Handler { return handler{logger: l}.decorate }
|
|
|
|
type handler struct{ logger Logger }
|
|
|
|
func (h handler) decorate(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newTraceContext(r.Context())
|
|
ctx = NewContext(ctx, h.logger)
|
|
|
|
// https://github.com/felixge/httpsnoop#why-this-package-exists
|
|
// https://github.com/golang/go/issues/18997
|
|
var metrics httpsnoop.Metrics
|
|
|
|
defer func() {
|
|
logRequest(ctx, metrics.Code, r)
|
|
}()
|
|
|
|
metrics = httpsnoop.CaptureMetrics(next, w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
|
|
func logRequest(ctx context.Context, code int, r *http.Request) {
|
|
host, _, err := net.SplitHostPort(r.RemoteAddr)
|
|
if err != nil {
|
|
host = r.RemoteAddr
|
|
}
|
|
|
|
url := *r.URL
|
|
uri := r.RequestURI
|
|
|
|
// Requests using the CONNECT method over HTTP/2.0 must use
|
|
// the authority field (aka r.Host) to identify the target.
|
|
// Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT
|
|
if r.ProtoMajor == 2 && r.Method == "CONNECT" {
|
|
uri = r.Host
|
|
}
|
|
|
|
if uri == "" {
|
|
uri = url.RequestURI()
|
|
}
|
|
|
|
keyvals := []interface{}{
|
|
"method", r.Method,
|
|
"status", code,
|
|
"proto", r.Proto,
|
|
"host", host,
|
|
"user_agent", r.UserAgent(),
|
|
"path", uri,
|
|
}
|
|
|
|
if fwd := r.Header.Get("X-Forwarded-For"); fwd != "" {
|
|
keyvals = append(keyvals, "x_forwarded_for", fwd)
|
|
}
|
|
|
|
if referer := r.Referer(); referer != "" {
|
|
keyvals = append(keyvals, "referer", referer)
|
|
}
|
|
|
|
if code >= 500 {
|
|
Info(FromContext(ctx)).Log(keyvals...)
|
|
} else {
|
|
Debug(FromContext(ctx)).Log(keyvals...)
|
|
}
|
|
}
|