Go Academy · レッスン

ロギングとリクエストIDのミドルウェア

構造化ロギングとトレースIDの注入

レッスン 2/413 ステップ

「ロギングとリクエストIDのミドルウェア」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。

構造化ロギングを使う理由

プレーンテキストのログは、大規模な環境では解析が困難です。構造化ロギング(JSONまたはkey=value)を使用すると、ログアグリゲーター(Datadog、Loki、ELK)でフィールドごとにエントリをフィルタリングし、関連付けられます。

リクエストIDの生成

ミドルウェアでリクエストごとに一意のID(UUIDまたはULID)を生成し、レスポンスヘッダーとコンテキストに追加します。

func RequestID(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        id := r.Header.Get("X-Request-ID")
        if id == "" { id = uuid.New().String() }
        w.Header().Set("X-Request-ID", id)
        ctx := context.WithValue(r.Context(), reqIDKey{}, id)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

slogを使用したロギングミドルウェア

Go 1.21では、構造化ロギングのためにlog/slogが追加されました。ミドルウェア内で使用します。

func StructuredLogger(logger *slog.Logger) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            start := time.Now()
            cw := &captureWriter{ResponseWriter: w}
            next.ServeHTTP(cw, r)
            logger.Info("request",
                "method", r.Method,
                "path", r.URL.Path,
                "status", cw.status,
                "latency_ms", time.Since(start).Milliseconds(),
                "request_id", r.Context().Value(reqIDKey{}),
            )
        })
    }
}

captureWriter

ResponseWriterをラップして、ハンドラーが書き込んだステータスコードを取得します。

type captureWriter struct {
    http.ResponseWriter
    status int
}
func (cw *captureWriter) WriteHeader(code int) {
    cw.status = code
    cw.ResponseWriter.WriteHeader(code)
}
func (cw *captureWriter) Status() int {
    if cw.status == 0 { return http.StatusOK }
    return cw.status
}

すべてのログ行にリクエストIDを追加する

あらかじめIDを設定したリクエストごとの子ロガーを作成し、それをコンテキストに保存します。

reqLogger := logger.With("request_id", id)
ctx := context.WithValue(r.Context(), loggerKey{}, reqLogger)

コンテキストからロガーを取得する

任意のハンドラーやサービスからリクエスト単位のロガーを取得するヘルパーです。

func LoggerFromContext(ctx context.Context) *slog.Logger {
    l, ok := ctx.Value(loggerKey{}).(*slog.Logger)
    if !ok { return slog.Default() }
    return l
}

ログレベル

適切なレベルを使用します。Debugは開発時の詳細なログ、Infoはリクエストの概要、Warnは復旧可能な異常、Errorは対処が必要な失敗に使用します。機密性の高いフィールド(トークンやパスワード)は記録しないでください。

レイテンシバケット

すべてのログ行にリクエストのレイテンシを含めます。メトリクスシステム(Prometheus)でヒストグラムバケットに集計し、P50/P95/P99パーセンタイルを追跡します。

マイクロサービスにおける相関 ID

分散トレーシングシステム全体を導入しなくても分散トレーシングを可能にするため、受信リクエストの X-Request-ID ヘッダーを、すべての送信 HTTP および gRPC 呼び出しに転送します。

ログサンプリング

トラフィックの多いサービスでは、デバッグログや情報ログをサンプリングします(例:debug レベルで 100 リクエストに 1 件だけ記録します)。これにより、エラーログを完全に保持しながらストレージコストを削減できます。

zap と slog の比較

zap(Uber)はスループットの高いサービスでは slog より高速ですが、セットアップがより複雑です。slog は標準ライブラリで移植性があり、ほとんどのサービスには十分です。ベンチマークでボトルネックが確認されない限り、slog を優先してください。

確認問題

ロギングミドルウェアで captureWriter が必要なのはなぜですか?

まとめ: ロギングとリクエスト ID

重要なポイント:

  • ミドルウェアで X-Request-ID を生成または転送し、context に保存する
  • キーと値のフィールドを持つ構造化ログには slog を使用する
  • captureWriter でステータスコードを捕捉し、ハンドラー処理後のログ記録に利用する
  • 相関 ID をすべての下流呼び出しに転送する
無料で開始

AI チューターと学ぶ Go — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
51
レッスン
203

よくある質問

「ロギングとリクエストIDのミドルウェア」レッスンは無料ですか?

はい。「ロギングとリクエストIDのミドルウェア」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。

「ロギングとリクエストIDのミドルウェア」で何を学びますか?

構造化ロギングとトレースIDの注入 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Go Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「ロギングとリクエストIDのミドルウェア」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このGo Academyレッスンでコードを書いて実行できますか?

はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. HTTPミドルウェアチェーンの基本
  2. ロギングとリクエストIDのミドルウェア
  3. 認証とレート制限のミドルウェア
  4. CORSとパニックリカバリーのミドルウェア
← Go Academyに戻る