1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

今まで、文字列などを出力するときはlogかfmtを使って標準出力か標準エラー出力をしていたが、APIサーバを作るにあたり利用者の行動をファイルに記録する必要があると考えた。そこで、Goの標準パッケージであるlog/slogを用いて、json形式での構造化ロギングを行った。

実装

コード

このコードは、GoのWebフレームワークに一つであるginを用いた簡単なAPIサーバです。エンドポイントへのアクセスが行われたとき、その情報をlog/slogを用いてserver.logに出力します。

main.go
package main

import (
	"github.com/gin-gonic/gin"
	"io"
	"log"
	"log/slog"
	"os"
	"time"
)

func main() {
	// ファイルを開く
	file, err := os.OpenFile("server.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Println("Error")
		return
	}
	defer file.Close()
	fileWriter := io.Writer(file)

	// loggerの生成
	logger := slog.New(slog.NewJSONHandler(fileWriter, nil))
	// 生成したloggerをデフォルトにする
	slog.SetDefault(logger)

	r := gin.Default()
	// Ginのミドルウェアを設定
	r.Use(ginLogFormat(logger))

	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong")
	})

	r.Run()
}

// Ginのミドルウェア
func ginLogFormat(logger *slog.Logger) gin.HandlerFunc {
	return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
		logger.Info("gin-request",
			slog.String("time", param.TimeStamp.Format(time.RFC3339)),
			slog.Int("status", param.StatusCode),
			slog.String("latency", param.Latency.String()),
			slog.String("client_ip", param.ClientIP),
			slog.String("method", param.Method),
			slog.String("path", param.Path),
			slog.String("error", param.ErrorMessage),
		)
		return ""
	})
}

実行結果

  • http://localhost:8080/pingにアクセス -> pongが返される(200)
server.log
{"time":"2024-07-04T12:52:46.369314015+09:00","level":"INFO","msg":"gin-request","time":"2024-07-04T12:52:46+09:00","status":200,"latency":"23.841µs","client_ip":"::1","method":"GET","path":"/ping","error":""}
  • http://localhost:8080/hogeにアクセス -> ページが存在しない(404)
server.log
{"time":"2024-07-04T12:58:19.784257142+09:00","level":"INFO","msg":"gin-request","time":"2024-07-04T12:58:19+09:00","status":404,"latency":"370ns","client_ip":"::1","method":"GET","path":"/hoge","error":""}

おわりに

サードパーティのパッケージに依存せず、標準パッケージ内の機能で構造化ロギングを行えるのはすごいと思った。このパッケージのことをもう少し深く掘り下げて、実運用で活かせるようなログ収集をしていきたい。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?