结构化日志记录
发布者:admin 发表于:442天前 阅读数:536 评论:0

记录日志的主要目的是便于在事件发生或过后检查系统的状态。当你有大量正在记录日志的微服务时,日志消息会很难梳理。

本节使用第三方库来对日志进行记录。

实践

获取第三方库:

go get github.com/sirupsen/logrus
go get github.com/apex/log

建立logrus.go:

package structured

import "github.com/sirupsen/logrus"

// Hook 实现了logrus中的hook 接口
type Hook struct {
    id string
}

// Fire 在每次记录日志时都会触发
func (hook *Hook) Fire(entry *logrus.Entry) error {
    entry.Data["id"] = hook.id
    return nil
}

// Levels 日志等级
func (hook *Hook) Levels() []logrus.Level {
    return logrus.AllLevels
}

// Logrus 演示了一些基本的logrus库操作
func Logrus() {

    logrus.SetFormatter(&logrus.TextFormatter{})
    logrus.SetLevel(logrus.InfoLevel)
    logrus.AddHook(&Hook{"123"})

    fields := logrus.Fields{}
    fields["success"] = true
    fields["complex_struct"] = struct {
        Event string
        When  string
    }{"Something happened", "Just now"}

    x := logrus.WithFields(fields)
    x.Warn("warning!")
    x.Error("error!")
}

建立apex.go:

package structured

import (
    "errors"
    "os"

    "github.com/apex/log"
    "github.com/apex/log/handlers/text"
)

// ThrowError抛出我们将追踪的错误
func ThrowError() error {
    err := errors.New("a crazy failure")
    log.WithField("id", "123").Trace("ThrowError").Stop(&err)
    return err
}

type CustomHandler struct {
    id      string
    handler log.Handler
}

// HandleLog 会对日志进行处理
func (h *CustomHandler) HandleLog(e *log.Entry) error {
    e.WithField("id", h.id)
    return h.handler.HandleLog(e)
}

func Apex() {
    log.SetHandler(&CustomHandler{"123", text.New(os.Stdout)})
    err := ThrowError()

    //WithError可以便利的记录错误
    log.WithError(err).Error("an error occurred")
}

建立main.go:

package main

import (
    "fmt"

    "github.com/agtorre/go-cookbook/chapter4/structured"
)

func main() {
    fmt.Println("Logrus:")
    structured.Logrus()

    fmt.Println()
    fmt.Println("Apex:")
    structured.Apex()
}

这会输出:

Logrus:
WARN[0000] warning! complex_struct={Something happened Just now}
id=123 success=true
ERRO[0000] error! complex_struct={Something happened Just now}
id=123 success=true
Apex:
INFO[0000] ThrowError id=123
ERROR[0000] ThrowError duration=133ns error=a crazy failure
id=123
ERROR[0000] an error occurred error=a crazy failure

说明

sirupsen/logrus和apex/log包都是优秀的结构化日志库。二者都提供了用于发送到多个事件或向日志条目添加额外字段的处理方案。其中使用logrus为日志和服务名称添加行号将相对简单。这方便了跨不同服务跟踪日志。