in internal/util/logging.go [117:169]
func captureZapFieldsForRequest(handler http.Handler, w http.ResponseWriter, req *http.Request) (string, []zap.Field) {
resp := httpsnoop.CaptureMetrics(handler, w, req)
domain, port, err := net.SplitHostPort(req.Host)
if err != nil {
domain = req.Host
}
if ip := net.ParseIP(domain); ip != nil && ip.To16() != nil && ip.To4() == nil {
// For ECS, if the host part of an url is an IPv6, it must keep the brackets
// when stored in `url.domain` (but not when stored in ip fields).
domain = "[" + domain + "]"
}
sourceHost, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
sourceHost = req.RemoteAddr
}
fields := []zap.Field{
// Request fields.
zap.String("source.address", sourceHost),
zap.String("http.request.method", req.Method),
zap.String("url.path", req.URL.Path),
zap.String("url.domain", domain),
// Response fields.
zap.Int("http.response.code", resp.Code),
zap.Int64("http.response.body.bytes", resp.Written),
zap.Int64("event.duration", resp.Duration.Nanoseconds()),
}
// Fields that are not always available.
if ip := net.ParseIP(sourceHost); ip != nil {
fields = append(fields, zap.String("source.ip", sourceHost))
} else {
fields = append(fields, zap.String("source.domain", sourceHost))
}
if referer := req.Referer(); referer != "" {
fields = append(fields, zap.String("http.request.referer", referer))
}
if userAgent := req.UserAgent(); userAgent != "" {
fields = append(fields, zap.String("user_agent.original", userAgent))
}
if query := req.URL.RawQuery; query != "" {
fields = append(fields, zap.String("url.query", query))
}
if port != "" {
if intPort, err := strconv.Atoi(port); err == nil && intPort != 0 {
fields = append(fields, zap.Int("url.port", intPort))
}
}
message := req.Method + " " + req.URL.Path + " " + req.Proto
return message, fields
}