I want to customize logging format in gorilla handler implementation in LoggingHandler. Basically It gives Common Log format as a default.I want to customize based on the request headers. Assume I pass the tenantId value as a one request header.Then I want added it into the os.StdOut.
r := mux.NewRouter()
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("This is a catch-all route"))
})
loggedRouter := handlers.LoggingHandler(os.Stdout, r)
127.0.0.1 - sandun [10/Oct/2018:13:55:36 -0700] "GET /api/request HTTP/1.0" 200 2326
Then Request Header
teanantId : 50
expected output
127.0.0.1 - sandun [10/Oct/2018:13:55:36 -0700] "GET /api/request HTTP/1.0" 200 2326 50
I want to add tenantid at the last on the log output.
How I do this without changing gorilla handlers liabry.
As more details: I can do it by changing inside code of gorilla handlers library.
// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
// ts is the timestamp with which the entry should be logged.
// status and size are used to provide the response HTTP status and size.
func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte {
tenantId, err := strconv.Atoi(req.Header.Get("tenantid"))
if err != nil {
tenantId = 0
}
username := "-"
if url.User != nil {
if name := url.User.Username(); name != "" {
username = name
}
}
host, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
host = req.RemoteAddr
}
uri := req.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 req.ProtoMajor == 2 && req.Method == "CONNECT" {
uri = req.Host
}
if uri == "" {
uri = url.RequestURI()
}
buf := make([]byte, 0, 3*(len(host)+len(username)+len(req.Method)+len(uri)+len(req.Proto)+50)/2)
buf = append(buf, host...)
buf = append(buf, " - "...)
buf = append(buf, username...)
buf = append(buf, " ["...)
buf = append(buf, ts.Format("02/Jan/2006:15:04:05 -0700")...)
buf = append(buf, `] "`...)
buf = append(buf, req.Method...)
buf = append(buf, " "...)
buf = appendQuoted(buf, uri)
buf = append(buf, " "...)
buf = append(buf, req.Proto...)
buf = append(buf, `" `...)
buf = append(buf, strconv.Itoa(status)...)
buf = append(buf, " "...)
buf = append(buf, strconv.Itoa(size)...)
buf = append(buf, " "...)
buf = append(buf, strconv.Itoa(tenantId)...)
return buf
}
But I think it is not good solution. I am expecting good solution from this community.
appreciate your help.
Gorilla handlers library uses Apache Common Log Format. Changing of the output format makes your log messages absolutely unclear for everyone except you.
The idiomatic way: create you own middleware handler, that writes to output (or any other io.Writer) value of teanantId
header.
The second (wrong in my opinion) way: fork repository, change behavior and use it.