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:
parent
de27361ffa
commit
8c9d725eeb
|
@ -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,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) {
|
func createFileWriter(config FileConfig) (io.Writer, error) {
|
||||||
var logFile io.Writer
|
singleFileInit.once.Do(func() {
|
||||||
fullpath := config.Fullpath()
|
|
||||||
|
|
||||||
// Try to open the existing file
|
var logFile io.Writer
|
||||||
logFile, err := os.OpenFile(fullpath, os.O_APPEND|os.O_WRONLY, filePermMode)
|
fullpath := config.Fullpath()
|
||||||
if err != nil {
|
|
||||||
// If the existing file wasn't found, or couldn't be opened, just ignore
|
// Try to open the existing file
|
||||||
// it and recreate a new one.
|
logFile, err := os.OpenFile(fullpath, os.O_APPEND|os.O_WRONLY, filePermMode)
|
||||||
logFile, err = createDirFile(config)
|
|
||||||
// If creating a new logfile fails, then we have no choice but to error out.
|
|
||||||
if err != nil {
|
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) {
|
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) {
|
||||||
if err := os.MkdirAll(config.Dirname, dirPermMode); err != nil {
|
rotatingFileInit.once.Do(func() {
|
||||||
return nil, err
|
if err := os.MkdirAll(config.Dirname, dirPermMode); err != nil {
|
||||||
}
|
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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue