Add a prefix to zap logger for all message

541 views Asked by At

I had set up the zap logger with the following configuration

       outLevel := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
        return level < zapcore.WarnLevel
    })

    // Warnings and everything above will be printed to stderr
    errorLevel := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
        return level >= zapcore.WarnLevel
    })

    stdoutSyncer := zapcore.Lock(os.Stdout)
    stderrSyncer := zapcore.Lock(os.Stderr)

    config := zap.NewDevelopmentConfig()
    config.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
    config.EncoderConfig.TimeKey = ""

    core := zapcore.NewTee(
        zapcore.NewCore(
            zapcore.NewConsoleEncoder(config.EncoderConfig),
            stdoutSyncer,
            outLevel,
        ),
        zapcore.NewCore(
            zapcore.NewConsoleEncoder(config.EncoderConfig),
            stderrSyncer,
            errorLevel,
        ),
    )

    logger := zap.New(core)

    zap.ReplaceGlobals(logger)

Help me understand if is it possible to prepend a prefix to every log message (DEBUG, INFO) something like what log library provides https://pkg.go.dev/log#SetPrefix

zap.L().Info("this is new message") 

and the prefix is "=>"

The final log line would appear like this

"=> this is new message"

I tried with log.With api but it seem to create a new json object which is different from what I need.

1

There are 1 answers

0
toozyfuzzy On

The simplest way to achieve this i can think of is to just wrap the Writer that zapcore uses. Here's how:

type PrefixWriter struct {
    prefix   []byte
    writer   io.Writer
    // buffer to cache the slice to not allocate memory each call
    wrBuffer bytes.Buffer 
}

func NewPrefixWriter(prefix string, w io.Writer) *PrefixWriter {
    return &PrefixWriter{
        prefix: []byte(prefix + " "),
        writer: w,
    }
}

func (w *PrefixWriter) Write(p []byte) (n int, err error) {
    w.wrBuffer.Reset()
    w.wrBuffer.Write(w.prefix)
    w.wrBuffer.Write(p)
    return w.writer.Write(w.wrBuffer.Bytes())
}

func logInit(d bool, f *os.File) *zap.SugaredLogger {
    pe := zap.NewProductionEncoderConfig()

    // Create our custom writers
    prefix := "[MY_APP]"
    fileWriter := NewPrefixWriter(prefix, f)
    consoleWriter := NewPrefixWriter(prefix, os.Stdout)

    pe.EncodeLevel = zapcore.CapitalColorLevelEncoder

    encoder := zapcore.NewConsoleEncoder(pe)

    level := zap.InfoLevel
    if d {
        level = zap.DebugLevel
    }

    core := zapcore.NewTee(
        // Add custom writers to zapcore
        zapcore.NewCore(encoder, zapcore.AddSync(fileWriter), level),
        zapcore.NewCore(encoder, zapcore.AddSync(consoleWriter), level),
    )

    l := zap.New(core)

    return l.Sugar()
}