github.com/wfusion/gofusion@v1.1.14/common/infra/asynq/pkg/log/log.go (about)

     1  // Copyright 2020 Kentaro Hibino. All rights reserved.
     2  // Use of this source code is governed by a MIT license
     3  // that can be found in the LICENSE file.
     4  
     5  // Package log exports logging related types and functions.
     6  package log
     7  
     8  import (
     9  	"fmt"
    10  	"io"
    11  	stdlog "log"
    12  	"os"
    13  	"sync"
    14  )
    15  
    16  // Base supports logging at various log levels.
    17  type Base interface {
    18  	// Debug logs a message at Debug level.
    19  	Debug(args ...any)
    20  
    21  	// Info logs a message at Info level.
    22  	Info(args ...any)
    23  
    24  	// Warn logs a message at Warning level.
    25  	Warn(args ...any)
    26  
    27  	// Error logs a message at Error level.
    28  	Error(args ...any)
    29  
    30  	// Fatal logs a message at Fatal level
    31  	// and process will exit with status set to 1.
    32  	Fatal(args ...any)
    33  }
    34  
    35  // baseLogger is a wrapper object around log.Logger from the standard library.
    36  // It supports logging at various log levels.
    37  type baseLogger struct {
    38  	*stdlog.Logger
    39  }
    40  
    41  // Debug logs a message at Debug level.
    42  func (l *baseLogger) Debug(args ...any) {
    43  	l.prefixPrint("DEBUG: ", args...)
    44  }
    45  
    46  // Info logs a message at Info level.
    47  func (l *baseLogger) Info(args ...any) {
    48  	l.prefixPrint("INFO: ", args...)
    49  }
    50  
    51  // Warn logs a message at Warning level.
    52  func (l *baseLogger) Warn(args ...any) {
    53  	l.prefixPrint("WARN: ", args...)
    54  }
    55  
    56  // Error logs a message at Error level.
    57  func (l *baseLogger) Error(args ...any) {
    58  	l.prefixPrint("ERROR: ", args...)
    59  }
    60  
    61  // Fatal logs a message at Fatal level
    62  // and process will exit with status set to 1.
    63  func (l *baseLogger) Fatal(args ...any) {
    64  	l.prefixPrint("FATAL: ", args...)
    65  	os.Exit(1)
    66  }
    67  
    68  func (l *baseLogger) prefixPrint(prefix string, args ...any) {
    69  	args = append([]any{prefix}, args...)
    70  	l.Print(args...)
    71  }
    72  
    73  // newBase creates and returns a new instance of baseLogger.
    74  func newBase(out io.Writer) *baseLogger {
    75  	prefix := fmt.Sprintf("asynq: pid=%d ", os.Getpid())
    76  	return &baseLogger{
    77  		stdlog.New(out, prefix, stdlog.Ldate|stdlog.Ltime|stdlog.Lmicroseconds|stdlog.LUTC),
    78  	}
    79  }
    80  
    81  // NewLogger creates and returns a new instance of Logger.
    82  // Log level is set to DebugLevel by default.
    83  func NewLogger(base Base) *Logger {
    84  	if base == nil {
    85  		base = newBase(os.Stderr)
    86  	}
    87  	return &Logger{base: base, level: DebugLevel}
    88  }
    89  
    90  // Logger logs message to io.Writer at various log levels.
    91  type Logger struct {
    92  	base Base
    93  
    94  	mu sync.Mutex
    95  	// Minimum log level for this logger.
    96  	// Message with level lower than this level won't be outputted.
    97  	level Level
    98  }
    99  
   100  // Level represents a log level.
   101  type Level int32
   102  
   103  const (
   104  	// DebugLevel is the lowest level of logging.
   105  	// Debug logs are intended for debugging and development purposes.
   106  	DebugLevel Level = iota
   107  
   108  	// InfoLevel is used for general informational log messages.
   109  	InfoLevel
   110  
   111  	// WarnLevel is used for undesired but relatively expected events,
   112  	// which may indicate a problem.
   113  	WarnLevel
   114  
   115  	// ErrorLevel is used for undesired and unexpected events that
   116  	// the program can recover from.
   117  	ErrorLevel
   118  
   119  	// FatalLevel is used for undesired and unexpected events that
   120  	// the program cannot recover from.
   121  	FatalLevel
   122  )
   123  
   124  // String is part of the fmt.Stringer interface.
   125  //
   126  // Used for testing and debugging purposes.
   127  func (l Level) String() string {
   128  	switch l {
   129  	case DebugLevel:
   130  		return "debug"
   131  	case InfoLevel:
   132  		return "info"
   133  	case WarnLevel:
   134  		return "warning"
   135  	case ErrorLevel:
   136  		return "error"
   137  	case FatalLevel:
   138  		return "fatal"
   139  	default:
   140  		return "unknown"
   141  	}
   142  }
   143  
   144  // canLogAt reports whether logger can log at level v.
   145  func (l *Logger) canLogAt(v Level) bool {
   146  	l.mu.Lock()
   147  	defer l.mu.Unlock()
   148  	return v >= l.level
   149  }
   150  
   151  func (l *Logger) Debug(args ...any) {
   152  	if !l.canLogAt(DebugLevel) {
   153  		return
   154  	}
   155  	l.base.Debug(args...)
   156  }
   157  
   158  func (l *Logger) Info(args ...any) {
   159  	if !l.canLogAt(InfoLevel) {
   160  		return
   161  	}
   162  	l.base.Info(args...)
   163  }
   164  
   165  func (l *Logger) Warn(args ...any) {
   166  	if !l.canLogAt(WarnLevel) {
   167  		return
   168  	}
   169  	l.base.Warn(args...)
   170  }
   171  
   172  func (l *Logger) Error(args ...any) {
   173  	if !l.canLogAt(ErrorLevel) {
   174  		return
   175  	}
   176  	l.base.Error(args...)
   177  }
   178  
   179  func (l *Logger) Fatal(args ...any) {
   180  	if !l.canLogAt(FatalLevel) {
   181  		return
   182  	}
   183  	l.base.Fatal(args...)
   184  }
   185  
   186  func (l *Logger) Debugf(format string, args ...any) {
   187  	l.Debug(fmt.Sprintf(format, args...))
   188  }
   189  
   190  func (l *Logger) Infof(format string, args ...any) {
   191  	l.Info(fmt.Sprintf(format, args...))
   192  }
   193  
   194  func (l *Logger) Warnf(format string, args ...any) {
   195  	l.Warn(fmt.Sprintf(format, args...))
   196  }
   197  
   198  func (l *Logger) Errorf(format string, args ...any) {
   199  	l.Error(fmt.Sprintf(format, args...))
   200  }
   201  
   202  func (l *Logger) Fatalf(format string, args ...any) {
   203  	l.Fatal(fmt.Sprintf(format, args...))
   204  }
   205  
   206  // SetLevel sets the logger level.
   207  // It panics if v is less than DebugLevel or greater than FatalLevel.
   208  func (l *Logger) SetLevel(v Level) {
   209  	l.mu.Lock()
   210  	defer l.mu.Unlock()
   211  	if v < DebugLevel || v > FatalLevel {
   212  		panic("log: invalid log level")
   213  	}
   214  	l.level = v
   215  }