1. Home
  2. Golang
  3. GuideToBecomingGoDeveloper
  4. Logging
  5. Zerolog - Golang learning step 6-3

Zerolog - Golang learning step 6-3

  • 公開日
  • カテゴリ:Logging
  • タグ:Golang,roadmap.sh,学習メモ
Zerolog - Golang learning step 6-3

roadmap.sh > Go > Logging > Zerolog の学習を進めていきます。

※ 学習メモとしての記録ですが、後にこのセクションを学ぶ道しるべとなるよう、ですます調で記載しています。

contents

  1. 開発環境
  2. 参考 URL
  3. Zerolog パッケージ
  4. Zerolog のインストール
  5. 基本的な使い方
  6. JSON 形式のログ
  7. ログレベル
    1. ログレベルの設定
  8. コンテキストの活用
  9. エラーのログ記録
  10. ファイルにログを保存
  11. パフォーマンスの考慮点

開発環境

  • チップ: Apple M2 Pro
  • OS: macOS Sonoma
  • go version: go1.23.2 darwin/arm64

参考 URL

Zerolog パッケージ

Zerolog は、Go の高性能かつ使いやすいログライブラリです。他の一般的なログライブラリ(例: logrus や zap)と比較して依存関係が少なく軽量、低いメモリ使用量と高速なログ処理が特徴です。また、JSON 形式の構造化ログをデフォルトでサポートしており、ログの管理や分析に適しています。

Zerolog のインストール

Zerolog は go get コマンドを使ってインストールします。

go get -u github.com/rs/zerolog

基本的な使い方

以下は、Zerolog を使った簡単なログの例です。

package main

import (
  "github.com/rs/zerolog"
  "github.com/rs/zerolog/log"
  "os"
)

func main() {
  // 標準出力にログを出力
  log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})

  // 情報ログ
  log.Info().Msg("アプリケーションが起動しました")

  // 構造化ログ
  log.Info().
    Str("user", "test_user").
    Int("attempt", 3).
    Msg("ログイン試行")

  // エラーログ
  log.Error().
    Err(nil).
    Str("reason", "無効なパスワード").
    Msg("ログイン失敗")
}
  • log.Info().Msg() のようにログレベルを指定してメッセージを出力できます。
  • StrInt メソッドを使って構造化データを追加できます。

このコードを実行すると、以下のようなログが出力されます。

10:26PM INF アプリケーションが起動しました
10:26PM INF ログイン試行 attempt=3 user=test_user
10:26PM ERR ログイン失敗 reason="無効なパスワード"

JSON 形式のログ

Zerolog のデフォルト出力は JSON 形式です。以下のコードでは JSON 形式のログを出力します。

package main

import (
  "github.com/rs/zerolog"
  "github.com/rs/zerolog/log"
)

func main() {
  // JSON ログの例
  log.Info().
    Str("event", "user_signup").
    Str("user", "test_user").
    Msg("ユーザー登録が完了しました")
}

このコードを実行すると、以下のような JSON 形式のログが出力されます。

{"level":"info","event":"user_signup","user":"test_user","time":"2024-12-11T22:28:36+09:00","message":"ユーザー登録が完了しました"}

デフォルトでタイムスタンプ(time フィールド)が含まれますが、zerolog.TimeFieldFormat を使ってカスタマイズすることも可能です。

ログレベル

Zerolog は以下のログレベルをサポートしています。

Trace, Debug, Info, Warn, Error, Fatal, Panic

log.Debug().Msg("デバッグ情報")
log.Info().Msg("一般的な情報")
log.Warn().Msg("警告")
log.Error().Msg("エラー")

ログレベルの設定

Zerolog では、ログレベルを動的に変更することができます。以下のように zerolog.SetGlobalLevel を使ってログレベルを指定できます。

package main

import (
  "github.com/rs/zerolog"
  "github.com/rs/zerolog/log"
)

func main() {
  // デフォルトは Info レベル
  zerolog.SetGlobalLevel(zerolog.WarnLevel)

  // このログは出力されない(Info レベル)
  log.Info().Msg("このログは表示されません")

  // このログは出力される(Warn レベル以上)
  log.Warn().Msg("警告ログです")
  log.Error().Msg("エラーログです")
}

出力:

{"level":"warn","time":"2024-12-11T22:31:23+09:00","message":"警告ログです"}
{"level":"error","time":"2024-12-11T22:31:23+09:00","message":"エラーログです"}

なお、設定したログレベル以下のログは出力されません。例えば、zerolog.WarnLevel に設定すると、InfoDebug レベルのログは無視されます。

コンテキストの活用

ログにコンテキスト情報を追加できます。

logger := log.With().
    Str("service", "auth-service").
    Str("version", "1.0.0").
    Logger()

logger.Info().Msg("サービスを起動しました")

出力:

{"level":"info","service":"auth-service","version":"1.0.0","time":"2024-12-11T22:34:56+09:00","message":"サービスを起動しました"}

エラーのログ記録

エラー情報を構造化して記録できます

func someFunction() error {
  return fmt.Errorf("エラーになりました")
}
func main() {
  err := someFunction()
  if err != nil {
    log.Error().
      Err(err).
      Str("function", "someFunction").
      Msg("処理に失敗しました")
  }
}

出力:

{"level":"error","error":"エラーになりました","function":"someFunction","time":"2024-12-11T22:37:40+09:00","message":"処理に失敗しました"}

ファイルにログを保存

ログをファイルに保存するには、log.Output() を使います。

package main

import (
  "os"
  "github.com/rs/zerolog"
  "github.com/rs/zerolog/log"
)

func main() {
  // ファイルを開く
  file, err := os.Create("app.log")
  if err != nil {
    log.Fatal().Err(err).Msg("ログファイルを作成できませんでした")
  }
  defer file.Close()

  // ファイルにログを出力
  log.Logger = log.Output(file)

  log.Info().Msg("ファイルにログを出力しました")
}

出力(app.log):

{"level":"info","time":"2024-12-11T22:39:38+09:00","message":"ファイルにログを出力しました"}

パフォーマンスの考慮点

Zerolog は高パフォーマンスを重視して設計されていますが、以下の点に注意が必要です:

  1. 不要なログレベルは無効化する
  2. フィールド名は短く意味のある名前にする
  3. 大量のログ出力時はサンプリングを検討する

例: サンプリングを有効にするには以下のように設定します。

log.Logger = log.Sample(&zerolog.BasicSampler{N: 10}) // 10回に1回のログ出力    

まとめ

  • Zerolog は軽量で高性能な Go のログライブラリ。依存関係が少なく、ゼロアロケーションを実現
  • JSON 形式の構造化ログをデフォルトでサポートし、可読性と解析性が高い
  • 7 段階のログレベル(Trace, Debug, Info, Warn, Error, Fatal, Panic)のサポート
  • コンテキスト情報を活用した詳細な構造化ログの作成が容易
  • ファイル出力やコンソール出力など、柔軟な出力先の設定が可能
  • サンプリング機能による大量ログ出力時のパフォーマンス最適化


[Prev] Step 6-2: Zap

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級