Go语言 如何使用zerolog将INFO日志过滤为stdout,将ERROR日志过滤为stderr?

2vuwiymt  于 2023-09-28  发布在  Go
关注(0)|答案(2)|浏览(109)

我使用zerolog进行 Go 日志记录:

zerolog.SetGlobalLevel(zerolog.InfoLevel)
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "15:04:05"})

这会将所有消息打印到os.Stderr中,但我希望将日志拆分为多个输出,并满足以下条件:
DebugLevelInfoLevelWarnLevel将被打印到os.Stdout
ErrorLevelFatalLevelPanicLevel将打印到os.Stderr
我怎么才能做到这一点?

x6492ojm

x6492ojm1#

你可以实现LevelWriter。例如(playground):

var (
    // Using different time formats to make it clear which logger is being used
    debugOut = zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC1123} // time format: "Mon, 02 Jan 2006 15:04:05 MST"
    errorOut = zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339} // time format: "2006-01-02T15:04:05Z07:00"
)

// logOut implements zerolog.LevelWriter
type logOut struct{}

// Write should not be called
func (l logOut) Write(p []byte) (n int, err error) {
    return os.Stdout.Write(p)
}

// WriteLevel write to the appropriate output
func (l logOut) WriteLevel(level zerolog.Level, p []byte) (n int, err error) {
    if level <= zerolog.WarnLevel {
        return debugOut.Write(p)
    } else {
        return errorOut.Write(p)
    }
}

func main() {
    logger := zerolog.New(logOut{}).With().Timestamp().Logger()

    logger.Info().Str("foo", "bar").Msg("Info")   // Output: "Tue, 08 Aug 2023 22:12:31 NZST INF Info foo=bar"
    logger.Error().Str("foo", "bar").Msg("Error") // Output: "2023-08-08T22:12:31+12:00 ERR Error foo=bar"
}
ujv3wf0j

ujv3wf0j2#

你需要使用MultiLevelWriter,将日志转发到多个LevelWriter s输出(虽然它不在函数签名中,但你应该给予它LevelWriter s,否则它不会做任何特殊的逻辑)。
LevelWriterio.WriterWriteLevel(level Level, p []byte) (n int, err error)的接口,因此您可以添加所需的任何zerolog写入器(因为它是io.Writer),并在WriteLevel上使用级别条件。
下面是一个LevelWriter的例子:

type SpecificLevelWriter struct {
    io.Writer
    Levels []zerolog.Level
}

func (w SpecificLevelWriter) WriteLevel(level zerolog.Level, p []byte) (int, error) {
    for _, l := range w.Levels {
        if l == level {
            return w.Write(p)
        }
    }
    return len(p), nil
}

现在你需要在MultiLevelWriter中使用它两次:

func CreateLogger() zerolog.Logger {
    writer := zerolog.MultiLevelWriter(
        SpecificLevelWriter{
            Writer: zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "15:04:05"},
            Levels: []zerolog.Level{
                zerolog.DebugLevel, zerolog.InfoLevel, zerolog.WarnLevel,
            },
        },
        SpecificLevelWriter{
            Writer: zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "15:04:05"},
            Levels: []zerolog.Level{
                zerolog.ErrorLevel, zerolog.FatalLevel, zerolog.PanicLevel,
            },
        },
    )

    return zerolog.New(writer).Logger()
}

请注意,正如我所说,zerologs记录器是io.Writer,您可以将os.Stdout替换为zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "15:04:05"}

相关问题