概要
bep/logg というログライブラリが公開されていて、ベンチマークの結果を見ると速かったのでちょっと触ってみました。
apex/log からフォークしたライブラリみたいですね。
まだ、バージョンは v0.1.0 だけど、シンプルな構成で使いやすいと思いました。
以下、サンプルです。せっかくなので、ちょっと非同期処理しながらログ出力するようにしてみました。
サンプル
package main import ( "context" "fmt" "io" "net/http" "os" "runtime" "github.com/bep/logg" "github.com/bep/logg/handlers/cli" "github.com/devlights/gomy/chans" "github.com/devlights/gomy/errs" ) type ( data struct { url string length int info *logg.Entry } ) var ( handler = cli.New(os.Stderr) logger = logg.New(logg.Options{Level: logg.LevelInfo, Handler: handler}) appLog = logger.WithLevel(logg.LevelInfo) ) func main() { var ( ctx = context.Background() done = ctx.Done() urls = []string{ "https://devlights.hatenablog.com/", "https://github.com/devlights/gomy", "https://github.com/devlights/try-golang", "https://github.com/devlights/try-python", "https://github.com/devlights/try-csharp", "https://qiita.com/", "https://zenn.dev/", "https://dev.to/", } ) var ( in = chans.ForEach(done, urls...) out = make(chan data) ) var ( workerCount = runtime.NumCPU() / 2 fanOut = chans.FanOut(done, in, workerCount, func(url string) { info := appLog.WithField("url", url) info.Log(logg.String("fetching")) defer info.Log(logg.String("fetched ")) resp := errs.Panic(http.Get(url)) defer resp.Body.Close() buf := errs.Panic(io.ReadAll(resp.Body)) out <- data{url, len(buf), info} }) ) go func() { defer close(out) <-chans.WhenAll(fanOut...) }() for v := range out { v := v v.info.Log(logg.StringFunc(func() string { return fmt.Sprintf("%d bytes", v.length) })) } }
実行すると、例えば以下のように出力されます。
$ go run main.go • fetching url=https://devlights.hatenablog.com/ • fetching url=https://qiita.com/ • fetching url=https://github.com/devlights/try-python • fetching url=https://github.com/devlights/gomy • fetching url=https://github.com/devlights/try-golang • fetching url=https://zenn.dev/ • fetching url=https://github.com/devlights/try-csharp • fetched url=https://github.com/devlights/gomy • 216923 bytes url=https://github.com/devlights/gomy • fetched url=https://github.com/devlights/try-csharp • 191365 bytes url=https://github.com/devlights/try-csharp • fetched url=https://github.com/devlights/try-golang • 208036 bytes url=https://github.com/devlights/try-golang • fetched url=https://github.com/devlights/try-python • 200681 bytes url=https://github.com/devlights/try-python • fetched url=https://zenn.dev/ • fetching url=https://dev.to/ • 164268 bytes url=https://zenn.dev/ • fetched url=https://dev.to/ • 479801 bytes url=https://dev.to/ • fetched url=https://devlights.hatenablog.com/ • 64004 bytes url=https://devlights.hatenablog.com/ • fetched url=https://qiita.com/ • 183852 bytes url=https://qiita.com/
上の出力は、ハンドラを cli にしている状態で、 text にすると以下のようになります。
$ go run main.go INFO fetching url=https://devlights.hatenablog.com/ INFO fetching url=https://github.com/devlights/try-csharp INFO fetching url=https://github.com/devlights/try-golang INFO fetching url=https://github.com/devlights/try-python INFO fetching url=https://zenn.dev/ INFO fetching url=https://dev.to/ INFO fetching url=https://qiita.com/ INFO fetched url=https://zenn.dev/ INFO 164268 bytes url=https://zenn.dev/ INFO fetched url=https://dev.to/ INFO 479801 bytes url=https://dev.to/ INFO fetched url=https://github.com/devlights/try-python INFO 200681 bytes url=https://github.com/devlights/try-python INFO fetched url=https://devlights.hatenablog.com/ INFO fetching url=https://github.com/devlights/gomy INFO 64004 bytes url=https://devlights.hatenablog.com/ INFO fetched url=https://github.com/devlights/try-csharp INFO 191365 bytes url=https://github.com/devlights/try-csharp INFO fetched url=https://github.com/devlights/try-golang INFO 208036 bytes url=https://github.com/devlights/try-golang INFO fetched url=https://qiita.com/ INFO 183852 bytes url=https://qiita.com/ INFO fetched url=https://github.com/devlights/gomy INFO 226120 bytes url=https://github.com/devlights/gomy
jsonにすると以下のようになります。
$ go run main.go {"level":"info","timestamp":"2022-08-12T06:48:49.052414898Z","fields":[{"name":"url","value":"https://github.com/devlights/try-golang"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.052455998Z","fields":[{"name":"url","value":"https://github.com/devlights/try-csharp"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.052478928Z","fields":[{"name":"url","value":"https://github.com/devlights/try-python"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.052485748Z","fields":[{"name":"url","value":"https://devlights.hatenablog.com/"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.052493508Z","fields":[{"name":"url","value":"https://github.com/devlights/gomy"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.124647118Z","fields":[{"name":"url","value":"https://github.com/devlights/try-python"}],"message":"fetched "} {"level":"info","timestamp":"2022-08-12T06:48:49.124701448Z","fields":[{"name":"url","value":"https://github.com/devlights/try-python"}],"message":"200681 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.127061278Z","fields":[{"name":"url","value":"https://github.com/devlights/try-csharp"}],"message":"191365 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.127022028Z","fields":[{"name":"url","value":"https://github.com/devlights/try-csharp"}],"message":"fetched "} {"level":"info","timestamp":"2022-08-12T06:48:49.127183268Z","fields":[{"name":"url","value":"https://qiita.com/"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.131769767Z","fields":[{"name":"url","value":"https://github.com/devlights/gomy"}],"message":"fetched "} {"level":"info","timestamp":"2022-08-12T06:48:49.131796387Z","fields":[{"name":"url","value":"https://dev.to/"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.131890257Z","fields":[{"name":"url","value":"https://github.com/devlights/gomy"}],"message":"214604 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.133329867Z","fields":[{"name":"url","value":"https://github.com/devlights/try-golang"}],"message":"fetched "} {"level":"info","timestamp":"2022-08-12T06:48:49.133365087Z","fields":[{"name":"url","value":"https://github.com/devlights/try-golang"}],"message":"208036 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.1765476Z","fields":[{"name":"url","value":"https://dev.to/"}],"message":"fetched "} {"level":"info","timestamp":"2022-08-12T06:48:49.17662295Z","fields":[{"name":"url","value":"https://dev.to/"}],"message":"479801 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.426874904Z","fields":[{"name":"url","value":"https://devlights.hatenablog.com/"}],"message":"fetched "} {"level":"info","timestamp":"2022-08-12T06:48:49.426951764Z","fields":[{"name":"url","value":"https://zenn.dev/"}],"message":"fetching"} {"level":"info","timestamp":"2022-08-12T06:48:49.426990114Z","fields":[{"name":"url","value":"https://devlights.hatenablog.com/"}],"message":"64004 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.442471392Z","fields":[{"name":"url","value":"https://zenn.dev/"}],"message":"fetched "} {"level":"info","timestamp":"2022-08-12T06:48:49.442509422Z","fields":[{"name":"url","value":"https://zenn.dev/"}],"message":"164268 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.805860549Z","fields":[{"name":"url","value":"https://qiita.com/"}],"message":"183852 bytes"} {"level":"info","timestamp":"2022-08-12T06:48:49.805652549Z","fields":[{"name":"url","value":"https://qiita.com/"}],"message":"fetched "}
参考情報
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。