Successfully reported this slideshow.

Gocon2017:Goのロギング周りの考察

2,863 views

Published on

Golangでのロギング状況がどうなっているのかを調べてみました。
Go で作られたOSSで採用されているロギングライブラリや、ロギングライブラリ作者

Published in: Technology
  • Be the first to comment

Gocon2017:Goのロギング周りの考察

  1. 1. Goのロギング周りの考 察 株式会社ホワイトプラス システム開発Gマネジャー 大和屋貴仁 Go Conference 2017 Autumn OSSで採用されているロギング
  2. 2. 大和屋貴仁 株式会社ホワイトプラス システム開発G マネジャー Microsoft MVP for Azure(2011-2018 Qiita : @t_Yamatoya http://sqlazure.jp/r
  3. 3. 富士フィルムイメージングシステムズと 共同開発したRFID検証。 宅配ネットクリーニングのリネット 会員数20万人突破! Golang、RFIDなど新しい技術や物を活用したサービス改善に興味のあるエンジニア募集!!
  4. 4. 今日のお話 標準logパッケージの特徴 OSSのロギング事情 利用しているロギングライブラリ Golangのロギング事情について調べてみまし た アプリを書くときのロギング実装の参考になれば幸い
  5. 5. SRE サイトリライアビリティエンジニアリング ――Googleの信頼性を支えるエンジニアリングチーム
  6. 6. Prometheusは、特にルール言語にBorgmonと多くの類似 点があります。 依然としてBorgmonはGoogle内部のものですが、ア ラートを発するためのデータソースとして時系列デー タを扱うという発想は、今日ではPrometheus、Riemann、 Heka、Bosunといったオープンソースのツールを通じ て広く受け入れられており… Prometheus と google SRE サイトリライアビリティエンジニアリング ――Googleの信頼性を支えるエンジニアリングチーム
  7. 7. Prometheus 入門から運用まで徹底解説
  8. 8. Logging for Prometheus
  9. 9. 1通のメールが発端 Fabian Reinartz ドイツ ベルリン 2016/04- CoreOS 2015/09-2016/03 SoundCloud/Prometheus 2017年08月10日 To: Prometheus Developers Group Instead I just want to serve Brian's request to discuss our logging library usage. Triggered was this by me using Go kit's logging package in prometheus/tsdb rather than our so far canonical prometheus/common/log package. Prometheusで使用するロギングライブラリについて議論したい。 tsdbではGo kitを使用してたよね。
  10. 10. Prometheusの実装的なお話し prometheus/tsdb PrometheusのTime Series Database ストレージレイヤー prometheus/Prometheus メイン実装 prometheus/common/log github.com/go-kit/kit/log 異なるロギングライブラリを使用している
  11. 11. Prometheusの実装的なお話し prometheus/tsdb PrometheusのTime Series Database ストレージレイヤー prometheus/Prometheus メイン実装 prometheus/common/log github.com/go-kit/kit/log 1つのメソッドをもつインターフェイスがベース ロギングライブラリを完璧にラッピングしている 18のメソッドをもつ複雑なインターフェイス ロガーをプラグインで使用してもらうには、Go Kitライブラリは便利。common/logは年月を経て、いろんな副作用 を内在してしまっている。
  12. 12. Prometheusのロギング変更に関する意見 ・2種類のライブラリを使用するのは混乱の元なので一貫性が気になる。 ・強いこだわりはない ・tsdbはできるだけ一般的でPrometheus固有でないロギングインターフェイスを使用する必要がある ・Go Kit と作者はGo Communityに強い影響力を持っているので一般的に採用可能で、 将来的にも問題ないかな Switch to go-kit log #3061 https://github.com/prometheus/prometheus/pull/3061
  13. 13. Logging : Go Kit
  14. 14. Gokitのロギング仕様ブック https://docs.google.com/document/d/1shW9DZJXOeGbG9Mr9Us9MiaPqmlcVatD_D8lrOXRNMU/edit#
  15. 15. Log パッケージで不便な点 とてもシンプルなパッケージ ・非構造体(Printスタイル) ・限定的な設定項目 時間や日付の出力単位 ログの出力パスの指定 ・loggerは型で定義されている ・グローバルloggerオブジェクトが提供される
  16. 16. Log パッケージで困ること ・型で定義されているので、別の実装を提供しにくい ・グローバルloggerオブジェクトを呼び出す関数が存在する インポートしたライブラリのロギングを制御しにくい ・レベル付きロギングが欲しい debug、info、warn、error
  17. 17. Dave Chene シドニーのプログラマ 2011年2月からGoのコントリビューター 2011年4月からGoのコミッター 非公式の調査:Goアプリケーションのロギング状況 https://groups.google.com/forum/#!msg/golang-dev/F3l9Iz1JX4g/BOBpbhF-FAAJ
  18. 18. 大きく次の3種類のルートを選択している ・fmt.Printf ・logパッケージから関数を使用する ・パッケージレベルのログ変数の宣言 非公式の調査:Goアプリケーションのロギング状況 https://groups.google.com/forum/#!msg/golang-dev/F3l9Iz1JX4g/BOBpbhF-FAAJ
  19. 19. というわけでサードパーティ 乱立するロギングライブラリ golang/glog inconshreveable/log15 sirupsen/logrus uber-go/zap go-kit/go ロギングは常時付いて回る 乱立していると、どのライブラリを使用すると良いのか悩む
  20. 20. Prometheusのロギング go-kit/kit/log github.com/go-kit/kit/log promlog/log.go でゆるーくラッピングしている func New(al AllowedLevel) log.Logger { l := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) l = log.With(l, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) return l }
  21. 21. Prometheusのロギング go-kit/kit/log github.com/go-kit/kit/log key/value形式の構造化ロギング レベル付ロギング 文脈情報の付加 JSONフォーマット、テキストフォーマットの出力
  22. 22. Prometheusのロギング go-kit/kit/log github.com/go-kit/kit/log logger.Log("transport", "HTTP", "addr", addr, "msg", "listening") key/value形式で指定する構造化ログ var logger log.Logger logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) logger = log.With(logger, "instance_id", 123) logger.Log("msg", "starting") 文脈情報の付加 instance_id=123 msg=starting
  23. 23. Prometheusのロギング go-kit/kit/log github.com/go-kit/kit/log var logger log.Logger logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) logger.Log("msg", "hello") 呼び出し元と時間情報の付加 ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello
  24. 24. Syncthinsのロギング log 標準パッケージ log.Println("Lstat:") log.Printf(" Size: %d bytes", fi.Size()) log.Printf(" Mode: 0%o", fi.Mode()) log.Printf(" Time: %v", fi.ModTime()) log.Printf(" %d.%09d", fi.ModTime().Unix(), fi.ModTime().Nanosecond()) log.Println() func main() { log.SetFlags(0) log.SetOutput(os.Stdout) Goの標準ライブラリのlogパッケージをそのまま利用。
  25. 25. Terraformのロギング オリジナル:logutils github.com/hashicorp/logutils Goのエコシステムを断片化せずに 標準ライブラリのlogパッケージを拡張して少しモダンにします → Logパッケージを使用したまま、logutilsに切り替え可能
  26. 26. package main import ( "log" ) func main() { log.Print("[DEBUG] Debugging") log.Print("[WARN] Warning") log.Print("[ERROR] Erring") log.Print("Message I haven't updated") } github.com/hashicorp/logutils
  27. 27. package main import ( "log" "os" "github.com/hashicorp/logutils" ) func main() { filter := &logutils.LevelFilter{ Levels: []logutils.LogLevel{"DEBUG", "WARN", "ERROR"}, MinLevel: logutils.LogLevel("WARN"), Writer: os.Stderr, } log.SetOutput(filter) log.Print("[DEBUG] Debugging") log.Print("[WARN] Warning") log.Print("[ERROR] Erring") log.Print("Message I haven't updated") } github.com/hashicorp/logutils
  28. 28. github.com/hashicorp/logutils Levelsに指定した文字列、順序でLevelが登録される Levels: []logutils.LogLevel{"DEBUG", "WARN", "ERROR"} DEBUG, WARN, ERROR WARN, DEBUG, ERROR A, B, C HOGE, FOO, BAR 与えた文字列の[ ]で括られた部分をレベルとして認識する log.Print("[DEBUG] Debugging") [DEBUG] FOO FOOHOGE [DEBUG] Hogehoge [DEBUG] FOO LOGにレベル概念を付与し、 指定したレベル以上のログだけを出力させる機能
  29. 29. github.com/hashicorp/logutils Levelsに指定した文字列、順序でLevelが登録される Levels: []logutils.LogLevel{"DEBUG", "WARN", "ERROR"} DEBUG, WARN, ERROR WARN, DEBUG, ERROR A, B, C HOGE, FOO, BAR 与えた文字列の[ ]で括られた部分をレベルとして認識する log.Print("[DEBUG] Debugging") [DEBUG] FOO FOOHOGE [DEBUG] Hogehoge [DEBUG] FOO LOGにレベル概念を付与し、 指定したレベル以上のログだけを出力させる機能 x := bytes.IndexByte(line, '[') if x >= 0 { y := bytes.IndexByte(line[x:], ']') if y >= 0 { level = LogLevel(line[x+1 : x+y]) } } _, ok := f.badLevels[level]
  30. 30. Kubernetesのロギング golang/glog staging/src/k8s.io/apiserver/pkg/util/logs 実態は、golang/glogを使用している。 k8s.io/apiserver/pkg/util/logs はglogの実装。 glogの既定のFlush時間を30秒から5秒に変更 func InitLogs() { log.SetOutput(GlogWriter{}) log.SetFlags(0) go wait.Until(glog.Flush, *logFlushFreq, wait.NeverStop) }
  31. 31. Kubernetesのロギング golang/glog staging/src/k8s.io/apiserver/pkg/util/logs 実態は、golang/glogを使用している。 k8s.io/apiserver/pkg/util/logs はglogの実装。 google内で使用しているC++ロギングと同様のログ実装 Info、Warning、Error、Fatal関数の提供 Infofのような書式設定 Vスタイルのロギング
  32. 32. OpenShiftのロギング k8s.io/apiserver/pkg/util/logs github.com/kubernetes/apiserver/tree/master/pkg/util/logs github.com/golang/glog 実態は、golang/glogを使用している。
  33. 33. Grafanaのロギング オリジナル:grafana/grafana/pkg/log github.com/grafana/grafana/pkg/log inconshreveable/log15を使用している var logLevels = map[string]log15.Lvl{ "trace": log15.LvlDebug, "debug": log15.LvlDebug, "info": log15.LvlInfo, "warn": log15.LvlWarn, "error": log15.LvlError, "critical": log15.LvlCrit, } func Debug(format string, v ...interface{}) { var message string if len(v) > 0 { message = fmt.Sprintf(format, v...) } else { message = format } Root.Debug(message) }
  34. 34. Grafanaのロギング inconshreveable/log15 github.com/grafana/grafana/pkg/log inconshreveable/log15を使用している key/value の構造型ログ レベル付きログ ターミナル出力時のカラーリング対応 ファイル、ストリーム、syslog、ネットワークへの出力 出力のバッファリング
  35. 35. Docker(moby/moby)のロギング logrus https://github.com/Sirupsen/logrus if cli.Config.Experimental { logrus.Warn("Running experimental build") } logrus.SetFormatter(&logrus.TextFormatter{ TimestampFormat: jsonmessage.RFC3339NanoFixed, DisableColors: cli.Config.RawLogs, FullTimestamp: true, })
  36. 36. Docker(moby/moby)のロギング logrus https://github.com/Sirupsen/logrus logrusは構造化Loggerです レベル付きログ コンソール出力時のカラー書式設定に対応 出力にJSON形式やテキスト形式、標準出力などに対応
  37. 37. InfluxDBのロギング zap github.com/uber-go/zap func NewService(c Config) (*Service, error) { s := Service{ checkInterval: time.Duration(c.CheckInterval), advancePeriod: time.Duration(c.AdvancePeriod), Logger: zap.New(zap.NullEncoder()), } return &s, nil } // WithLogger sets the logger for the service. func (s *Service) WithLogger(log zap.Logger) { s.Logger = log.With(zap.String("service", "shard-precreation")) }
  38. 38. InfluxDBのロギング zap github.com/uber-go/zap logrusは構造化Loggerです レベル付きログ
  39. 39. glg https://github.com/kpango/glg glg is simple and fast leveled logging library for Go. glog https://github.com/golang/glog Leveled execution logs for Go. go-cronowriter https://github.com/utahta/go-cronowriter Simple writer that rotate log files automatically based on current date and time, like cronolog. go-log https://github.com/siddontang/go-log Log lib supports level and multi handlers. go-log https://github.com/ian-kent/go-log Log4j implementation in Go. go-logger https://github.com/apsdehal/go-logger Simple logger of Go Programs, with level handlers. gologger https://github.com/sadlil/gologger Simple easy to use log lib for go, logs in Colored Console, Simple Console, File or Elasticsearch. gomol https://github.com/aphistic/gomol Multiple-output, structured logging for Go with extensible logging outputs. gone/log https://github.com/One-com/gone/tree/master/log Fast, extendable, full-featured, std-lib source compatible log library. log https://github.com/apex/log Structured logging package for Go. log https://github.com/go-playground/log Simple, configurable and scalable Structured Logging for Go. log-voyage https://github.com/firstrow/logvoyage Full-featured logging saas written in golang. log15 https://github.com/inconshreveable/log15 Simple, powerful logging for Go. logdump https://github.com/ewwwwwqm/logdump Package for multi-level logging. logex https://github.com/chzyer/logex Golang log lib, supports tracking and level, wrap by standard log lib. logger https://github.com/azer/logger Minimalistic logging library for Go. logo https://github.com/mbndr/logo Golang logger to different configurable writers. logrus https://github.com/Sirupsen/logrus Structured logger for Go. logrusly https://github.com/sebest/logrusly logrus plug-in to send errors to a Loggly logutils https://github.com/hashicorp/logutils Utilities for slightly better logging in Go (Golang) extending the standard logger. logxi https://github.com/mgutz/logxi 12-factor app logger that is fast and makes you happy. lumberjack https://github.com/natefinch/lumberjack Simple rolling logger, implements io.WriteCloser. mlog https://github.com/jbrodriguez/mlog Simple logging module for go, with 5 levels, an optional rotating logfile feature and stdout/stderr output. ozzo-log https://github.com/go-ozzo/ozzo-log High performance logging supporting log severity, categorization, and filtering. Can send filtered log messages to various targets (e.g. console, network, mail). seelog https://github.com/cihub/seelog Logging functionality with flexible dispatching, filtering, and formatting. slf https://github.com/ventu-io/slf The Structured Logging Facade (SLF) for Go (like SLF4J but structured and for Go). slog https://github.com/ventu-io/slog The reference implementation of the Structured Logging Facade (SLF) for Go. spew https://github.com/davecgh/go-spew Implements a deep pretty printer for Go data structures to aid in debugging. stdlog https://github.com/alexcesaro/log Stdlog is an object-oriented library providing leveled logging. It is very useful for cron jobs. tail https://github.com/hpcloud/tail Go package striving to emulate the features of the BSD tail program. xlog https://github.com/xfxdev/xlog Plugin architecture and flexible log system for Go, with level ctrl, multiple log target and custom log format. xlog https://github.com/rs/xlog Structured logger for `net/context` aware HTTP handlers with flexible dispatching. 参考:awesome-goのLoggingより34種類
  40. 40. まとめ ロギングは次の3パターンが多い ・fmt.Printf ・logパッケージから関数を使用する ・パッケージレベルのログ変数の宣言 ライブラリは乱立して、これが強いとかない状況 ・Prometheus : go-kit/kit/log ・Hashicorp : hashicorp/logutils ・Docker : logrus ・kubernetes : golang/glog ・Grafana : inconshreveable/log15
  41. 41. まとめ ライブラリは以下のような特徴を持つ傾向 key/value の構造型ログ レベル付きログ ターミナル出力時のカラーリング対応や書式設定 出力フォーマット 出力先 出力のバッファリング 目立った特徴を探すのが大変な状況。 自分の好みで良いかも?
  42. 42. ロギングライブラリ・ロギング実装に関する お話でした アプリケーションを書く際にロギング実装の検討材料になれば幸いです Golang
  43. 43. http://sqlazure.jp/r/ コンタクト

×
Save this presentationTap To Close