I have the following httprouter
handler but I want to customize so that I can inject my own logger functions.
router := httprouter.New()
router.Handle("GET", "/mysite", mylogger(handler1))
And mylogger
is like:
var logger = log.New(os.Stdout, "[Log] ", 0)
func mylogger(fn func(w http.ResponseWriter, r *http.Request, param httprouter.Params)) func(w http.ResponseWriter, r *http.Request, param httprouter.Params) {
return func(w http.ResponseWriter, r *http.Request, param httprouter.Params) {
start := time.Now()
logger.Printf("%s %s", r.Method, r.URL.Path)
fn(w, r, param)
logger.Printf("Done in %v (%s %s)", time.Since(start), r.Method, r.URL.Path)
}
}
And myhandler
is like:
func myhandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
....
}
Is there any way that I can wrap the httprouter
handler that I do not have to pass handler to mylogger
function? I want to do something like in Go AppEngine Context:
func AppEngineHandler(c appengine.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
...
c.Infof("Here's my log")
}
Without having used the httprouter
package before, it would appear all you need to do is change the function signature you're attempting to wrap.
So, firstly, change the declaration of the fn
argument in the method:
func mylogger(fn func(c *myapp.Context, w http.ResponseWriter, r *http.Request, param httprouter.Params))
// ^^^^^ have it accept a context of your own
..then create and pass the context into your handler in the wrapper:
c := &myapp.Context{ your: arguments, here: true }
fn(c, w, r, param)
// ^^ - pass the context in
Then change the signature of your handler:
func myhandler(c *myapp.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
// use c here
}