いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-546 (slogメモ-15)(Go 1.24でslog.DiscardHandlerが追加)

関連記事

Goメモ-477 (slogメモ-01)(基本的な使い方) - いろいろ備忘録日記

Goメモ-478 (slogメモ-02)(構造化ログの出力) - いろいろ備忘録日記

Goメモ-479 (slogメモ-03)(デフォルトロガー) - いろいろ備忘録日記

Goメモ-480 (slogメモ-04)(従来のlogパッケージとの連携) - いろいろ備忘録日記

Goメモ-482 (slogメモ-05)(テキスト形式のログ) - いろいろ備忘録日記

Goメモ-483 (slogメモ-06)(JSON形式のログ) - いろいろ備忘録日記

Goメモ-484 (slogメモ-07)(動的にログレベルを変更) - いろいろ備忘録日記

Goメモ-485 (slogメモ-08)(グループ (1)) - いろいろ備忘録日記

Goメモ-486 (slogメモ-09)(グループ (2)) - いろいろ備忘録日記

Goメモ-487 (slogメモ-10)(機密情報などのマスキング) - いろいろ備忘録日記

Goメモ-488 (slogメモ-11)(カスタムログレベル) - いろいろ備忘録日記

Goメモ-490 (slogメモ-12)(context.Contextとの連携) - いろいろ備忘録日記

Goメモ-491 (slogメモ-13)(io.Writerとの連携) - いろいろ備忘録日記

Goメモ-493 (slogメモ-14)(カスタムログハンドラの作成 (1)) - いろいろ備忘録日記

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。

今更ながら、Go 1.21で導入された log/slog を使ってみたりしています。

少しづつメモしていきます。今回はGo1.24で追加された slog.DiscardHandler について。

io.Discard と同じ名前なので動きは予想できますが、このハンドラは出力を一切行いません。

ツール作ったりしてて、デバッグオプションが有効のときのみ出力するログとかによく使いますね。

サンプル

main.go

package main

import (
    "flag"
    "log/slog"
    "os"
)

func main() {
    discard := flag.Bool("discard", false, "Use slog.DiscardHandler")
    flag.Parse()

    if err := run(*discard); err != nil {
        panic(err)
    }
}

func run(discard bool) error {
    //
    // Go 1.24 にて、slog.DiscardHandler が追加された。
    // io.Discard と同様に、このハンドラは出力を行わない。
    //
    // > DiscardHandler discards all log output. DiscardHandler.Enabled returns false for all Levels.
    // > (DiscardHandler は、すべてのログ出力を破棄します。DiscardHandler.Enabled は、すべての Levels に対して false を返します。)
    //
    // # REFERENCES
    //   - https://pkg.go.dev/log/slog#example-package-DiscardHandler
    //
    var (
        l = slog.New(handler(discard))
    )

    l.Info("helloworld")
    l.Warn("helloworld")
    l.Error("helloworld")

    return nil
}

func handler(discard bool) slog.Handler {
    if discard {
        return slog.DiscardHandler
    }

    return slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ReplaceAttr: rmTime})
}

// From https://cs.opensource.google/go/go/+/refs/tags/go1.24.0:src/log/slog/internal/slogtest/slogtest.go;l=13
func rmTime(groups []string, a slog.Attr) slog.Attr {
    if a.Key == slog.TimeKey && len(groups) == 0 {
        return slog.Attr{}
    }
    return a
}

Taskfile.yml

version: "3"

tasks:
  default:
    cmds:
      - task: run
  run:
    cmds:
      - go run main.go -discard=false
      - go run main.go -discard=true

shell

実行すると以下のように出力されます。

$ task
task: [run] go run main.go -discard=false
level=INFO msg=helloworld
level=WARN msg=helloworld
level=ERROR msg=helloworld
task: [run] go run main.go -discard=true

slog.DiscardHandlerを利用するオプションを指定した場合は出力がされていませんね。

参考情報

Goのおすすめ書籍


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。