Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add zapcore.NewMultiWriteSyncer in zap.Config using golang zap log project

Tags:

go

go-zap

I am working on a log package and hope to configure whether to use log rotation through switches.

Previous code did not support log rotate

// using zap.Config and cannot log rotate

// Build constructs a global zap logger from the Config and Options.
func (o *Options) Build() error {
    var zapLevel zapcore.Level
    if err := zapLevel.UnmarshalText([]byte(o.Level)); err != nil {
        zapLevel = zapcore.InfoLevel
    }
    encodeLevel := zapcore.CapitalLevelEncoder
    if o.Format == consoleFormat && o.EnableColor {
        encodeLevel = zapcore.CapitalColorLevelEncoder
    }

    zc := &zap.Config{
        Level:             zap.NewAtomicLevelAt(zapLevel),
        Development:       o.Development,
        DisableCaller:     o.DisableCaller,
        DisableStacktrace: o.DisableStacktrace,
        Sampling: &zap.SamplingConfig{
            Initial:    100,
            Thereafter: 100,
        },
        Encoding: o.Format,
        EncoderConfig: zapcore.EncoderConfig{
            MessageKey:     "message",
            LevelKey:       "level",
            TimeKey:        "timestamp",
            NameKey:        "logger",
            CallerKey:      "caller",
            StacktraceKey:  "stacktrace",
            LineEnding:     zapcore.DefaultLineEnding,
            EncodeLevel:    encodeLevel,
            EncodeTime:     timeEncoder,
            EncodeDuration: milliSecondsDurationEncoder,
            EncodeCaller:   zapcore.ShortCallerEncoder,
            EncodeName:     zapcore.FullNameEncoder,
        },
        OutputPaths:      o.OutputPaths,
        ErrorOutputPaths: o.ErrorOutputPaths,
    }
    
    logger, err := zc.Build(zap.AddStacktrace(zapcore.PanicLevel))
    if err != nil {
        return err
    }
    zap.RedirectStdLog(logger.Named(o.Name))
    zap.ReplaceGlobals(logger)

    return nil
}

Now I hope to support rotation. I checked the relevant information and found that it can be rotated in the following way

//   logrotate.log
syncer :=zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger))   
// lumberJackLogger encapsulate lumberjack.Logger

core := zapcore.NewCore(
        zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
        syncer,
        logLevel,
    )
logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))

I hope to change OutputPaths and ErrorOutputPaths into the form of logrorate.go when starting rotation based on config.

Just like the following pseudo code

if ! o.EnableRorate
  zap.Config{...OutputPaths,ErrorOutputPaths}
else
   zap.config add zapcore.NewMultiWriteSyncer

Please tell me what I need to do to achieve my expectations. Looking forward to your reply

PS: I hope that other configurations besides o.OutputPaths and o.ErrorOutputPaths can still be used under the new solution.

like image 800
moluzhui Avatar asked Dec 29 '25 21:12

moluzhui


1 Answers

It seems to be a weird mix of concerns having a logger package do log rotation. The life cycle of an app is almost always less than the life cycle of log files on disk, and logging to disk is just one of many logger outputs. Take a look at zap.Sink. Nowhere is a file even remotely implied, it's basically just an io.Writer.

If you're not in control over the machine on which your app runs, then ask your platform person to introduce logrotate to the system. This is a pretty stable tool from the 80s, still active and used all over the place. It will allow you to write, care-free from zap, and let logrotate care about size/lines/whatever.

It could be that we have different interpretations of what "log rotation" means, and I have interpreted it to be a constraint on log file size, and some archival function (logrotate gzips by default). If this differs from your interpretation, then forgive me.

like image 109
Jonas G. Drange Avatar answered Dec 31 '25 19:12

Jonas G. Drange



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!