Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to log http server errors in golang?

Tags:

go

I'm trying to catch and log http error 400 that happens when url params are not encoded properly.

My server implementation looks like:

router := http.NewServeMux()
router.HandleFunc("/", requestHandler)

s := &http.Server{
    Addr:           ":8080",
    Handler:        router,
    ErrorLog:       myLogger,
}
log.Fatal(s.ListenAndServe())

The request never reaches requestHandler, and having ErrorLog: myLogger makes no difference.

like image 797
serg Avatar asked Aug 22 '14 22:08

serg


1 Answers

You need to create a custom Wrapper around the requestHandler that records the StatusCode and inspects it after the requestCall has been processed.

Notice how we wrap the main router itself. with WrapHandler(router)

package main

import (
    "log"
    "net/http"
)

type LogRecord struct {
    http.ResponseWriter
    status int
}

func (r *LogRecord) Write(p []byte) (int, error) {
    return r.ResponseWriter.Write(p)
}

func (r *LogRecord) WriteHeader(status int) {
    r.status = status
    r.ResponseWriter.WriteHeader(status)
}

func WrapHandler(f http.Handler) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        record := &LogRecord{
            ResponseWriter: w,
        }

        f.ServeHTTP(record, r)

        log.Println("Bad Request ", record.status)

        if record.status == http.StatusBadRequest {
            log.Println("Bad Request ", r)
        }
    }
}

func main() {
    router := http.NewServeMux()

    s := &http.Server{
        Addr:    ":8080",
        Handler: WrapHandler(router),
    }
    log.Fatal(s.ListenAndServe())
}
like image 175
fabrizioM Avatar answered Sep 22 '22 07:09

fabrizioM