去包装httprouter有记录器吗?

时间:2014-11-02 01:20:23

标签: google-app-engine http logging go

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

1 个答案:

答案 0 :(得分:0)

之前没有使用过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
}