github.com/dominant-strategies/go-quai@v0.28.2/log/logger.go (about) 1 package log 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "runtime" 8 "strings" 9 10 "github.com/natefinch/lumberjack" 11 "github.com/sirupsen/logrus" 12 "gopkg.in/urfave/cli.v1" 13 ) 14 15 type Logger struct { 16 *logrus.Logger 17 } 18 19 var Log Logger = Logger{logrus.New()} 20 21 func init() { 22 23 } 24 25 func ConfigureLogger(ctx *cli.Context) { 26 logLevel := logrus.Level(ctx.GlobalInt("verbosity")) 27 Log.SetLevel(logLevel) 28 29 logToStdOut := ctx.GlobalBool("logtostdout") 30 31 log_filename := "nodelogs" 32 regionNum := ctx.GlobalString("region") 33 34 if ctx.GlobalIsSet("zone") { 35 zoneNum := ctx.GlobalString("zone") 36 log_filename = filepath.Join(log_filename, "zone-"+regionNum+"-"+zoneNum) 37 } else if ctx.GlobalIsSet("region") { 38 log_filename = filepath.Join(log_filename, "region-"+regionNum) 39 } else { 40 log_filename = filepath.Join(log_filename, "prime") 41 } 42 log_filename += ".log" 43 44 Log.Formatter = &logrus.TextFormatter{ 45 ForceColors: ctx.GlobalBool("showcolors"), 46 PadLevelText: true, 47 FullTimestamp: true, 48 TimestampFormat: "01-02|15:04:05.000", 49 } 50 51 if logToStdOut { 52 Log.SetOutput(os.Stdout) 53 } else { 54 Log.SetOutput(&lumberjack.Logger{ 55 Filename: log_filename, 56 MaxSize: 500, // megabytes 57 MaxBackups: 5, 58 MaxAge: 28, //days 59 }) 60 } 61 } 62 63 func SetLevelInt(level int) { 64 Log.SetLevel(logrus.Level(level)) 65 } 66 67 func SetLevelString(level string) { 68 logLevel, err := logrus.ParseLevel(level) 69 if err != nil { 70 Log.Error("Invalid log level: ", level) 71 return 72 } 73 Log.SetLevel(logLevel) 74 } 75 76 func New(out_path string) Logger { 77 logger := logrus.New() 78 logger.SetOutput(&lumberjack.Logger{ 79 Filename: out_path, 80 MaxSize: 500, // megabytes 81 MaxBackups: 3, 82 MaxAge: 28, //days 83 }) 84 return Logger{logger} 85 } 86 87 // Uses of the global logger will use the following static method. 88 func Trace(msg string, args ...interface{}) { 89 Log.Trace(constructLogMessage(msg, args...)) 90 } 91 92 // Individual logging instances will use the following method. 93 func (l Logger) Trace(msg string, args ...interface{}) { 94 l.Logger.Trace(constructLogMessage(msg, args...)) 95 } 96 97 func Debug(msg string, args ...interface{}) { 98 Log.Debug(constructLogMessage(msg, args...)) 99 } 100 func (l Logger) Debug(msg string, args ...interface{}) { 101 l.Logger.Debug(constructLogMessage(msg, args...)) 102 } 103 104 func Info(msg string, args ...interface{}) { 105 Log.Info(constructLogMessage(msg, args...)) 106 } 107 func (l Logger) Info(msg string, args ...interface{}) { 108 l.Logger.Info(constructLogMessage(msg, args...)) 109 } 110 111 func Warn(msg string, args ...interface{}) { 112 Log.Warn(constructLogMessage(msg, args...)) 113 } 114 func (l Logger) Warn(msg string, args ...interface{}) { 115 l.Logger.Warn(constructLogMessage(msg, args...)) 116 } 117 118 func Error(msg string, args ...interface{}) { 119 Log.Error(constructLogMessage(msg, args...)) 120 } 121 func (l Logger) Error(msg string, args ...interface{}) { 122 l.Logger.Error(constructLogMessage(msg, args...)) 123 } 124 125 func Fatal(msg string, args ...interface{}) { 126 Log.Fatal(constructLogMessage(msg, args...)) 127 } 128 func (l Logger) Fatal(msg string, args ...interface{}) { 129 l.Logger.Fatal(constructLogMessage(msg, args...)) 130 } 131 132 func Panic(msg string, args ...interface{}) { 133 Log.Panic(constructLogMessage(msg, args...)) 134 } 135 func (l Logger) Panic(msg string, args ...interface{}) { 136 l.Logger.Panic(constructLogMessage(msg, args...)) 137 } 138 139 func Lazy(fn func() string, logLevel string) { 140 level, err := logrus.ParseLevel(logLevel) 141 if err == nil && Log.IsLevelEnabled(level) { 142 callCorrectLevel(level, fn()) 143 } 144 } 145 146 func reportLineNumber(skiplevel int) string { 147 if Logger.GetLevel(Log) < logrus.DebugLevel { 148 return "" 149 } 150 _, file, line, ok := runtime.Caller(skiplevel + 1) 151 fileAndDir := filepath.Join(filepath.Base(filepath.Dir(file)), filepath.Base(file)) 152 if !ok || fileAndDir == "log/logger.go" { 153 return "" 154 } 155 return fmt.Sprintf("%s:%d", fileAndDir, line) 156 } 157 158 func callCorrectLevel(level logrus.Level, msg string, args ...interface{}) { 159 switch level { 160 case logrus.TraceLevel: 161 Trace(msg, args...) 162 case logrus.DebugLevel: 163 Debug(msg, args...) 164 case logrus.InfoLevel: 165 Info(msg, args...) 166 case logrus.WarnLevel: 167 Warn(msg, args...) 168 case logrus.ErrorLevel: 169 Error(msg, args...) 170 case logrus.FatalLevel: 171 Fatal(msg, args...) 172 case logrus.PanicLevel: 173 Panic(msg, args...) 174 default: 175 Error("Unknown log level: %v", level) 176 } 177 } 178 179 func constructLogMessage(msg string, fields ...interface{}) string { 180 var pairs []string 181 182 lineInfo := reportLineNumber(2) 183 184 if len(fields) != 1 { 185 // Sometimes we want to log a single string, 186 if len(fields)%2 != 0 { 187 fields = append(fields, "MISSING VALUE") 188 } 189 190 for i := 0; i < len(fields); i += 2 { 191 key := fields[i] 192 value := fields[i+1] 193 pairs = append(pairs, fmt.Sprintf("%v=%v", key, value)) 194 } 195 } 196 197 if lineInfo != "" { 198 return fmt.Sprintf("%-40s %-40s %s", lineInfo, msg, strings.Join(pairs, " ")) 199 } else { 200 return fmt.Sprintf("%-40s %s", msg, strings.Join(pairs, " ")) 201 } 202 }