我具有以下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
}

09-11 03:37