128 lines
2.8 KiB
Go
128 lines
2.8 KiB
Go
package logger
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
|
)
|
|
|
|
var (
|
|
defaultLogger *Logger
|
|
once sync.Once
|
|
)
|
|
|
|
// Logger wraps the standard log.Logger with file and stdout output
|
|
type Logger struct {
|
|
*log.Logger
|
|
fileWriter io.WriteCloser
|
|
}
|
|
|
|
// Init initializes the default logger with both file and stdout output
|
|
func Init(logDir, logFileName string, maxSizeMB int, maxBackups int, maxAgeDays int) error {
|
|
var err error
|
|
once.Do(func() {
|
|
defaultLogger, err = New(logDir, logFileName, maxSizeMB, maxBackups, maxAgeDays)
|
|
if err != nil {
|
|
return
|
|
}
|
|
// Replace standard log output with the multi-writer
|
|
multiWriter := io.MultiWriter(os.Stdout, defaultLogger.fileWriter)
|
|
log.SetOutput(multiWriter)
|
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
|
})
|
|
return err
|
|
}
|
|
|
|
// New creates a new logger that writes to both stdout and a log file
|
|
func New(logDir, logFileName string, maxSizeMB int, maxBackups int, maxAgeDays int) (*Logger, error) {
|
|
// Ensure log directory exists
|
|
if err := os.MkdirAll(logDir, 0755); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logPath := filepath.Join(logDir, logFileName)
|
|
|
|
// Create file writer with rotation
|
|
fileWriter := &lumberjack.Logger{
|
|
Filename: logPath,
|
|
MaxSize: maxSizeMB, // megabytes
|
|
MaxBackups: maxBackups, // number of backup files
|
|
MaxAge: maxAgeDays, // days
|
|
Compress: true, // compress old log files
|
|
}
|
|
|
|
// Create multi-writer that writes to both stdout and file
|
|
multiWriter := io.MultiWriter(os.Stdout, fileWriter)
|
|
|
|
// Create logger with standard flags
|
|
logger := log.New(multiWriter, "", log.LstdFlags|log.Lshortfile)
|
|
|
|
return &Logger{
|
|
Logger: logger,
|
|
fileWriter: fileWriter,
|
|
}, nil
|
|
}
|
|
|
|
// Close closes the file writer
|
|
func (l *Logger) Close() error {
|
|
if l.fileWriter != nil {
|
|
return l.fileWriter.Close()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetDefault returns the default logger instance
|
|
func GetDefault() *Logger {
|
|
return defaultLogger
|
|
}
|
|
|
|
// Printf logs a formatted message
|
|
func Printf(format string, v ...interface{}) {
|
|
if defaultLogger != nil {
|
|
defaultLogger.Printf(format, v...)
|
|
} else {
|
|
log.Printf(format, v...)
|
|
}
|
|
}
|
|
|
|
// Print logs a message
|
|
func Print(v ...interface{}) {
|
|
if defaultLogger != nil {
|
|
defaultLogger.Print(v...)
|
|
} else {
|
|
log.Print(v...)
|
|
}
|
|
}
|
|
|
|
// Println logs a message with newline
|
|
func Println(v ...interface{}) {
|
|
if defaultLogger != nil {
|
|
defaultLogger.Println(v...)
|
|
} else {
|
|
log.Println(v...)
|
|
}
|
|
}
|
|
|
|
// Fatal logs a message and exits
|
|
func Fatal(v ...interface{}) {
|
|
if defaultLogger != nil {
|
|
defaultLogger.Fatal(v...)
|
|
} else {
|
|
log.Fatal(v...)
|
|
}
|
|
}
|
|
|
|
// Fatalf logs a formatted message and exits
|
|
func Fatalf(format string, v ...interface{}) {
|
|
if defaultLogger != nil {
|
|
defaultLogger.Fatalf(format, v...)
|
|
} else {
|
|
log.Fatalf(format, v...)
|
|
}
|
|
}
|
|
|