From 8c9d725eebb30f438ec723ed443b0b51c44c1b67 Mon Sep 17 00:00:00 2001 From: Nuno Diegues Date: Sun, 17 Jan 2021 20:31:41 +0000 Subject: [PATCH] TUN-3768: Reuse file loggers This change is focused on fixing rotating loggers in Windows where it was failing due to Windows file semantics disallowing the rotation while that file was still being open (because we had multiple lumberjacks pointing to the same file). This is fixed by ensuring the initialization happens only once. --- logger/create.go | 65 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/logger/create.go b/logger/create.go index 7d8ff933..fe678a7d 100644 --- a/logger/create.go +++ b/logger/create.go @@ -6,6 +6,7 @@ import ( "os" "path" "path/filepath" + "sync" "github.com/mattn/go-colorable" "github.com/rs/zerolog" @@ -143,23 +144,40 @@ func createConsoleLogger(config ConsoleConfig) io.Writer { } } +type fileInitializer struct { + once sync.Once + writer io.Writer + creationError error +} + +var ( + singleFileInit fileInitializer + rotatingFileInit fileInitializer +) + func createFileWriter(config FileConfig) (io.Writer, error) { - var logFile io.Writer - fullpath := config.Fullpath() + singleFileInit.once.Do(func() { - // Try to open the existing file - logFile, err := os.OpenFile(fullpath, os.O_APPEND|os.O_WRONLY, filePermMode) - if err != nil { - // If the existing file wasn't found, or couldn't be opened, just ignore - // it and recreate a new one. - logFile, err = createDirFile(config) - // If creating a new logfile fails, then we have no choice but to error out. + var logFile io.Writer + fullpath := config.Fullpath() + + // Try to open the existing file + logFile, err := os.OpenFile(fullpath, os.O_APPEND|os.O_WRONLY, filePermMode) if err != nil { - return nil, err + // If the existing file wasn't found, or couldn't be opened, just ignore + // it and recreate a new one. + logFile, err = createDirFile(config) + // If creating a new logfile fails, then we have no choice but to error out. + if err != nil { + singleFileInit.creationError = err + return + } } - } - return logFile, nil + singleFileInit.writer = logFile + }) + + return singleFileInit.writer, singleFileInit.creationError } func createDirFile(config FileConfig) (io.Writer, error) { @@ -183,14 +201,19 @@ func createDirFile(config FileConfig) (io.Writer, error) { } func createRollingLogger(config RollingConfig) (io.Writer, error) { - if err := os.MkdirAll(config.Dirname, dirPermMode); err != nil { - return nil, err - } + rotatingFileInit.once.Do(func() { + if err := os.MkdirAll(config.Dirname, dirPermMode); err != nil { + rotatingFileInit.creationError = err + return + } - return &lumberjack.Logger{ - Filename: path.Join(config.Dirname, config.Filename), - MaxBackups: config.maxBackups, - MaxSize: config.maxSize, - MaxAge: config.maxAge, - }, nil + rotatingFileInit.writer = &lumberjack.Logger{ + Filename: path.Join(config.Dirname, config.Filename), + MaxBackups: config.maxBackups, + MaxSize: config.maxSize, + MaxAge: config.maxAge, + } + }) + + return rotatingFileInit.writer, rotatingFileInit.creationError }