goでfluentdを使ってlogを吐いてみる その2
前回まで
前回はfluent-logger-golangを使ってfluentdにログを吐いてみました
今回は少し踏み込んで実際のアプリで使う場合を想定して使ってみました。
複数のstructをログに送りたいが…
実際にアプリを運用するとなると複数のstructの値をログに出力したいときがあるかと思います。
今回はPlayer
と PlayerComment
をつかいます。
type Player struct {
ID int `msg:"id"`
Name string `msg:"name"`
}
type PlayerComment struct {
ID int `msg:"id"`
Comment string `msg:"comment"`
PlayerID int `msg:"player_id"`
CreatedAt int64 `msg:"created_at"`
UpdatedAt int64 `msg:"updated_at"`
}
この2つのstructをログに出したい場合
- map[string]literal
- map[string]literal
- struct
のいずれかである必要があります。 今回は複数のstructのデータをログに出力したいので map[string]interface{}
を使います
data := make(map[string]interface)
data["player"] = &Player{ID: 1, Name: "hogehoge"}
data["player_comment"] = &PlayerComment{ID: 1, PlayerID: 1, Comment: "fugafuga"}
こののようになるかと思います
しかし実際にこれを動かすと
fluent#EncodeAndPostData: can't convert ... to msgpack:msgp: type "main.Player" not supported
この様なエラーになり送ることができません。 (自分もこれで嵌り先輩に相談しました…)
複数のstructをログに送る
tinylib/msgp を使用してmsgpack用のメソッドを自動生成します
自動生成の方はtinylib/msgpのwiki に詳しく書いてあります
//go:generate msgp
をファイルに追加してあげて $ go generate
コマンドを実行します
するとこのようなファイルが生成されます
(長いのでgistに貼っています)
生成できたら
$ go run main.go main_gen.go
でログが送れるようになると思います。
Konboi/go-fluent-logger-sample にサンプルコードを置いておきましたのでこちらを見てもらえればと思います。
さいごに
多少嵌りましたが、LL言語でやっていたときのようなログの出力ができることが確認できました
しかし検証してみたところtime.Time
などはfieldがunexporteなのでそこは調整する必要があると感じました。