Closed4

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

yuji⛩️yuji⛩️

最小構成

https://github.com/samber/slog-chi?tab=readme-ov-file#minimal

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=""
yuji⛩️yuji⛩️

デフォルトロガーを利用

ローカル以外だけ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)
yuji⛩️yuji⛩️

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にクローズされました