はじめに
以下のようなスクリプト、configでfluentdに送ってみる
Log
についてはgo generateでmsgp.Marshaler
を自動生成しています
msgpのgeneratorについてはこちら
main.go
package main
//go:generate msgp
import (
"log"
"time"
"github.com/fluent/fluent-logger-golang/fluent"
)
func main() {
logger, err := fluent.New(fluent.Config{FluentPort: 24224, FluentHost: "127.0.0.1"})
if err != nil {
log.Println(err.Error())
return
}
defer logger.Close()
logData := Log{
ID: 12345,
Name: "hogehoge",
CreatedAt: time.Now(),
}
if err := logger.Post("debug.test", logData); err != nil {
log.Println(err.Error())
return
}
log.Println("done")
}
type Log struct {
ID uint32 `msg:"id"`
Name string `msg:"name"`
CreatedAt time.Time `msg:"created_at"`
}
fluent.conf
<source>
@type forward
</source>
<match **>
@type file
path /path/to/log
</match>
実行
$ go run main.go main_gen.go
2017/12/02 19:30:16 done
ログを見てみる
何かエラーが出ている。
cat log/app.log.20171202.b55f58f8a5413f5de
2017-12-02T19:30:16+09:00 fluent.error {"error":"#<MessagePack::UnknownExtTypeError: unexpected extension type>","error_class":"MessagePack::UnknownExtTypeError","message":"forward error error=#<MessagePack::UnknownExtTypeError: unexpected extension type> error_class=MessagePack::UnknownExtTypeError"}
解決策
msgpでtime.Timeを扱うときにstringとして変換するように以下の1行を追加してgo generate
//msgp:shim time.Time as:string using:timeToStr/strToTime
これでtime.TimeはtimeToStr
とstrToTime
メソッドでstringに変換されて用いられます。
なので、これらのメソッドも実装しておきます
func timeToStr(t time.Time) string {
return t.Format("2006-01-02 15:04:05")
}
func strToTime(v string) time.Time {
t, _ := time.Parse("2006-01-02 15:04:05", v)
return t
}
最終的なスクリプトは以下
main.go
package main
//go:generate msgp
//msgp:shim time.Time as:string using:timeToStr/strToTime
import (
"log"
"time"
"github.com/fluent/fluent-logger-golang/fluent"
)
func main() {
logger, err := fluent.New(fluent.Config{FluentPort: 24224, FluentHost: "127.0.0.1"})
if err != nil {
log.Println(err.Error())
return
}
defer logger.Close()
logData := Log{
ID: 12345,
Name: "hogehoge",
CreatedAt: time.Now(),
}
if err := logger.Post("debug.test", logData); err != nil {
log.Println(err.Error())
return
}
log.Println("done")
}
type Log struct {
ID uint32 `msg:"id"`
Name string `msg:"name"`
CreatedAt time.Time `msg:"created_at"`
}
func timeToStr(t time.Time) string {
return t.Format("2006-01-02 15:04:05")
}
func strToTime(v string) time.Time {
t, _ := time.Parse("2006-01-02 15:04:05", v)
return t
}
これで送信すると
$ go run main.go main_gen.go
2017/12/02 19:39:56 done
ちゃんとした形でログが出ています
$ cat log/app.log.20171202.b55f58f8a5413f5de
2017-12-02T19:39:56+09:00 debug.test {"id":12345,"name":"hogehoge","created_at":"2017-12-02 19:39:56"}
こうやったら直った、っていうだけで実はあまり理由を理解してない。。。