123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- package logger
- import (
- "context"
- "errors"
- "fmt"
- "log/slog"
- "os"
- "sync"
- )
- type CtxAttrKey struct{}
- var (
- once sync.Once
- ctxAttrMu sync.RWMutex
- logger *Logger
- )
- type Logger struct {
- config Config
- logFile *os.File
- stdoutLogger *slog.Logger
- fileLogger *slog.Logger
- emailLogger *slog.Logger
- }
- func Init(c Config) error {
- var err error
- once.Do(func() {
- logger = &Logger{config: c}
- if c.stdoutLogEnabled {
- logger.stdoutLogger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
- Level: c.stdoutLogLevel,
- }))
- }
- if c.fileLogEnabled {
- logger.logFile, err = os.OpenFile(c.filepath, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0644)
- if err != nil {
- return
- }
- logger.fileLogger = slog.New(slog.NewJSONHandler(logger.logFile, &slog.HandlerOptions{
- Level: c.fileLogLevel,
- }))
- }
- if c.emailLogEnabled {
- if c.smtpClient == nil {
- err = errors.New("empty SMTP client")
- return
- }
- ew, ewErr := NewEmailWriter(c.smtpClient, c.emailRecipient, c.emailSubject)
- if ewErr != nil {
- err = ewErr
- return
- }
- logger.emailLogger = slog.New(slog.NewJSONHandler(ew, &slog.HandlerOptions{
- Level: c.emailLogLevel,
- }))
- }
- })
- return err
- }
- func Default() *Logger {
- if logger == nil {
- logger = &Logger{}
- }
- return logger
- }
- func ErrorKV(ctx context.Context, msg string, args ...any) {
- log(ctx, slog.LevelError, msg, args...)
- }
- func WarnKV(ctx context.Context, msg string, args ...any) {
- log(ctx, slog.LevelWarn, msg, args...)
- }
- func InfoKV(ctx context.Context, msg string, args ...any) {
- log(ctx, slog.LevelInfo, msg, args...)
- }
- func DebugKV(ctx context.Context, msg string, args ...any) {
- log(ctx, slog.LevelDebug, msg, args...)
- }
- func Errorf(ctx context.Context, format string, args ...any) {
- log(ctx, slog.LevelError, fmt.Sprintf(format, args...))
- }
- func Warnf(ctx context.Context, format string, args ...any) {
- log(ctx, slog.LevelWarn, fmt.Sprintf(format, args...))
- }
- func Infof(ctx context.Context, format string, args ...any) {
- log(ctx, slog.LevelInfo, fmt.Sprintf(format, args...))
- }
- func Debugf(ctx context.Context, format string, args ...any) {
- log(ctx, slog.LevelDebug, fmt.Sprintf(format, args...))
- }
- func Error(ctx context.Context, msg string) {
- log(ctx, slog.LevelError, msg)
- }
- func Warn(ctx context.Context, msg string) {
- log(ctx, slog.LevelWarn, msg)
- }
- func Info(ctx context.Context, msg string) {
- log(ctx, slog.LevelInfo, msg)
- }
- func Debug(ctx context.Context, msg string) {
- log(ctx, slog.LevelDebug, msg)
- }
- func log(ctx context.Context, level slog.Level, msg string, args ...any) {
- if Default().stdoutLogger != nil {
- Default().stdoutLogger.Log(ctx, level, msg, append(args, AttrFromCtx(ctx)...)...)
- }
- if Default().fileLogger != nil {
- Default().fileLogger.Log(ctx, level, msg, append(args, AttrFromCtx(ctx)...)...)
- }
- if Default().emailLogger != nil {
- Default().emailLogger.Log(ctx, level, msg, append(args, AttrFromCtx(ctx)...)...)
- }
- }
- func Close() error {
- if Default().logFile != nil {
- if err := Default().logFile.Close(); err != nil {
- return err
- }
- }
- return nil
- }
|