LoginSignup
34
34

More than 5 years have passed since last update.

golangに(僕が)便利(だと思う様)なlogger作った

Last updated at Posted at 2014-02-09

golangでアプリケーションログ取る時、一般的にはlogパッケージが用いられると思います。
が、あれイロイロ不便なので自分で作りました。

既存の問題

標準のlogや、他の人が公開してくれているloggerにはこんな問題があると思います。

  • レベル別にできない。
  • 関数名やgoroutine番号が出せない
  • なんか作りが複雑(主に野良)

方向性

なのでこんな感じの方向性とか機能を盛り込みました。

  • logをレベル付できるようにした。
  • 関数名とかをログに含められるようにした。
  • timeやtext/packageなどgoの標準に沿った作りにした。

サンプル

sample1.go
package main

import (
    "github.com/umisama/golog"
    "os"
)

var logger log.Logger

func OtherFuncName() {
    logger.Info("here is OtherFuncName()")
}

func main() {
    logger, _ = log.NewLogger(os.Stdout,
                        log.TIME_FORMAT_SEC,        // Set time writting format.
                        log.LOG_FORMAT_POWERFUL,    // Set log writting format.
                        log.LogLevel_Debug)         // Set log level.

    logger.Debug("debug")
    logger.Info("Infomation")
    logger.Warn("Warning!")
    logger.Critical("Critical!")

    OtherFuncName()
}
output
2014/2/9 12:41:59 main.go:20(main) : "debug"
2014/2/9 12:41:59 main.go:21(main) : "Infomation"
2014/2/9 12:41:59 main.go:22(main) : "Warning!"
2014/2/9 12:41:59 main.go:23(main) : "Critical!"
2014/2/9 12:41:59 main.go:11(OtherFuncName) : "here is OtherFuncName()"

NewLogger()がロガーを作ってくれますが、この時time.Format()とtext/templateに指示する表示を渡します。適当にカスタマイズもできます。一応、

LOG_FORMAT_SIMPLE   = "{{.Time}} : {{.Message}} \n"
LOG_FORMAT_STANDARD = "{{.Time}} {{.ShortFileName}}:({{.LineNumber}}) : {{.Message}}\n"
LOG_FORMAT_POWERFUL = "{{.Time}} {{.ShortFileName}}:{{.LineNumber}}({{.ShortFuncName}}) : {{.Message}}\n"

こんな感じのは用意してあります。
あと、当然ですがNewLogger()にあげるレベルを変えるとそれ以下のログは出力されなくなります。

    logger, _ = log.NewLogger(os.Stdout,
                        log.TIME_FORMAT_SEC,        // Set time writting format.
                        log.LOG_FORMAT_POWERFUL,    // Set log writting format.
                        log.LogLevel_Critical)      // Set log level.
output
2014/2/9 12:41:59 main.go:23(main) : "Critical!"

レベルは一応 Debug < Info < Warn < Critical という感じになってます。

工夫点

NewLogger()で取得されるLoggerは、interfaceが帰ってきます。この時、指定されたレベルに対して必要な出力メソッドのみ中身のあるもの返し、その他は、

func (x Logger) Hoge () { return }

の様に処理の無いメソッドを持つstructを返し分けています。
これでgcの最適化が効いてインライン関数になりますから、非表示で埋まっているデバッグログのパフォーマンス影響がほぼ0になります。(分岐すらできません)
上手く行ってないぽい・・・orz
デバッグコードがプロダクトに性能低下を与えることが、どうしても許せない人にオススメです。
# いや、まぁメッチャ微々たるものだけど

今後

  • プロダクトに入れて行って改良します。
34
34
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
34
34