zerolog
zerolog copied to clipboard
ConsoleWriter fails when used with other writers
I'm currently trying to use consolewriter along with filewriter and journalwriter.
Below is my configuration code
// ConfigLogger contains Configuration for logging
type ConfigLogger struct {
// Enable console logging
ConsoleLoggingEnabled bool
// EncodeLogsAsJson makes the log framework log JSON
EncodeLogsAsJson bool
// FileLoggingEnabled makes the framework log to a file
// the fields below can be skipped if this value is false!
FileLoggingEnabled bool
// JournalLoggingEnabled makes the framework log to systemd-journald
JournalLoggingEnabled bool
// Directory to log to to when filelogging is enabled
Directory string
// Filename is the name of the logfile which will be placed inside the directory
Filename string
// MaxSize the max size in MB of the logfile before it's rolled
MaxSize int
// MaxBackups the max number of rolled files to keep
MaxBackups int
// MaxAge the max age in days to keep a logfile
MaxAge int
}
func newRollingFile(config ConfigLogger) io.Writer {
if err := os.MkdirAll(config.Directory, 0744); err != nil {
log.Error().Err(err).Str("path", config.Directory).Msg("can't create log directory")
return nil
}
return &lumberjack.Logger{
Filename: path.Join(config.Directory, config.Filename),
MaxBackups: config.MaxBackups, // files
MaxSize: config.MaxSize, // megabytes
MaxAge: config.MaxAge, // days
}
}
//ConfigureLogger updates opeion on logger
func ConfigureLogger(config ConfigLogger) zerolog.Logger {
var writers []io.Writer
zerolog.SetGlobalLevel(zerolog.DebugLevel)
if config.ConsoleLoggingEnabled {
writers = append(writers, zerolog.ConsoleWriter{Out: os.Stdout, NoColor: false})
}
if config.FileLoggingEnabled {
writers = append(writers, newRollingFile(config))
}
if config.JournalLoggingEnabled {
writers = append(writers, journald.NewJournalDWriter())
}
mw := io.MultiWriter(writers...)
zerolog.MessageFieldName = "msg"
hostname, err := os.Hostname()
if err != nil {
panic("Unable to get hostname of the system")
}
logger := zerolog.
New(mw).
With().
Int("pid", os.Getpid()).
Int("v", 0).
Str("hostname", hostname).
Str("name", "hio:vm:manager").
Caller().
Timestamp().
Logger().
Hook(BunyanHook{})
logger.Info().
Bool("fileLogging", config.FileLoggingEnabled).
Bool("jsonLogOutput", config.EncodeLogsAsJson).
Str("logDirectory", config.Directory).
Str("fileName", config.Filename).
Int("maxSizeMB", config.MaxSize).
Int("maxBackups", config.MaxBackups).
Int("maxAgeInDays", config.MaxAge).
Msg("logging configured")
return logger
}
Invocation is done
conf := utilities.ConfigLogger{
ConsoleLoggingEnabled: true,
EncodeLogsAsJson: true,
FileLoggingEnabled: true,
JournalLoggingEnabled: true,
Directory: "/var/log/",
Filename: filename,
MaxSize: 100,
MaxBackups: 2,
MaxAge: 7,
}
log.Logger = utilities.ConfigureLogger(conf)
But when I run application, I get
panic: runtime error: slice bounds out of range [:3] with length 2
goroutine 1 [running]:
github.com/rs/zerolog.consoleDefaultFormatLevel.func1(0x9edb40, 0xc0000998d0, 0xa84176, 0x5)
/workspace/pkg/mod/github.com/rs/[email protected]/console.go:357 +0x49e
github.com/rs/zerolog.ConsoleWriter.writePart(0xb2c360, 0xc0000bc008, 0x0, 0x0, 0x0, 0xc0000dc400, 0x4, 0x4, 0x0, 0x0, ...)
/workspace/pkg/mod/github.com/rs/[email protected]/console.go:256 +0x156
github.com/rs/zerolog.ConsoleWriter.Write(0xb2c360, 0xc0000bc008, 0x0, 0x0, 0x0, 0xc0000dc400, 0x4, 0x4, 0x0, 0x0, ...)
/workspace/pkg/mod/github.com/rs/[email protected]/console.go:111 +0x285
io.(*multiWriter).Write(0xc0000b02a0, 0xc0001b8c00, 0x175, 0x1f4, 0x158, 0x1f4, 0x19)
/usr/local/go/src/io/multi.go:60 +0x87
github.com/rs/zerolog.levelWriterAdapter.WriteLevel(...)
/workspace/pkg/mod/github.com/rs/[email protected]/writer.go:20
github.com/rs/zerolog.(*Event).write(0xc0000be660, 0x160, 0x1f4)
/workspace/pkg/mod/github.com/rs/[email protected]/event.go:78 +0x125
github.com/rs/zerolog.(*Event).msg(0xc0000be660, 0xa8a50a, 0x12)
/workspace/pkg/mod/github.com/rs/[email protected]/event.go:142 +0x21b
github.com/rs/zerolog.(*Event).Msg(...)
/workspace/pkg/mod/github.com/rs/[email protected]/event.go:108
hive-vm-manager/utilities.Configure(0x1010101, 0xa85922, 0x9, 0xa93be7, 0x23, 0x64, 0x2, 0x7, 0x0, 0x0, ...)
/workspaces/hive-vm-manager/utilities/logger.go:92 +0x9c5
hive-vm-manager/hio-vm-manager-cmd/cmd.InitLoggerConfig(0xa93be7, 0x23)
/workspaces/hive-vm-manager/hio-vm-manager-cmd/cmd/common.go:21 +0xc6
hive-vm-manager/hio-vm-manager-cmd/cmd.init.0()
/workspaces/hive-vm-manager/hio-vm-manager-cmd/cmd/correctoldmetadata.go:62 +0x77
What am I missing? I tried setting NoColor option to both true and false. Since the LogLevel is set using SetGlobalLogLevel func call, do I need to anything specific for consolewriter?
@rs ,
Any thoughts/suggestions? If this is not the right place to ask questions, can you please let me know what platform is used for queries?
@GaikwadPratik , Have you tried zerolog.MultiLevelWriter instead of io.MultiWriter?
https://github.com/rs/zerolog#multiple-log-output
@thaney071 ,
Thank you for suggestion. I tried that. No it didn't work. It failed with same error as soon as enabled ConsoleLogging. Any other suggestion?
In my case, the problem was that I was passing a field named "level". Renaming it solved the issue.
@kamushadenes,
I think that is also case with me. bunyan hook needs level and that's when ConsoleWriter breaks down.
Because in case of bunyan, the hook is as follows:
type BunyanHook struct{}
func (b BunyanHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
blevel := 10
switch level {
case zerolog.FatalLevel:
blevel = 60
case zerolog.ErrorLevel:
blevel = 50
case zerolog.WarnLevel:
blevel = 40
case zerolog.InfoLevel:
blevel = 30
case zerolog.DebugLevel:
blevel = 20
case zerolog.TraceLevel:
default:
blevel = 10
}
e.Int("level", blevel)
}
and then as indicated in original post, it is added to logger as
.....
Logger().
Hook(BunyanHook{})
Also bunyan expects level to be an int whereas zerolog.console expects it as string with at min 3 characters.
The only option I could find was to write my own Formatter for console writer and use colorize functionality from zero log. I wish that would've been public. but alas, not everything is easy, yet