github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/logger/logger.go (about)

     1  package logger
     2  
     3  import (
     4  	"runtime"
     5  
     6  	"github.com/sirupsen/logrus"
     7  
     8  	"github.com/ShoshinNikita/budget-manager/internal/pkg/caller"
     9  	"github.com/ShoshinNikita/budget-manager/internal/web/api/models"
    10  )
    11  
    12  type Logger interface {
    13  	WithField(key string, value interface{}) Logger
    14  	WithFields(fields Fields) Logger
    15  	WithError(err error) Logger
    16  	WithRequest(models.Request) Logger
    17  
    18  	Debug(args ...interface{})
    19  	Debugf(format string, args ...interface{})
    20  
    21  	Info(args ...interface{})
    22  	Infof(format string, args ...interface{})
    23  
    24  	Warn(args ...interface{})
    25  	Warnf(format string, args ...interface{})
    26  
    27  	Error(args ...interface{})
    28  	Errorf(format string, args ...interface{})
    29  }
    30  
    31  type Fields logrus.Fields
    32  
    33  type Config struct {
    34  	// Mode is a mode of Logger. Valid options: prod, production, dev, develop.
    35  	// Default value is prod
    36  	Mode string
    37  
    38  	// Level is a level of logger. Valid options: debug, info, warn, error, fatal.
    39  	// It is always debug, when debug mode is on
    40  	Level string
    41  }
    42  
    43  func New(cnf Config) Logger {
    44  	log := logrus.New()
    45  	log.SetReportCaller(false)
    46  
    47  	log.SetLevel(parseLogLevel(cnf.Level))
    48  
    49  	switch cnf.Mode {
    50  	case "prod", "production":
    51  		log.SetFormatter(&logrus.JSONFormatter{
    52  			CallerPrettyfier: func(frame *runtime.Frame) (function string, file string) {
    53  				// Skip file field
    54  				return caller.FormatCaller(frame.Func), ""
    55  			},
    56  		})
    57  	case "dev", "develop":
    58  		fallthrough
    59  	default:
    60  		log.SetFormatter(devFormatter{})
    61  	}
    62  
    63  	return logger{log}
    64  }
    65  
    66  // parseLogLevel converts passed string to a logrus log level
    67  func parseLogLevel(lvl string) logrus.Level {
    68  	switch lvl {
    69  	case "dbg", "debug":
    70  		return logrus.DebugLevel
    71  	case "inf", "info":
    72  		return logrus.InfoLevel
    73  	case "warn", "warning":
    74  		return logrus.WarnLevel
    75  	case "err", "error":
    76  		return logrus.ErrorLevel
    77  	case "fatal":
    78  		return logrus.FatalLevel
    79  	default:
    80  		return logrus.InfoLevel
    81  	}
    82  }
    83  
    84  // logger is a wrapper for logrus.FieldLogger that implements Logger interface
    85  type logger struct {
    86  	logrus.FieldLogger
    87  }
    88  
    89  func (l logger) WithField(key string, value interface{}) Logger {
    90  	return logger{l.FieldLogger.WithField(key, value)}
    91  }
    92  
    93  func (l logger) WithFields(fields Fields) Logger {
    94  	return logger{l.FieldLogger.WithFields(logrus.Fields(fields))}
    95  }
    96  
    97  func (l logger) WithError(err error) Logger {
    98  	return logger{l.FieldLogger.WithError(err)}
    99  }
   100  
   101  func (l logger) WithRequest(req models.Request) Logger {
   102  	if fields := structToFields(req, "req"); len(fields) != 0 {
   103  		return l.WithFields(fields)
   104  	}
   105  	return l
   106  }