ロギングについて
プログラムを書いていると、内部の処理で値がどのように変化しているかログを出して確かめたい時があると思います。しかし、 全ての情報をログに出力しようとするのはあまりにも煩雑になってしまい、本来得たい情報が読み取りづらくなる恐れがあります。
上記の問題を解決したいため、ログに出力する情報を制御できる仕組みが欲しいです。
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 言語を利用されている方は是非使ってみてください。