| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- package log
- import (
- "context"
- "fmt"
- "io"
- "log"
- "os"
- "github.com/gofiber/utils/v2"
- "github.com/valyala/bytebufferpool"
- )
- var _ AllLogger[*log.Logger] = (*defaultLogger)(nil)
- type defaultLogger struct {
- stdlog *log.Logger
- level Level
- depth int
- }
- // privateLog logs a message at a given level log the default logger.
- // when the level is fatal, it will exit the program.
- func (l *defaultLogger) privateLog(lv Level, fmtArgs []any) {
- if l.level > lv {
- return
- }
- level := lv.toString()
- buf := bytebufferpool.Get()
- buf.WriteString(level)
- fmt.Fprint(buf, fmtArgs...)
- _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error
- if lv == LevelPanic {
- panic(buf.String())
- }
- buf.Reset()
- bytebufferpool.Put(buf)
- if lv == LevelFatal {
- os.Exit(1) //nolint:revive // we want to exit the program when Fatal is called
- }
- }
- // privateLogf logs a formatted message at a given level log the default logger.
- // when the level is fatal, it will exit the program.
- func (l *defaultLogger) privateLogf(lv Level, format string, fmtArgs []any) {
- if l.level > lv {
- return
- }
- level := lv.toString()
- buf := bytebufferpool.Get()
- buf.WriteString(level)
- if len(fmtArgs) > 0 {
- _, _ = fmt.Fprintf(buf, format, fmtArgs...)
- } else {
- _, _ = fmt.Fprint(buf, format)
- }
- _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error
- if lv == LevelPanic {
- panic(buf.String())
- }
- buf.Reset()
- bytebufferpool.Put(buf)
- if lv == LevelFatal {
- os.Exit(1) //nolint:revive // we want to exit the program when Fatal is called
- }
- }
- // privateLogw logs a message at a given level log the default logger.
- // when the level is fatal, it will exit the program.
- func (l *defaultLogger) privateLogw(lv Level, format string, keysAndValues []any) {
- if l.level > lv {
- return
- }
- level := lv.toString()
- buf := bytebufferpool.Get()
- buf.WriteString(level)
- // Write format privateLog buffer
- if format != "" {
- buf.WriteString(format)
- }
- // Write keys and values privateLog buffer
- if len(keysAndValues) > 0 {
- if (len(keysAndValues) & 1) == 1 {
- keysAndValues = append(keysAndValues, "KEYVALS UNPAIRED")
- }
- for i := 0; i < len(keysAndValues); i += 2 {
- if i > 0 || format != "" {
- buf.WriteByte(' ')
- }
- switch key := keysAndValues[i].(type) {
- case string:
- buf.WriteString(key)
- default:
- _, _ = fmt.Fprint(buf, key)
- }
- buf.WriteByte('=')
- buf.WriteString(utils.ToString(keysAndValues[i+1]))
- }
- }
- _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error
- if lv == LevelPanic {
- panic(buf.String())
- }
- buf.Reset()
- bytebufferpool.Put(buf)
- if lv == LevelFatal {
- os.Exit(1) //nolint:revive // we want to exit the program when Fatal is called
- }
- }
- // Trace logs the given values at trace level.
- func (l *defaultLogger) Trace(v ...any) {
- l.privateLog(LevelTrace, v)
- }
- // Debug logs the given values at debug level.
- func (l *defaultLogger) Debug(v ...any) {
- l.privateLog(LevelDebug, v)
- }
- // Info logs the given values at info level.
- func (l *defaultLogger) Info(v ...any) {
- l.privateLog(LevelInfo, v)
- }
- // Warn logs the given values at warn level.
- func (l *defaultLogger) Warn(v ...any) {
- l.privateLog(LevelWarn, v)
- }
- // Error logs the given values at error level.
- func (l *defaultLogger) Error(v ...any) {
- l.privateLog(LevelError, v)
- }
- // Fatal logs the given values at fatal level and terminates the process.
- func (l *defaultLogger) Fatal(v ...any) {
- l.privateLog(LevelFatal, v)
- }
- // Panic logs the given values at panic level and panics.
- func (l *defaultLogger) Panic(v ...any) {
- l.privateLog(LevelPanic, v)
- }
- // Tracef formats according to a format specifier and logs at trace level.
- func (l *defaultLogger) Tracef(format string, v ...any) {
- l.privateLogf(LevelTrace, format, v)
- }
- // Debugf formats according to a format specifier and logs at debug level.
- func (l *defaultLogger) Debugf(format string, v ...any) {
- l.privateLogf(LevelDebug, format, v)
- }
- // Infof formats according to a format specifier and logs at info level.
- func (l *defaultLogger) Infof(format string, v ...any) {
- l.privateLogf(LevelInfo, format, v)
- }
- // Warnf formats according to a format specifier and logs at warn level.
- func (l *defaultLogger) Warnf(format string, v ...any) {
- l.privateLogf(LevelWarn, format, v)
- }
- // Errorf formats according to a format specifier and logs at error level.
- func (l *defaultLogger) Errorf(format string, v ...any) {
- l.privateLogf(LevelError, format, v)
- }
- // Fatalf formats according to a format specifier, logs at fatal level, and terminates the process.
- func (l *defaultLogger) Fatalf(format string, v ...any) {
- l.privateLogf(LevelFatal, format, v)
- }
- // Panicf formats according to a format specifier, logs at panic level, and panics.
- func (l *defaultLogger) Panicf(format string, v ...any) {
- l.privateLogf(LevelPanic, format, v)
- }
- // Tracew logs at trace level with a message and key/value pairs.
- func (l *defaultLogger) Tracew(msg string, keysAndValues ...any) {
- l.privateLogw(LevelTrace, msg, keysAndValues)
- }
- // Debugw logs at debug level with a message and key/value pairs.
- func (l *defaultLogger) Debugw(msg string, keysAndValues ...any) {
- l.privateLogw(LevelDebug, msg, keysAndValues)
- }
- // Infow logs at info level with a message and key/value pairs.
- func (l *defaultLogger) Infow(msg string, keysAndValues ...any) {
- l.privateLogw(LevelInfo, msg, keysAndValues)
- }
- // Warnw logs at warn level with a message and key/value pairs.
- func (l *defaultLogger) Warnw(msg string, keysAndValues ...any) {
- l.privateLogw(LevelWarn, msg, keysAndValues)
- }
- // Errorw logs at error level with a message and key/value pairs.
- func (l *defaultLogger) Errorw(msg string, keysAndValues ...any) {
- l.privateLogw(LevelError, msg, keysAndValues)
- }
- // Fatalw logs at fatal level with a message and key/value pairs, then terminates the process.
- func (l *defaultLogger) Fatalw(msg string, keysAndValues ...any) {
- l.privateLogw(LevelFatal, msg, keysAndValues)
- }
- // Panicw logs at panic level with a message and key/value pairs, then panics.
- func (l *defaultLogger) Panicw(msg string, keysAndValues ...any) {
- l.privateLogw(LevelPanic, msg, keysAndValues)
- }
- // WithContext returns a logger that shares the underlying output but adjusts the call depth.
- func (l *defaultLogger) WithContext(_ context.Context) CommonLogger {
- return &defaultLogger{
- stdlog: l.stdlog,
- level: l.level,
- depth: l.depth - 1,
- }
- }
- // SetLevel updates the minimum level that will be emitted by the logger.
- func (l *defaultLogger) SetLevel(level Level) {
- l.level = level
- }
- // SetOutput replaces the underlying writer used by the logger.
- func (l *defaultLogger) SetOutput(writer io.Writer) {
- l.stdlog.SetOutput(writer)
- }
- // Logger returns the logger instance. It can be used to adjust the logger configurations in case of need.
- func (l *defaultLogger) Logger() *log.Logger {
- return l.stdlog
- }
- // DefaultLogger returns the default logger.
- func DefaultLogger[T any]() AllLogger[T] {
- if l, ok := logger.(AllLogger[T]); ok {
- return l
- }
- return nil
- }
|