【问题标题】:How to use Sentry with go.uber.org/zap/zapcore logger如何将 Sentry 与 go.uber.org/zap/zapcore 记录器一起使用
【发布时间】:2021-02-24 07:14:45
【问题描述】:

我正在使用 go.uber.org/zap/zapcore 登录我的 Go 应用程序。

package logger

import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "log"
)

var l *zap.Logger

func Get() *zap.Logger {
    return l
}

func Init() {
    conf := zap.NewProductionConfig()

    logger, err := conf.Build()
    if err != nil {
        log.Fatal("Init logger failed", err)
    }
    l = logger
}

我也有哨兵项目并使用github.com/getsentry/raven-go

我想将error及以上级别的日志发送给Sentry。

例如,当使用logger.Info()info 级别登录时,我只想像往常一样记录它们,但在errorfatal 日志的情况下,我需要将这些消息发送到Sentry。我怎样才能做到这一点?

【问题讨论】:

  • github.com/getsentry/raven-go 已过时,不应再用于新项目。而是使用the new Sentry SDK
  • 好的,我已经更改了库,但我的问题与它无关
  • @Viktor 可能是因为 Init() 应该是 init()

标签: go logging sentry go-zap


【解决方案1】:

以下将捕获消息并在检测到错误级别时将其发送给哨兵,并带有自定义的错误行号和消息。

err := sentry.Init(sentry.ClientOptions{Dsn: "http://~~~~~"})
if err != nil {
    log.fatal("Sentry Error Setup ::", err.Error())
}

logger, _ := zap.NewDevelopment(zap.Hooks(func(entry zapcore.Entry) error {
    if entry.Level == zapcore.ErrorLevel {
        defer sentry.Flush(2 * time.Second)
        sentry.CaptureMessage(fmt.Sprintf("%s, Line No: %d :: %s", entry.Caller.File, entry.Caller.Line, entry.Message))
    }
    return nil
}))

sugar := logger.Sugar()

【讨论】:

    【解决方案2】:

    答案是你应该使用 zap wrapper 来添加钩子,然后你必须使用名为 WithOptions 的 logger 函数

    sentryOptions := zap.WrapCore(func(core zapcore.Core) zapcore.Core {
        return zapcore.RegisterHooks(core, func(entry zapcore.Entry) error {
            // your logic here
        })
    })
    
    logger.WithOptions(sentryOptions)
    

    【讨论】: