概要
Sidekiq と互換性のある golang 製の go-workers でカスタムロギングを設定する方法を紹介します
環境
- macOS 10.14.6
- go 1.12.9
通常の場合
package main
import (
"github.com/jrallison/go-workers"
"time"
)
func perform(msg *workers.Msg) {
c, _ := msg.Args().Int()
for i := 0; i < c; i++ {
time.Sleep(1 * time.Second)
workers.Logger.Println(i)
}
workers.Logger.Println("end")
}
func main() {
workers.Configure(map[string]string{
"server": "localhost:6379",
"process": "1",
})
workers.Process("default", perform, 1)
workers.Run()
}
これで実行すると以下のようなフォーマットで表示されます
これをいろいろとカスタムしてみたいと思います
そもそもカスタムするには
公式の issue に回答があります
基本的には workers.Logger
に好きな logger を設定すれば OK です
それ以外にも Println
と Printf
を実装した構造体を設定しても OK です
後者のほうがより自分でカスタマイズできます
特定の値を常に入れる
例えばファイル名と実行行数を入れたい場合には以下のようにします
package main
import (
"github.com/jrallison/go-workers"
"log"
"os"
"time"
)
func perform(msg *workers.Msg) {
c, _ := msg.Args().Int()
for i := 0; i < c; i++ {
time.Sleep(1 * time.Second)
workers.Logger.Println(i)
}
workers.Logger.Println("end")
}
func main() {
logger := log.New(os.Stdout, "workers: ", log.Ldate|log.Lmicroseconds)
logger.SetFlags(log.LstdFlags | log.Lshortfile)
workers.Logger = logger
workers.Configure(map[string]string{
"server": "localhost:6379",
"process": "1",
})
workers.Process("default", perform, 1)
workers.Run()
}
=> workers: 2019/08/30 16:22:49 manager.go:53: processing queue default with 1 workers.
標準の log パッケージを使って logger を作成し SetFlags
でファイル名と行数を出力するようにしています
こんな感じで好きなロギングパッケージを workers.Logger
に設定することでカスタムできます
Println と Printf を実装する
もうひとつの方法を紹介します
こちらのほうがカスタマイズ性は高いですが考慮することが多いので面倒でもあります
構造体を一つ定義しそこに Println
と Printf
関数を実装します
package main
import (
"encoding/json"
"fmt"
"github.com/jrallison/go-workers"
"strconv"
"sync"
"time"
)
type MyLogger struct {
}
func (l *MyLogger) Println(v ...interface{}) {
m := map[string]string{}
for i, vv := range v {
switch vv.(type) {
case string:
m["msg"+strconv.Itoa(i)] = vv.(string)
case int:
m["msg"+strconv.Itoa(i)] = strconv.Itoa((vv.(int)))
}
}
j, _ := json.Marshal(m)
fmt.Println(string(j))
}
func (l *MyLogger) Printf(fmt string, v ...interface{}) {
// noop
}
func waiter(i int) {
t := time.Duration(i)
time.Sleep(t * time.Second)
workers.Logger.Println(i)
}
func perform(msg *workers.Msg) {
c, _ := msg.Args().Int()
var wg sync.WaitGroup
for i := 0; i < c; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
waiter(i)
}(i)
}
wg.Wait()
workers.Logger.Println("end")
}
func main() {
workers.Logger = &MyLogger{}
workers.Configure(map[string]string{
"server": "localhost:6379",
"process": "1",
})
workers.Process("default", perform, 1)
workers.Run()
}
=> {"msg0":"processing queue","msg1":"default","msg2":"with","msg3":"1","msg4":"workers."}
[]interface{}
で渡ってくるので型を意識する必要があります
今回は JSON に変換していますがそれが目的であればサードパーティのパッケージを使ったほうが良いかなと思います
また上記では Println
関数しか実装していませんが Printf
も使うのであれば実装しましょう
最後に
go-workers でロギングをカスタマイズする方法を紹介しました
個人的には workers.Logger
をロギングパッケージで上書きする方法が簡単で良いかなと思います
自分でロガーを作成したい場合は後者の Println
を実装する方法をおすすめします
0 件のコメント:
コメントを投稿