我具有以下httprouter
处理程序,但我想自定义以便注入自己的记录器功能。
router := httprouter.New()
router.Handle("GET", "/mysite", mylogger(handler1))
mylogger
就像: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)
}
}
myhandler
就像:func myhandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
....
}
有什么方法可以包装不必将处理程序传递给
httprouter
函数的mylogger
处理程序?我想在Go AppEngine上下文中执行以下操作:func AppEngineHandler(c appengine.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
...
c.Infof("Here's my log")
}
最佳答案
在没有使用过httprouter
包的情况下,您似乎要做的就是更改要包装的函数签名。
因此,首先,在方法中更改fn
参数的声明:
func mylogger(fn func(c *myapp.Context, w http.ResponseWriter, r *http.Request, param httprouter.Params))
// ^^^^^ have it accept a context of your own
..然后创建上下文并将其传递给包装器中的处理程序:
c := &myapp.Context{ your: arguments, here: true }
fn(c, w, r, param)
// ^^ - pass the context in
然后更改处理程序的签名:
func myhandler(c *myapp.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
// use c here
}