Closed4
[Go] samber/slog-chi を使ってchiのmiddlewareにslogでリクエストログ出力

go get github.com/samber/slog-chi

最小構成
import (
"net/http"
"os"
"time"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
slogchi "github.com/samber/slog-chi"
"log/slog"
)
// Create a slog logger, which:
// - Logs to stdout.
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
// Chi instance
router := chi.NewRouter()
// Middleware
router.Use(slogchi.New(logger))
router.Use(middleware.Recoverer)
// Routes
router.GET("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
router.GET("/error", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(400), 400)
})
// Start server
err := http.ListenAndServe(":4242", router)
// output:
// time=2023-10-15T20:32:58.926+02:00 level=INFO msg="200: OK" env=production request.time=2023-10-15T20:32:58.626+02:00 request.method=GET request.path=/ request.route="" request.ip=127.0.0.1:63932 request.length=0 response.time=2023-10-15T20:32:58.926+02:00 response.latency=100ms response.status=200 response.length=7 id=""

デフォルトロガーを利用
ローカル以外だけJSON出力
func setupLogger() {
env := os.Getenv("ENV")
if env == "local" {
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelDebug,
})))
return
}
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stderr, nil)))
}
router := chi.NewMux()
router.Use(slogchi.New(slog.Default()))
router.Use(middleware.Recoverer)

slog-chi を使わず自分で記述するならこんな感じ
// slogMiddleware は、リクエストをログに記録するためのカスタムミドルウェアです。
func slogMiddleware(logger *slog.Logger) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// リクエストの情報をログに記録
logger.Info("Request received",
slog.String("method", r.Method),
slog.String("url", r.URL.String()),
slog.String("remote_addr", r.RemoteAddr),
)
next.ServeHTTP(w, r)
})
}
}
r.Use(slogMiddleware(slog.Default()))
このスクラップは2025/01/13にクローズされました