evrone / go-clean-template

Clean Architecture template for Golang services
MIT License
6.23k stars 522 forks source link

Log error appear as info #148

Open diogoalbuquerque opened 2 years ago

diogoalbuquerque commented 2 years ago

This project helps me a lot to have a guideline to follow the clean code, so thank you very much. I'm studying go and forgive me if I did something wrong. But when I set the log level to error and after creating the configuration, if I call l.error it always appears as info.

I don't know if there's something here that always turns into info or if I'm doing something wrong.

func (l *Logger) log(message string, args ...interface{}) {
    if len(args) == 0 {
        l.logger.Info().Msg(message)
    } else {
        l.logger.Info().Msgf(message, args...)
    }
}

func (l *Logger) msg(level string, message interface{}, args ...interface{}) {
    switch msg := message.(type) {
    case error:
        l.log(msg.Error(), args...)
    case string:
        l.log(msg, args...)
    default:
        l.log(fmt.Sprintf("%s message %v has unknown type %v", level, message, msg), args...)
    }
}
SebUndefined commented 2 years ago

Hi @diogoalbuquerque,

I use the following. Please note that I switch to the pretty logger in case of debug level.

Edit: I updated with a proper interface name

package logger

import (
    "fmt"
    "os"
    "strings"
    "time"

    "github.com/rs/zerolog"
)

// Logger -.
type Logger interface {
    Debug(message interface{}, args ...interface{})
    Info(message string, args ...interface{})
    Warn(message string, args ...interface{})
    Error(message interface{}, args ...interface{})
    Fatal(message interface{}, args ...interface{})
}

// logger -.
type logger struct {
    logger *zerolog.Logger
}

// New -.
func New(level string) Logger {
    var l zerolog.Level

    switch strings.ToLower(level) {
    case "error":
        l = zerolog.ErrorLevel
        break
    case "warn":
        l = zerolog.WarnLevel
        break
    case "info":
        l = zerolog.InfoLevel
        break
    case "debug":
        l = zerolog.DebugLevel
        break
    default:
        l = zerolog.InfoLevel
        break
    }

    zerolog.SetGlobalLevel(l)
    skipFrameCount := 3
    var z zerolog.Logger
    if l == zerolog.DebugLevel {
        z = zerolog.New(os.Stdout).Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).
            With().
            Timestamp().
            CallerWithSkipFrameCount(zerolog.CallerSkipFrameCount + skipFrameCount).
            Logger()
    } else {
        z = zerolog.New(os.Stdout).
            With().
            Timestamp().
            CallerWithSkipFrameCount(zerolog.CallerSkipFrameCount + skipFrameCount).
            Logger()
    }

    return &logger{
        logger: &z,
    }
}

func (l *logger) formatMessage(message any) string {
    switch t := message.(type) {
    case error:
        return t.Error()
    case string:
        return t
    default:
        return fmt.Sprintf("Unknown type %v", message)
    }
}

// Debug -.
func (l *logger) Debug(message any, args ...any) {
    mf := l.formatMessage(message)
    l.log(l.logger.Debug(), mf, args...)
}

// Info -.
func (l *logger) Info(message string, args ...any) {
    mf := l.formatMessage(message)
    l.log(l.logger.Info(), mf, args...)
}

// Warn -.
func (l *logger) Warn(message string, args ...any) {
    mf := l.formatMessage(message)
    l.log(l.logger.Warn(), mf, args...)
}

// Error -.
func (l *logger) Error(message interface{}, args ...any) {
    mf := l.formatMessage(message)
    l.log(l.logger.Error(), mf, args...)
}

// Fatal -.
func (l *logger) Fatal(message interface{}, args ...any) {
    mf := l.formatMessage(message)
    l.log(l.logger.Fatal(), mf, args...)

    os.Exit(1)
}

func (l *logger) log(e *zerolog.Event, m string, args ...any) {
    if len(args) == 0 {
        e.Msg(m)
    } else {
        e.Msgf(m, args)
    }
}