在GO中的Gorilla处理程序中自定义LoggingHandlers实现中的日志格式

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.