go-chiは、あまり素のnet/httpからかけ離れたラッピングを行っては居ないので、goでのweb APIの取扱を考えたりするのに便利なのですが、本番運用のことを考えるとJSON logが欲しくなったりしますね。
go-chiのloggerミドルウェアの出力は綺麗なのですが、これをJSON logにしたい。
httplog
middleware一覧の部分で紹介sれているhttplogが便利です。
package main import ( "log" "net/http" "os" "github.com/go-chi/chi" "github.com/go-chi/httplog" "github.com/go-chi/render" ) func main() { // これと l := httplog.NewLogger("app", httplog.Options{ JSON: true, }) r := chi.NewRouter() // r.Use(middlware.Logger) // これは消す r.Use(httplog.RequestLogger(l)) // これ r.Get("/api", func(w http.ResponseWriter, r *http.Request) { data := map[string]string{ "message": "hello", } render.JSON(w, r, data) }) addr := os.Getenv("Addr") if addr == "" { addr = ":4444" } log.Printf("listen: %s", addr) if err := http.ListenAndServe(addr, r); err != nil { log.Fatalf("!! %+v", err) } }
実行例 (formatted)
2020/09/22 21:48:09 listen: :44444
{
"httpRequest": {
"header": {
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"connection": "keep-alive",
"user-agent": "HTTPie/1.0.3"
},
"proto": "HTTP/1.1",
"remoteIP": "127.0.0.1:57785",
"requestID": "xxx",
"requestMethod": "GET",
"requestPath": "/api",
"requestURL": "http://localhost:44444/api",
"scheme": "http"
},
"level": "info",
"message": "Request: GET /api",
"service": "app",
"timestamp": "2020-09-22T21:48:13.069761+09:00"
}
{
"httpRequest": {
"proto": "HTTP/1.1",
"remoteIP": "127.0.0.1:57785",
"requestID": "xxx",
"requestMethod": "GET",
"requestPath": "/api",
"requestURL": "http://localhost:44444/api"
},
"httpResponse": {
"bytes": 20,
"elapsed": 0.062464,
"header": {
"content-type": "application/json; charset=utf-8"
},
"status": 200
},
"level": "info",
"message": "Response: 200 OK",
"service": "app",
"timestamp": "2020-09-22T21:48:13.069966+09:00"
}
はい。
ちなみに裏側ではzerologが使われているようです1。
go list -json github.com/go-chi/httplog | jqfpy '[path for path in get()["Deps"] if "." in path and not path.startswith("vendor/")]' --squash -r
github.com/go-chi/chi
github.com/go-chi/chi/middleware
github.com/rs/zerolog
github.com/rs/zerolog/internal/json
github.com/rs/zerolog/log
-
もっと良い取得方法がある気がする。↩