goでfluentdを使ってlogを吐いてみる その2

前回まで

前回fluent-logger-golangを使ってfluentdにログを吐いてみました

今回は少し踏み込んで実際のアプリで使う場合を想定して使ってみました。

複数のstructをログに送りたいが…

実際にアプリを運用するとなると複数のstructの値をログに出力したいときがあるかと思います。

今回はPlayerPlayerComment をつかいます。

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をログに出したい場合

fluent-logger-golang

  • 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なのでそこは調整する必要があると感じました。