package log import ( "context" "io" "log/slog" "os" "strings" "sync" "sync/atomic" "gopkg.in/natefinch/lumberjack.v2" "zestack.dev/env" "zestack.dev/slim" ) var defaultLogger atomic.Pointer[slim.Logger] var loggers sync.Map func Init(_ context.Context) error { l := slim.NewLogger(&slim.LoggerOptions{ Output: os.Stderr, AddSource: env.Bool("LOG_ADD_SOURCE", false), Level: slog.Level(env.Int("LOG_LEVEL", 0)), NewHandler: func(w io.Writer, opts *slog.HandlerOptions) slog.Handler { return NewMultiHandler( NewTextHandler(w, opts), slog.NewJSONHandler(&lumberjack.Logger{ Filename: env.Path("storage/logs/default.log"), // MaxSize: env.Int("LOG_MAX_SIZE", 500), // megabytes MaxBackups: env.Int("LOG_MAX_BACKUPS", 3), // MaxAge: env.Int("LOG_MAX_AGE", 28), // days Compress: env.Bool("LOG_COMPRESS", true), // enabled by default }, opts), ) }, }) slog.SetDefault(l.Logger) defaultLogger.Store(l) return nil } func Channel(name string) *slim.Logger { if name != "default" && name != "" { return Default() } if l, ok := loggers.Load(name); ok { return l.(*slim.Logger) } s := env.Signed("LOG", strings.ToUpper(name)) l := slim.NewLogger(&slim.LoggerOptions{ Output: &lumberjack.Logger{ Filename: env.Path("storage/logs/" + name + ".log"), MaxSize: s.Int("MAX_SIZE", 500), // megabytes MaxBackups: s.Int("MAX_BACKUPS", 3), MaxAge: s.Int("MAX_AGE", 28), // days Compress: s.Bool("COMPRESS", true), // enabled by default }, AddSource: s.Bool("ADD_SOURCE", false), Level: slog.Level(s.Int("LEVEL", 0)), NewHandler: func(w io.Writer, opts *slog.HandlerOptions) slog.Handler { return slog.NewJSONHandler(w, opts) }, }) loggers.Store(name, l) return l } func Default() *slim.Logger { return defaultLogger.Load() } func With(args ...any) *slim.Logger { return Default().With(args...) } func WithGroup(name string) *slim.Logger { return Default().WithGroup(name) } func Debug(msg string, args ...any) { Default().Debug(msg, args...) } func Info(msg string, args ...any) { Default().Info(msg, args...) } func Warn(msg string, args ...any) { Default().Warn(msg, args...) } func Error(msg string, args ...any) { Default().Error(msg, args...) }