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.
This commit is contained in:
Nuno Diegues 2021-01-17 20:31:41 +00:00
parent de27361ffa
commit 8c9d725eeb
1 changed files with 44 additions and 21 deletions

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"sync"
"github.com/mattn/go-colorable" "github.com/mattn/go-colorable"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -143,7 +144,20 @@ 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) { func createFileWriter(config FileConfig) (io.Writer, error) {
singleFileInit.once.Do(func() {
var logFile io.Writer var logFile io.Writer
fullpath := config.Fullpath() fullpath := config.Fullpath()
@ -155,11 +169,15 @@ func createFileWriter(config FileConfig) (io.Writer, error) {
logFile, err = createDirFile(config) logFile, err = createDirFile(config)
// If creating a new logfile fails, then we have no choice but to error out. // If creating a new logfile fails, then we have no choice but to error out.
if err != nil { if err != nil {
return nil, err singleFileInit.creationError = err
return
} }
} }
return logFile, nil singleFileInit.writer = logFile
})
return singleFileInit.writer, singleFileInit.creationError
} }
func createDirFile(config FileConfig) (io.Writer, error) { 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) { func createRollingLogger(config RollingConfig) (io.Writer, error) {
rotatingFileInit.once.Do(func() {
if err := os.MkdirAll(config.Dirname, dirPermMode); err != nil { if err := os.MkdirAll(config.Dirname, dirPermMode); err != nil {
return nil, err rotatingFileInit.creationError = err
return
} }
return &lumberjack.Logger{ rotatingFileInit.writer = &lumberjack.Logger{
Filename: path.Join(config.Dirname, config.Filename), Filename: path.Join(config.Dirname, config.Filename),
MaxBackups: config.maxBackups, MaxBackups: config.maxBackups,
MaxSize: config.maxSize, MaxSize: config.maxSize,
MaxAge: config.maxAge, MaxAge: config.maxAge,
}, nil }
})
return rotatingFileInit.writer, rotatingFileInit.creationError
} }