英文:
Go wrap httprouter to have logger?
问题
我有以下的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 Context中做类似的事情:
func AppEngineHandler(c appengine.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
...
c.Infof("Here's my log")
}
英文:
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")
}
答案1
得分: 0
没有使用过httprouter
包之前,似乎你只需要改变你尝试包装的函数签名。
首先,在方法中改变fn
参数的声明:
func mylogger(fn func(c *myapp.Context, w http.ResponseWriter, r *http.Request, param httprouter.Params))
// ^^^^^ 让它接受你自己的上下文
然后,在包装器中创建并传递上下文到处理程序中:
c := &myapp.Context{ your: arguments, here: true }
fn(c, w, r, param)
// ^^ - 传递上下文
接下来,改变处理程序的签名:
func myhandler(c *myapp.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
// 在这里使用 c
}
请注意,这只是根据你提供的代码片段进行的翻译,可能需要根据你的实际代码进行适当的调整。
英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论