go-chi/chiでJSON logを手軽に使う方法
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
-
もっと良い取得方法がある気がする。↩