Golang记录http响应(除了请求)

时间:2016-07-18 18:42:10

标签: go gorilla

我正在使用Go和Gorilla Web工具包的mux和处理程序包来构建一个复杂的应用程序,其中一部分需要一个http服务器。 Gorilla的mux和处理程序包工作得非常好,我能够成功启动并运行http服务器,并且记录请求非常简单。

但是,我无法确定如何记录回复。理想情况下,我想要一种类似于Gorilla的LoggingHandler的机制,它可以轻松地“包装”日志记录机制。

是否有一个Golang包可以轻松包装/记录响应?有没有办法以这种方式使用Go或Gorilla的功能,我没有考虑过?

3 个答案:

答案 0 :(得分:4)

编辑抱歉,我没有注意到你提到gorilla-mux,我只用杜松子酒尝试过这个,但是如果它使用中间件,那么它仍然有效。

诀窍是,c.Next()在中间件中阻塞,直到所有后续中间件都返回。这是一个logrus解决方案。把它作为你的第一个中间件:

func Logrus(logger *logrus.Logger) gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now().UTC()
        path := c.Request.URL.Path
        c.Next()
        end := time.Now().UTC()
        latency := end.Sub(start)
        logger.WithFields(logrus.Fields{
            "status":     c.Writer.Status(),
            "method":     c.Request.Method,
            "path":       path,
            "ip":         c.ClientIP(),
            "duration":   latency,
            "user_agent": c.Request.UserAgent(),
        }).Info()
    }
}
GinEngine.Use(Logrus(logrus.StandardLogger()))

答案 1 :(得分:3)

感谢您提出的好建议。我尝试了一些建议,并采用了一个使用极简主义包装的相当简单的解决方案。以下是适用于我的解决方案(随意提供评论,或者更好的是,其他解决方案):

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httptest"
    "net/http/httputil"
    "github.com/gorilla/mux"
)
:

func logHandler(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        x, err := httputil.DumpRequest(r, true)
        if err != nil {
            http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
            return
        }
        log.Println(fmt.Sprintf("%q", x))
        rec := httptest.NewRecorder()
        fn(rec, r)
        log.Println(fmt.Sprintf("%q", rec.Body))            
    }
}

func MessageHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "A message was received")
}

以下代码将使用上述处理程序:

:
router := mux.NewRouter()
router.HandleFunc("/", logHandler(MessageHandler))
:

上述代码的输出将是:

:
2016/07/20 14:44:29 "GET ... HTTP/1.1\r\nHost: localhost:8088\r\nAccept: */*\r\nUser-Agent: curl/7.43.0\r\n\r\n"
2016/07/20 14:44:29 ...[response body]
:

答案 2 :(得分:2)

如果您想要将回复实际发送给客户,那么Eric Broda接受的答案将无济于事。我对那些实际可行的代码进行了修改:

 @ matches the character @ literally (case sensitive)
   .+? matches any character (except for line terminators)
    +? Quantifier — Matches between one and unlimited times, as few 
                    times as possible, expanding as needed (lazy)
 \b assert position at a word boundary (^\w|\w$|\W\w|\w\W)