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 }