niki/pkg/logger/logger.go

85 lines
1.9 KiB
Go

package logger
import (
"io"
"log"
"log/slog"
"os"
"path/filepath"
"sync"
"gopkg.in/natefinch/lumberjack.v2"
)
var globalLogger *slog.Logger
var once sync.Once
type Config struct {
Level string `koanf:"level"`
FilePath string `koanf:"file_path"`
UseLocalTime bool `koanf:"use_local_time"`
FileMaxSizeInMB int `koanf:"file_max_size_in_mb"`
FileMaxAgeInDays int `koanf:"file_max_age_in_days"`
}
// Init initializes the global logger instance.
func Init(cfg Config) {
once.Do(func() {
workingDir, err := os.Getwd()
if err != nil {
log.Fatalf("Error getting current working directory: %v", err)
}
fileWriter := &lumberjack.Logger{
Filename: filepath.Join(workingDir, cfg.FilePath),
LocalTime: cfg.UseLocalTime,
MaxSize: cfg.FileMaxSizeInMB,
MaxAge: cfg.FileMaxAgeInDays,
}
level := mapLevel(cfg.Level)
globalLogger = slog.New(
slog.NewJSONHandler(io.MultiWriter(fileWriter, os.Stdout), &slog.HandlerOptions{
Level: level,
}),
)
})
}
// L returns the global logger instance.
func L() *slog.Logger {
return globalLogger
}
// New creates a new logger instance for each service with specific settings.
func New(cfg Config) *slog.Logger {
workingDir, err := os.Getwd()
if err != nil {
log.Fatalf("Error getting current working directory: %v", err)
}
fileWriter := &lumberjack.Logger{
Filename: filepath.Join(workingDir, cfg.FilePath),
LocalTime: cfg.UseLocalTime,
MaxSize: cfg.FileMaxSizeInMB,
MaxAge: cfg.FileMaxAgeInDays,
}
return slog.New(
slog.NewJSONHandler(io.MultiWriter(fileWriter), &slog.HandlerOptions{}),
)
}
func mapLevel(levelStr string) slog.Level {
switch levelStr {
case "debug":
return slog.LevelDebug
case "info":
return slog.LevelInfo
case "warn":
return slog.LevelWarn
case "error":
return slog.LevelError
default:
return slog.LevelInfo
}
}