github.com/lyft/flytestdlib@v0.3.12-0.20210213045714-8cdd111ecda1/logger/logger.go (about) 1 // Defines global context-aware logger. 2 // The default implementation uses logrus. This package registers "logger" config section on init(). The structure of the 3 // config section is expected to be un-marshal-able to Config struct. 4 package logger 5 6 import ( 7 "context" 8 "io" 9 10 "github.com/lyft/flytestdlib/contextutils" 11 12 "fmt" 13 "runtime" 14 "strings" 15 16 "github.com/sirupsen/logrus" 17 ) 18 19 const ( 20 indentLevelKey contextutils.Key = "LoggerIndentLevel" 21 sourceCodeKey string = "src" 22 ) 23 24 var noopLogger = NoopLogger{} 25 26 func onConfigUpdated(cfg Config) { 27 logrus.SetLevel(logrus.Level(cfg.Level)) 28 29 switch cfg.Formatter.Type { 30 case FormatterText: 31 if _, isText := logrus.StandardLogger().Formatter.(*logrus.JSONFormatter); !isText { 32 logrus.SetFormatter(&logrus.TextFormatter{ 33 FieldMap: logrus.FieldMap{ 34 logrus.FieldKeyTime: "ts", 35 }, 36 }) 37 } 38 default: 39 if _, isJSON := logrus.StandardLogger().Formatter.(*logrus.JSONFormatter); !isJSON { 40 logrus.SetFormatter(&logrus.JSONFormatter{ 41 DataKey: jsonDataKey, 42 FieldMap: logrus.FieldMap{ 43 logrus.FieldKeyTime: "ts", 44 }, 45 }) 46 } 47 } 48 } 49 50 func getSourceLocation() string { 51 // The reason we pass 3 here: 0 means this function (getSourceLocation), 1 means the getLogger function (only caller 52 // to getSourceLocation, 2 means the logging function (e.g. Debugln), and 3 means the caller for the logging function. 53 _, file, line, ok := runtime.Caller(3) 54 if !ok { 55 file = "???" 56 line = 1 57 } else { 58 slash := strings.LastIndex(file, "/") 59 if slash >= 0 { 60 file = file[slash+1:] 61 } 62 } 63 64 return fmt.Sprintf("%v:%v", file, line) 65 } 66 67 func getLogger(ctx context.Context) logrus.FieldLogger { 68 cfg := GetConfig() 69 if cfg.Mute { 70 return noopLogger 71 } 72 73 entry := logrus.WithFields(logrus.Fields(contextutils.GetLogFields(ctx))) 74 if cfg.IncludeSourceCode { 75 entry = entry.WithField(sourceCodeKey, getSourceLocation()) 76 } 77 78 entry.Level = logrus.Level(cfg.Level) 79 80 return entry 81 } 82 83 // Returns a standard io.PipeWriter that logs using the same logger configurations in this package. 84 func GetLogWriter(ctx context.Context) *io.PipeWriter { 85 logger := getLogger(ctx) 86 return logger.(*logrus.Entry).Writer() 87 } 88 89 func WithIndent(ctx context.Context, additionalIndent string) context.Context { 90 indentLevel := getIndent(ctx) + additionalIndent 91 return context.WithValue(ctx, indentLevelKey, indentLevel) 92 } 93 94 func getIndent(ctx context.Context) string { 95 if existing := ctx.Value(indentLevelKey); existing != nil { 96 return existing.(string) 97 } 98 99 return "" 100 } 101 102 // Gets a value indicating whether logs at this level will be written to the logger. This is particularly useful to avoid 103 // computing log messages unnecessarily. 104 func IsLoggable(_ context.Context, level Level) bool { 105 return GetConfig().Level >= level 106 } 107 108 // Debug logs a message at level Debug on the standard logger. 109 func Debug(ctx context.Context, args ...interface{}) { 110 getLogger(ctx).Debug(args...) 111 } 112 113 // Print logs a message at level Info on the standard logger. 114 func Print(ctx context.Context, args ...interface{}) { 115 getLogger(ctx).Print(args...) 116 } 117 118 // Info logs a message at level Info on the standard logger. 119 func Info(ctx context.Context, args ...interface{}) { 120 getLogger(ctx).Info(args...) 121 } 122 123 // Warn logs a message at level Warn on the standard logger. 124 func Warn(ctx context.Context, args ...interface{}) { 125 getLogger(ctx).Warn(args...) 126 } 127 128 // Warning logs a message at level Warn on the standard logger. 129 func Warning(ctx context.Context, args ...interface{}) { 130 getLogger(ctx).Warning(args...) 131 } 132 133 // Error logs a message at level Error on the standard logger. 134 func Error(ctx context.Context, args ...interface{}) { 135 getLogger(ctx).Error(args...) 136 } 137 138 // Panic logs a message at level Panic on the standard logger. 139 func Panic(ctx context.Context, args ...interface{}) { 140 getLogger(ctx).Panic(args...) 141 } 142 143 // Fatal logs a message at level Fatal on the standard logger. 144 func Fatal(ctx context.Context, args ...interface{}) { 145 getLogger(ctx).Fatal(args...) 146 } 147 148 // Debugf logs a message at level Debug on the standard logger. 149 func Debugf(ctx context.Context, format string, args ...interface{}) { 150 getLogger(ctx).Debugf(format, args...) 151 } 152 153 // Printf logs a message at level Info on the standard logger. 154 func Printf(ctx context.Context, format string, args ...interface{}) { 155 getLogger(ctx).Printf(format, args...) 156 } 157 158 // Infof logs a message at level Info on the standard logger. 159 func Infof(ctx context.Context, format string, args ...interface{}) { 160 getLogger(ctx).Infof(format, args...) 161 } 162 163 // InfofNoCtx logs a formatted message without context. 164 func InfofNoCtx(format string, args ...interface{}) { 165 getLogger(context.TODO()).Infof(format, args...) 166 } 167 168 // Warnf logs a message at level Warn on the standard logger. 169 func Warnf(ctx context.Context, format string, args ...interface{}) { 170 getLogger(ctx).Warnf(format, args...) 171 } 172 173 // Warningf logs a message at level Warn on the standard logger. 174 func Warningf(ctx context.Context, format string, args ...interface{}) { 175 getLogger(ctx).Warningf(format, args...) 176 } 177 178 // Errorf logs a message at level Error on the standard logger. 179 func Errorf(ctx context.Context, format string, args ...interface{}) { 180 getLogger(ctx).Errorf(format, args...) 181 } 182 183 // Panicf logs a message at level Panic on the standard logger. 184 func Panicf(ctx context.Context, format string, args ...interface{}) { 185 getLogger(ctx).Panicf(format, args...) 186 } 187 188 // Fatalf logs a message at level Fatal on the standard logger. 189 func Fatalf(ctx context.Context, format string, args ...interface{}) { 190 getLogger(ctx).Fatalf(format, args...) 191 } 192 193 // Debugln logs a message at level Debug on the standard logger. 194 func Debugln(ctx context.Context, args ...interface{}) { 195 getLogger(ctx).Debugln(args...) 196 } 197 198 // Println logs a message at level Info on the standard logger. 199 func Println(ctx context.Context, args ...interface{}) { 200 getLogger(ctx).Println(args...) 201 } 202 203 // Infoln logs a message at level Info on the standard logger. 204 func Infoln(ctx context.Context, args ...interface{}) { 205 getLogger(ctx).Infoln(args...) 206 } 207 208 // Warnln logs a message at level Warn on the standard logger. 209 func Warnln(ctx context.Context, args ...interface{}) { 210 getLogger(ctx).Warnln(args...) 211 } 212 213 // Warningln logs a message at level Warn on the standard logger. 214 func Warningln(ctx context.Context, args ...interface{}) { 215 getLogger(ctx).Warningln(args...) 216 } 217 218 // Errorln logs a message at level Error on the standard logger. 219 func Errorln(ctx context.Context, args ...interface{}) { 220 getLogger(ctx).Errorln(args...) 221 } 222 223 // Panicln logs a message at level Panic on the standard logger. 224 func Panicln(ctx context.Context, args ...interface{}) { 225 getLogger(ctx).Panicln(args...) 226 } 227 228 // Fatalln logs a message at level Fatal on the standard logger. 229 func Fatalln(ctx context.Context, args ...interface{}) { 230 getLogger(ctx).Fatalln(args...) 231 } 232 233 type NoopLogger struct { 234 } 235 236 func (NoopLogger) WithField(key string, value interface{}) *logrus.Entry { 237 return nil 238 } 239 240 func (NoopLogger) WithFields(fields logrus.Fields) *logrus.Entry { 241 return nil 242 } 243 244 func (NoopLogger) WithError(err error) *logrus.Entry { 245 return nil 246 } 247 248 func (NoopLogger) Debugf(format string, args ...interface{}) { 249 } 250 251 func (NoopLogger) Infof(format string, args ...interface{}) { 252 } 253 254 func (NoopLogger) Warnf(format string, args ...interface{}) { 255 } 256 257 func (NoopLogger) Warningf(format string, args ...interface{}) { 258 } 259 260 func (NoopLogger) Errorf(format string, args ...interface{}) { 261 } 262 263 func (NoopLogger) Debug(args ...interface{}) { 264 } 265 266 func (NoopLogger) Info(args ...interface{}) { 267 } 268 269 func (NoopLogger) Warn(args ...interface{}) { 270 } 271 272 func (NoopLogger) Warning(args ...interface{}) { 273 } 274 275 func (NoopLogger) Error(args ...interface{}) { 276 } 277 278 func (NoopLogger) Debugln(args ...interface{}) { 279 } 280 281 func (NoopLogger) Infoln(args ...interface{}) { 282 } 283 284 func (NoopLogger) Warnln(args ...interface{}) { 285 } 286 287 func (NoopLogger) Warningln(args ...interface{}) { 288 } 289 290 func (NoopLogger) Errorln(args ...interface{}) { 291 } 292 293 func (NoopLogger) Print(...interface{}) { 294 } 295 296 func (NoopLogger) Printf(string, ...interface{}) { 297 } 298 299 func (NoopLogger) Println(...interface{}) { 300 } 301 302 func (NoopLogger) Fatal(...interface{}) { 303 } 304 305 func (NoopLogger) Fatalf(string, ...interface{}) { 306 } 307 308 func (NoopLogger) Fatalln(...interface{}) { 309 } 310 311 func (NoopLogger) Panic(...interface{}) { 312 } 313 314 func (NoopLogger) Panicf(string, ...interface{}) { 315 } 316 317 func (NoopLogger) Panicln(...interface{}) { 318 }