LoginSignup
2
1

More than 5 years have passed since last update.

fluent-logger-golangでtime.Timeを送ったら"error":"#<MessagePack::UnknownExtTypeError: unexpected extension type>"が出た

Last updated at Posted at 2017-12-02

はじめに

以下のようなスクリプト、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はtimeToStrstrToTimeメソッドで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"}

こうやったら直った、っていうだけで実はあまり理由を理解してない。。。

2
1
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
2
1