英文:
Gorilla mux, best way to 'catch' response codes
问题
我正在使用Gorilla mux进行路由。现在我的应用程序运行良好,我想找到一种方法将所有的响应代码记录到-statds(例如)。我找到了这个包:https://godoc.org/github.com/gorilla/handlers#LoggingHandler
它允许我将所有的响应输出为Apache格式。虽然这很好,但并不完全符合我的要求。我只想"提取"响应状态并将它们发送到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访问日志输出到stdout,而是希望能够"对响应代码做些什么"。我还创建了一个包含示例代码的简单存储库,你可以在这里找到它。
英文:
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
得分: 7
我找到了Tim Andersson的这篇有用的博客文章。首先,他构建了一个满足接口要求的新结构体:
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))
})
}
英文:
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
得分: 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"))
// 在这里可以处理状态码
cw := w.(*violetear.ResponseWriter)
fmt.Printf("状态码是:%d\n", cw.Status())
}
func main() {
router := violetear.New()
router.HandleFunc("/", handleGET, "GET")
log.Fatal(http.ListenAndServe(":8080", router))
}
通过使用cw := w.(*violetear.ResponseWriter)
,你可以访问violetear.ResponseWriter,通过cw.Status()
方法获取状态码。
英文:
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:
<!-- language: go -->
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
得分: -1
你可以编写自己的中间件,这是一个非常基本的示例:
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) {
// 目前,这个中间件只是像 "github.com/gorilla/handlers" 一样记录日志
log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL)
// 但是由于这是中间件,你可以让它做其他事情
// 例如,验证用户、写入文件、重定向、处理恐慌等等
// 如果你想要将日志记录到statds,可以添加相应的代码,如果不需要log.Printf,可以将其删除
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))
}
希望对你有帮助!
英文:
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))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论