📝
GCP ログ ライブラリ v 1.5 for Golang
GCPのKubernetesでログ出力するのに便利なGolang
のライブラリです。
使い方
go get cloud.google.com/go/logging
Gin
で利用するサンプルで説明します。
ミドルウェアでロガーを初期化し、contextに保持します。
main.go
import "cloud.google.com/go/logging"
func main() {
r := gin.New()
r.Use(gcpLogger)
gcpLogger
func gcpLogger(c *gin.Context) {
client, err := logging.NewClient(c, "my-project")
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"ok": false})
}
// ロガーを生成
logger := client.Logger("my-category-log",
logging.SourceLocationPopulation(
logging.PopulateSourceLocationForDebugEntries),
logging.RedirectAsJSON(os.Stdout))
c.Set("MyLogger", logger) // contextにロガーを保持
c.Next()
if err := client.Close(); err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"ok": false})
}
}
ハンドラーからロガーを使用します。
MyHandler
func MyHandler(c *gin.Context) {
v, _ = c.Get("MyLogger") // ロガーの取り出し
logger, ok := v.(*logging.Logger)
msg := fmt.Sprintf("foo=%s, bar=%s", foo, bar) // 出力メッセージ
// ログ出力
logger.Log(logging.Entry{
Severity: logging.Debug,
Payload: msg, // メッセージ
HTTPRequest: &logging.HTTPRequest{
Request: c.Request,
}})
次のようにGCPコンソールに構造化ログが出力されます。
解説
trace (x-cloud-tracing-context)
このライブラリを使う最大のメリットは、trace
を自動設定してくれることでしょう。
logging.Entry()
のHTTPRequest
に、http.Request
を渡すとx-cloud-tracing-context
を取り出してセットしてくれます。spandId
も設定してくれますので、GCPの膨大なログで迷子にならなくてすみます。[1]
HTTPRequest: &logging.HTTPRequest{
Request: c.Request
}
sourceLocation (ソースコードの行番号を出力)
どこに仕込んだlogger.Log()
から出力したログか分かるようにソースコードの行番号を表示します。ロガーを生成するところで以下のように指定します。これはseverity
がDebug
の時だけ行番号を出力するオプションになります。
logging.SourceLocationPopulation(logging.PopulateSourceLocationForDebugEntries)
常に出力する場合は、logging.AlwaysPopulateSourceLocation
を指定します。ただしパフォーマンスが悪化するのでご注意ください。
gRPC経由でのログ出力
デフォルトではGCPのCloud Logging APIをgRPCで呼び出してログ出力します。その場合は以下のようにlogging.RedirectAsJSON()
を削除します。[2]
ログ出力を非同期に実行できるためログ出力によるパフォーマンスの低下を避けることができます。
-client.Logger('my-logger', logging.RedirectAsJSON(os.Stdout))
+client.Logger('my-logger')
message メッセージ
Payloadに構造体をそのまま渡して出力できます。
type Category struct {
ID string `json:"id"`
Name string `json:"name"`
}
cat := Category{...}
logging.Entry{Payload: cat, ...}
Discussion