Tools
- lumberjeack is the primary tool we will be using
- (optional)zerolog package providing logger interface
Implementation with log package
Normal log package is okay if you're looking for something simple yet effective.
We create multiwriter io so that we can see output in the stdout and at the same time have the writer write to .log
file.
As you can see we created the file writer with the lumberjack package where we defined a few variables.
Filename
- takes the full path. It uses -lumberjack.log in os.TempDir() if you do not set it.
MaxSize
- maximum size in megabytes of the log file before it gets rotated
MaxBackups
- maximum number of old log files to retain
MaxAge
- maximum number of days to retain old log files based on the timestamp encoded in their filename
Compress
- determines if we compress the rotated log files with gzip
package logger import ( "fmt" "io" "log" "os" "path/filepath" "gopkg.in/natefinch/lumberjack.v2" ) func New(logPath string) (*log.Logger, error) { if err := os.MkdirAll(filepath.Dir(logPath), 0755); err != nil { return nil, fmt.Errorf("create log directory: %w", err) } fileWriter := &lumberjack.Logger{ Filename: logPath, MaxSize: 10, // megabytes MaxBackups: 5, // number of backups to keep MaxAge: 30, // days Compress: true, // compress old logs } // Create a multi-writer that writes to both stdout and the file var writers []io.Writer writers = append(writers, os.Stdout) writers = append(writers, fileWriter) multiWriter := io.MultiWriter(writers...) logger := log.New(multiWriter, "", log.LstdFlags|log.Lshortfile) return logger, nil }
Implementation with zerolog package
Same implementation but more powerful - here we can defined if we're debugging the application and change the level that zerolog is sending the logs through. In this example we have base level of info and debug level (if active) of trace.
package logger import ( "fmt" "os" "path/filepath" "github.com/rs/zerolog" "gopkg.in/natefinch/lumberjack.v2" ) func New(isDebug bool, logPath string) (*zerolog.Logger, error) { logLevel := zerolog.InfoLevel if isDebug { logLevel = zerolog.TraceLevel } if err := os.MkdirAll(filepath.Dir(logPath), 0755); err != nil { return nil, fmt.Errorf("create log directory: %w", err) } fileWriter := &lumberjack.Logger{ Filename: logPath, MaxSize: 10, // megabytes MaxBackups: 5, // number of backups to keep MaxAge: 30, // days Compress: true, // compress old logs } zerolog.SetGlobalLevel(logLevel) multi := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stdout}, fileWriter) logger := zerolog.New(multi).With().Timestamp().Logger() return &logger, nil }
That is it!
Pretty simple and very effective!
If you have very large logs with an application I suggest you give it a try!
Top comments (0)