これはなに
Golangでお手軽にWebサーバを作成する場合、軽量Webフレームワークである echo を選択する方は多いと思います。
いざ可動させよう、といったときにLogフォーマットが揃っていると後々便利になりますし、
ある程度こなれた人であればそうそうにフォーマットを整えることでしょう。
本記事では、広く普及しているLTSVフォーマットで出力するサンプルを紹介します。
(LTSVがなにでどう嬉しいかは説明しません)
LTSVフォーマットでアクセスログを出力する
HelloWorldのサンプルでは、e.Use(middleware.Logger())
でデフォルトのロガー使っています。
middleware.LoggerWithConfig()
を使ってアクセスログをカスタマイズすることができます。
logger := middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: logFormat(),
Output: os.Stdout,
})
e.Use(logger)
Formatはパラメータが多く、長くなりがちなため別関数にしています。
ログフォーマットは
"keyname:${tag}\tkey2name:${tag2}\n"
という形のフォーマットを定義することでLTSV形式で出力できます。
(最後\n
で改行を忘れないようにしましょう)
参照できるログのタグはこちらで確認します。
以下はアクセスログプロファイラ alp のパラメータを参考にしたLTSVフォーマットです。
func logFormat() string {
// Refer to https://github.com/tkuchiki/alp
var format string
format += "time:${time_rfc3339}\t"
format += "host:${remote_ip}\t"
format += "forwardedfor:${header:x-forwarded-for}\t"
format += "req:-\t"
format += "status:${status}\t"
format += "method:${method}\t"
format += "uri:${uri}\t"
format += "size:${bytes_out}\t"
format += "referer:${referer}\t"
format += "ua:${user_agent}\t"
format += "reqtime_ns:${latency}\t"
format += "cache:-\t"
format += "runtime:-\t"
format += "apptime:-\t"
format += "vhost:${host}\t"
format += "reqtime_human:${latency_human}\t"
format += "x-request-id:${id}\t"
format += "host:${host}\n"
return format
}
nginxなどと違ってレスポンスヘッダに対応していなかったり、レスポンスタイムがナノ秒単位固定だったりと、alp互換を作ることは困難でしたがLTSVで出力するという目標は達成できました。
スタートバナーを消す
デフォルトの設定では次のようにスタートバナーが表示されます。
$ go run main.go
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v3.3.dev
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:1323
最終的にLTSV以外のログは除外する必要が出てきそうなので消してしまいます。
HideBannerおよびHidePortがそれに当たるオプションですのでechoインスタンスの作成時に無効にします。
// Echo instance
e := echo.New()
e.HideBanner = true
e.HidePort = true
実行例
$ go run main.go
time:2018-11-01T22:53:59+09:00 host:::1 forwardedfor: req:- status:200 method:GET uri:/ size:14 referer: ua:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 reqtime_ns:21333 cache:- runtime:- apptime:- vhost:localhost:1323 reqtime_human:21.333µs x-request-id: host:localhost:1323
作成したHelloWorldサンプル
package main
import (
"net/http"
"os"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
func main() {
// Echo instance
e := echo.New()
e.HideBanner = true
e.HidePort = true
// Middleware
logger := middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: logFormat(),
Output: os.Stdout,
})
e.Use(logger)
e.Use(middleware.Recover())
// Route => handler
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!\n")
})
// Start server
e.Logger.Fatal(e.Start(":1323"))
}
func logFormat() string {
// Refer to https://github.com/tkuchiki/alp
var format string
format += "time:${time_rfc3339}\t"
format += "host:${remote_ip}\t"
format += "forwardedfor:${header:x-forwarded-for}\t"
format += "req:-\t"
format += "status:${status}\t"
format += "method:${method}\t"
format += "uri:${uri}\t"
format += "size:${bytes_out}\t"
format += "referer:${referer}\t"
format += "ua:${user_agent}\t"
format += "reqtime_ns:${latency}\t"
format += "cache:-\t"
format += "runtime:-\t"
format += "apptime:-\t"
format += "vhost:${host}\t"
format += "reqtime_human:${latency_human}\t"
format += "x-request-id:${id}\t"
format += "host:${host}\n"
return format
}