大猩猩多路人,最好的方式赶上'响应代码

时间:2017-02-10 14:48:57

标签: http go gorilla mux

我使用Gorilla mux进行所有路由。现在我的应用程序工作正常,我想找到一种方法来记录我的所有响应代码 - 例如 - statds。我找到了这个包:https://godoc.org/github.com/gorilla/handlers#LoggingHandler

允许我将所有响应输出为apache格式。虽然这很好,但它并不是我想要的100%。我只想extract响应状态并将它们发送给statds。现在,实现这一目标的最佳/最简单方法是什么?

package main

import (
    "log"
    "net/http"
    "os"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
    "github.com/rogierlommers/mux-status-handler/articles"
    "github.com/rogierlommers/mux-status-handler/users"
)

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/products", articles.Handler)
    r.HandleFunc("/users", users.Handler)

    loggedRouter := handlers.LoggingHandler(os.Stdout, r)
    log.Println("listening on 8080")
    http.ListenAndServe(":8080", loggedRouter)
}

上面的代码给了我这个:

apache logformat output

所以我正在寻找类似的东西,但我不想将Apache访问日志输出到stdout,我希望能够做一些事情"用响应代码。我还创建了一个包含我的示例代码的简单仓库。你可以找到它here

3 个答案:

答案 0 :(得分:1)

我从Tim Andersson找到了this useful Blog post。 首先,他构建了一个满足接口的新结构:

type loggingResponseWriter struct {
    http.ResponseWriter
    statusCode int
}

func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter {
    return &loggingResponseWriter{w, http.StatusOK}
}

func (lrw *loggingResponseWriter) WriteHeader(code int) {
    lrw.statusCode = code
    lrw.ResponseWriter.WriteHeader(code)
}

然后他将它用作包装器(或中间件):

func wrapHandlerWithLogging(wrappedHandler http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
        log.Printf("--> %s %s", req.Method, req.URL.Path)

        lrw := NewLoggingResponseWriter(w)
        wrappedHandler.ServeHTTP(lrw, req)

        statusCode := lrw.statusCode
        log.Printf("<-- %d %s", statusCode, http.StatusText(statusCode))
    })
}

答案 1 :(得分:0)

这是如何用violetear创建的,可能会给你一个关于如何处理处理程序中状态代码的提示:

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/nbari/violetear"
)

func handleGET(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("I handle GET requests\n"))
    // do anything here with the Status code
    cw := w.(*violetear.ResponseWriter)
    fmt.Printf("The status code is: %d\n", cw.Status())
}

func main() {
    router := violetear.New()
    router.HandleFunc("/", handleGET, "GET")
    log.Fatal(http.ListenAndServe(":8080", router))
}

使用:

cw := w.(*violetear.ResponseWriter)

您可以使用cw.Status()

访问公开状态代码的violetear.ResponseWriter

答案 2 :(得分:0)

您可以编写自己的中间件,这是一个非常基本的示例

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/mux"
    "github.com/rogierlommers/mux-status-handler/articles"
    "github.com/rogierlommers/mux-status-handler/users"
)

// middleWare ...
func middleWare(handler http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // right not all this does is log like
        // "github.com/gorilla/handlers"
        log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL)
        // However since this is middleware you can have it do other things
        // Examples, auth users, write to file, redirects, handle panics, ect
        // add code to log to statds, remove log.Printf if you want


        handler.ServeHTTP(w, r)
    })
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/products", articles.Handler)
    r.HandleFunc("/users", users.Handler)

    log.Println("listening on 8080")
    http.ListenAndServe(":8080", middleWare(r))
}