LoginSignup
3
2

More than 3 years have passed since last update.

Go のロギングライブラリ "go-logging"

Posted at

ロギングについて

プログラムを書いていると、内部の処理で値がどのように変化しているかログを出して確かめたい時があると思います。しかし、 全ての情報をログに出力しようとするのはあまりにも煩雑になってしまい、本来得たい情報が読み取りづらくなる恐れがあります。

上記の問題を解決したいため、ログに出力する情報を制御できる仕組みが欲しいです。

Go 言語には go-logging というロギングライブラリがあり、レベル毎のログ出力の制御や出力情報のカスタマイズなどができます。今回はこれについてご紹介したいと思います。

使い方紹介

サンプルコード

main.go
package main

import (
    "os"

    "github.com/op/go-logging"
)

var log = logging.MustGetLogger("example")

// ログの出力フォーマットを定義
var logFmt = logging.MustStringFormatter(
    `%{color}%{time:15:04:05.000} PID=%{pid} MOD=%{module} PKG=%{shortpkg} %{shortfile} FUNC=%{shortfunc} ▶ %{level:.4s} %{id:03x} %{color:reset} %{message}`,
)

func Backend(format logging.Formatter, level logging.Level) logging.LeveledBackend {
    // ロギングの初期設定
    // ログの出力先は os.Stderr(標準エラー)に設定する。
    backend := logging.NewLogBackend(os.Stderr, "", 0)

    // ログのフォーマットを適用する
    backendFormatter := logging.NewBackendFormatter(backend, format)

    // 出力するログの種類(レベル)を設定
    backendLeveled := logging.AddModuleLevel(backendFormatter)
    backendLeveled.SetLevel(level, "")

    return backendLeveled
}

func main() {
    backend := Backend(logFmt, logging.DEBUG)
    logging.SetBackend(backend)

    log.Debug("debug")
    log.Info("info")
    log.Notice("notice")
    log.Warning("warning")
    log.Error("err")
    log.Critical("crit")
}

実行結果

$ go run main.go
15:25:21.133 PID=15179 MOD=example PKG=main main.go:33 FUNC=main ▶ DEBU 001  debug
15:25:21.133 PID=15179 MOD=example PKG=main main.go:34 FUNC=main ▶ INFO 002  info
15:25:21.133 PID=15179 MOD=example PKG=main main.go:35 FUNC=main ▶ NOTI 003  notice
15:25:21.133 PID=15179 MOD=example PKG=main main.go:36 FUNC=main ▶ WARN 004  warning
15:25:21.133 PID=15179 MOD=example PKG=main main.go:37 FUNC=main ▶ ERRO 005  err
15:25:21.133 PID=15179 MOD=example PKG=main main.go:38 FUNC=main ▶ CRIT 006  crit

フォーマットについて

logging.Formatter という interface によって定義します。
サンプルコードで利用したもの以外にも、様々な情報をログに出力することができます。

%{id}        一意となるログのID
%{pid}       プロセスID
%{time}      ログ出力のタイムスタンプ
%{level}     ログの種類(レベル)
%{module}    モジュール名(MustGetLogger で指定した文字列)
%{program}   os.Args[0] で取得できる文字列
%{message}   ログのメッセージ
%{longfile}  ログが出力されたファイル名と行数を返す (/a/b/c/d.go:23)
%{shortfile} ログが出力されたファイル名と行数を返す (d.go:23)
%{longpkg}   パッケージ名を出力 (github.com/go-logging)
%{shortpkg}  パッケージ名を出力 (go-logging)
%{longfunc}  関数名を出力 (littleEndian.PutUint32)
%{shortfunc} 関数名を出力 (PutUint32)
%{color}     ログの種類(レベル)毎に色を付与できる

ログレベルの制御について

SetLevel によって出力するログのレベルを制御できます。
サンプルコードでは logging.DEBUG を渡していましたが、 logging.ERROR を渡すと ERROR 以上のログレベルのみを出力するようになります。

main.go
(省略)
func main() {
    backend := Backend(logFmt, logging.ERROR)
    logging.SetBackend(backend)

    log.Debug("debug") //出力されない
    log.Info("info") //出力されない
    log.Notice("notice") //出力されない
    log.Warning("warning") //出力されない

    log.Error("err")
    log.Critical("crit")
}

実行結果

$ go run main.go
15:48:02.674 PID=15555 MOD=example PKG=main main.go:39 FUNC=main ▶ ERRO 001  err
15:48:02.674 PID=15555 MOD=example PKG=main main.go:40 FUNC=main ▶ CRIT 002  crit

まとめ

go-logging は非常に使いやすいロギングライブラリとなっています。趣味や業務などで Go 言語を利用されている方は是非使ってみてください。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2