Goのnet/httpでログ出力ライブラリを試した話

公開:2021/02/16
更新:2021/02/16
2 min読了の目安(約1900字TECH技術記事

echoやGinなどのライブラリを使うことでログ出力が簡単にできます。
しかし、net/httpなどでログを出すとなると少し手間がかかってしまいます。
そこで、今回はlogrusとzapといった有名ライブラリを用いてlogキレイに出力できないか検証してみました。

zap

UberのOSSライブラリ。独自のベンチマークによると他のloggerより速い。
しかし、ドキュメントが少し分かりづらい気がする。

https://github.com/uber-go/zap

logrus

loggerの中では結構有名なやつ。現在はメンテナンスモードの状態。
標準のlogより使いやすい

https://github.com/Sirupsen/logrus

zapでの実装

package handler

import (
        "go.uber.org/zap"
        "net/http"
        "time"
)

func Zap(h http.Handler) http.Handler {
        logger, _ := zap.NewDevelopment()
        defer logger.Sync()

        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                logger.Info("incoming request",
                        zap.String("Host", r.Host),
                        zap.String("path", r.URL.Path),
                        zap.String("Ua", r.UserAgent()),
                        zap.Duration("elapsed", time.Second),
                )
                h.ServeHTTP(w, r)
        })
}

デメリットとして、ログレベルごとに実装できないので、少し工夫が必要です。(今回は実装しませんでした、、)
実装したログを出力すると以下のようになります。

logrusでの実装

package handler

import (
        "github.com/sirupsen/logrus"
        "net/http"
)

func Logrus(h http.Handler) http.Handler {

        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                logrus.WithFields(logrus.Fields{
                        "method": r.Method,
			"host":   r.Host,
                        "path":   r.URL.Path,
                        "Ua":     r.UserAgent,
                }).Info("incoming request")

                h.ServeHTTP(w, r)
        })
}

ログを出力すると以下のようになります。
zapと違ってtimestampなど自前で実装するところが多い気がします。

またログレベルによって色を変えられる点がいいですね。

まとめ

zapとlogrusでは、zapの方がシンプルでいいかと思います。
ただ上記でも書いたようにzapドキュメントがあまりまとまってないののちょっと大変かと思います。