github.com/vanstinator/golangci-lint@v0.0.0-20240223191551-cc572f00d9d1/pkg/logutils/stderr_log.go (about)

     1  package logutils
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"time"
     7  
     8  	"github.com/sirupsen/logrus" //nolint:depguard
     9  
    10  	"github.com/vanstinator/golangci-lint/pkg/exitcodes"
    11  )
    12  
    13  const (
    14  	// envLogLevel values: "error", "err", "warning", "warn","info"
    15  	envLogLevel = "LOG_LEVEL"
    16  	// envLogTimestamp value: "1"
    17  	envLogTimestamp = "LOG_TIMESTAMP"
    18  )
    19  
    20  type StderrLog struct {
    21  	name   string
    22  	logger *logrus.Logger
    23  	level  LogLevel
    24  }
    25  
    26  var _ Log = NewStderrLog(DebugKeyEmpty)
    27  
    28  func NewStderrLog(name string) *StderrLog {
    29  	sl := &StderrLog{
    30  		name:   name,
    31  		logger: logrus.New(),
    32  		level:  LogLevelWarn,
    33  	}
    34  
    35  	switch os.Getenv(envLogLevel) {
    36  	case "error", "err":
    37  		sl.logger.SetLevel(logrus.ErrorLevel)
    38  	case "warning", "warn":
    39  		sl.logger.SetLevel(logrus.WarnLevel)
    40  	case "info":
    41  		sl.logger.SetLevel(logrus.InfoLevel)
    42  	default:
    43  		sl.logger.SetLevel(logrus.DebugLevel)
    44  	}
    45  
    46  	sl.logger.Out = StdErr
    47  	formatter := &logrus.TextFormatter{
    48  		DisableTimestamp:          true, // `INFO[0007] msg` -> `INFO msg`
    49  		EnvironmentOverrideColors: true,
    50  	}
    51  	if os.Getenv(envLogTimestamp) == "1" {
    52  		formatter.DisableTimestamp = false
    53  		formatter.FullTimestamp = true
    54  		formatter.TimestampFormat = time.StampMilli
    55  	}
    56  	sl.logger.Formatter = formatter
    57  
    58  	return sl
    59  }
    60  
    61  func (sl StderrLog) prefix() string {
    62  	prefix := ""
    63  	if sl.name != "" {
    64  		prefix = fmt.Sprintf("[%s] ", sl.name)
    65  	}
    66  
    67  	return prefix
    68  }
    69  
    70  func (sl StderrLog) Fatalf(format string, args ...any) {
    71  	sl.logger.Errorf("%s%s", sl.prefix(), fmt.Sprintf(format, args...))
    72  	os.Exit(exitcodes.Failure)
    73  }
    74  
    75  func (sl StderrLog) Panicf(format string, args ...any) {
    76  	v := fmt.Sprintf("%s%s", sl.prefix(), fmt.Sprintf(format, args...))
    77  	panic(v)
    78  }
    79  
    80  func (sl StderrLog) Errorf(format string, args ...any) {
    81  	if sl.level > LogLevelError {
    82  		return
    83  	}
    84  
    85  	sl.logger.Errorf("%s%s", sl.prefix(), fmt.Sprintf(format, args...))
    86  	// don't call exitIfTest() because the idea is to
    87  	// crash on hidden errors (warnings); but Errorf MUST NOT be
    88  	// called on hidden errors, see log levels comments.
    89  }
    90  
    91  func (sl StderrLog) Warnf(format string, args ...any) {
    92  	if sl.level > LogLevelWarn {
    93  		return
    94  	}
    95  
    96  	sl.logger.Warnf("%s%s", sl.prefix(), fmt.Sprintf(format, args...))
    97  }
    98  
    99  func (sl StderrLog) Infof(format string, args ...any) {
   100  	if sl.level > LogLevelInfo {
   101  		return
   102  	}
   103  
   104  	sl.logger.Infof("%s%s", sl.prefix(), fmt.Sprintf(format, args...))
   105  }
   106  
   107  func (sl StderrLog) Debugf(format string, args ...any) {
   108  	if sl.level > LogLevelDebug {
   109  		return
   110  	}
   111  
   112  	sl.logger.Debugf("%s%s", sl.prefix(), fmt.Sprintf(format, args...))
   113  }
   114  
   115  func (sl StderrLog) Child(name string) Log {
   116  	prefix := ""
   117  	if sl.name != "" {
   118  		prefix = sl.name + "/"
   119  	}
   120  
   121  	child := sl
   122  	child.name = prefix + name
   123  
   124  	return &child
   125  }
   126  
   127  func (sl *StderrLog) SetLevel(level LogLevel) {
   128  	sl.level = level
   129  }