Gorilla mux, best way to 'catch' response codes

♀尐吖头ヾ 提交于 2019-12-14 02:08:59

问题


I'm using Gorilla mux for all my routing. Now my app is working fine, I want to find a way to log all my response codes to -for example- statds. I have found this package: https://godoc.org/github.com/gorilla/handlers#LoggingHandler

Which allows me to output all responses into apache format. Although this is nice, it's not 100% what I want. I just want to extract the response statusses and send them to statds. Now what's the best/easiest way to achieve this?

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)
}

Above code gives me this:

So I'm looking for something similar, but instead of outputting the Apache access logs to stdout, I would like to be able to "do something" with the response code. I have also created a simple repo which contains my sample code. You can find it here.


回答1:


I found this useful Blog post from Tim Andersson. First he builds a new struct that satisfies the interface:

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)
}

Then he's using it as a wrapper (or middleware):

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))
    })
}



回答2:


This is how it can be made with violetear, probably can give you a hint about how to deal with the status code within the handler:

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))
}

By using:

cw := w.(*violetear.ResponseWriter)

You can access the violetear.ResponseWriter which exposes the status code by using cw.Status()




回答3:


You can write your own middleware, here's a very base example

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))
}


来源:https://stackoverflow.com/questions/42162211/gorilla-mux-best-way-to-catch-response-codes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!