go言語におけるロギングについて
僕は Java 方面に慣れていますのでslf4j(Logback)やlog4j2の様なロギングライブラリがあると扱い易いなぁ…と思う次第です。
まとめ
例によって結論から書くと XML で設定する事に耐えられる ならseelogがオススメ。
CLI で指定出来る程度の設定が出来れば良いなら、公式リリースなglogがオススメ。
標準のlogパッケージについて
まず、僕の開発環境は Windows7 ですので、log/syslog を直接使うようなコードは避けたいのです。
加えて、コードをあまり変更せずに出力先や出力内 容を変更したいのですけども、その為の標準的な方法は機能としてライブラリ内に組込まれていません。
テスティングフレームワークの時も同様に感じましたけども、go 言語のコアライブラリは本当に一番下の足回りがあるのみです。
例えば、設定可能な項目はこれだけです。抜粋すると、
- 時間や日付をどういう単位で出力するか?(日付、時間、マイクロ秒)
- ログを出力した.go ファイルのパスをどう出力するか?(出さない、絶対パス、ファイル名のみ)
Loggerという型は定義されているので、設定可能なロギングフレームワークを実現する足回りはきちんと揃っています。
Logger 毎に抱え込んだ Mutex を使ってログの出力処理を同期している部分を見ると、パフォーマンス上の不安が 少しだけ ありますが、それでも複数の goroutine から安全に呼び出せるので面倒は少ないでしょう。
サンプルコード
package main
import (
"log"
"os"
)
func main() {
useGlobalLogger()
useLogger()
}
func useGlobalLogger() {
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetPrefix("gyappa gyappa ")
log.Println("Hello logging")
}
func useLogger() {
logger := log.New(os.Stderr, "**** ", log.LstdFlags|log.Llongfile)
logger.Fatalf("Hey!! %s", "logging")
}
golang/glog
インストール
go get github.com/golang/glog
解説
Google で開発してるC++の glogを golang にポートしたライブラリで、あまりドキュメントがありません。またファイルと標準出力にしかログを出力出来ません。
コード量的には極めてコンパクトなのでコード読んで使うライブラリです。
このライブラリを使う上で確実に抑えておくべき事柄はflag.Parse()
の呼び出しを忘れない様にする事です。
glog.go#init を見れば分かる様にコマンドラインオプションを追加しているもののオプションのパーズを終了していません。
これは、呼び出し元のコードが更にオプションを追加出来る様にやっているのですけども、一見すると処理が不完全である様に感じますね。
確実に理解しておかなければならない事柄はもう一つあります。FATAL レベルのログを出すとプロセスが exit(255)するという事です。
これは、C++版でも同様の実装になっているのである種の方面では常識なのかもしれませんが、僕はびっくりしました。
サンプルコード
- main.go
package main
import (
"flag"
"github.com/golang/glog"
)
func main() {
flag.Parse()
glog.Info("IINNFF")
glog.Warning("WWWWaaarn")
glog.Error("ERRR")
glog.V(3).Infoln("<<<", 3333, ">>>")
XXXXX()
ZZZZZ()
}
- a_x.go
package main
import "github.com/golang/glog"
func XXXXX() {
glog.Error("ERR : XXXXX")
glog.V(2).Info("V2 *** XXXXX ***")
glog.V(3).Info("V3 --- XXXXX ---")
}
- a_z.go
package main
import "github.com/golang/glog"
func ZZZZZ() {
glog.Error("ERR : ZZZZZ")
glog.V(2).Info("V2 *** ZZZZZ ***")
glog.V(3).Info("V3 --- ZZZZZ ---")
}
コマンドラインオプションについて
分かり辛いので、僕の分かった事だけをメモしておきます。
ログの出力処理はglog.go#outputを読めば大体分かります。