blob: 47fa3fb8670f4ba28e204c3627cfca0f8efa6f10 [file] [log] [blame]
Don Newton7577f072020-01-06 12:41:11 -05001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package log provides a structured Logger interface implemented using zap logger. It provides the following capabilities:
18//1. Package level logging - a go package can register itself (AddPackage) and have a logger created for that package.
19//2. Dynamic log level change - for all registered packages (SetAllLogLevel)
20//3. Dynamic log level change - for a given package (SetPackageLogLevel)
21//4. Provides a default logger for unregistered packages
22//5. Allow key-value pairs to be added to a logger(UpdateLogger) or all loggers (UpdateAllLoggers) at run time
23//6. Add to the log output the location where the log was invoked (filename.functionname.linenumber)
24//
25// Using package-level logging (recommended approach). In the examples below, log refers to this log package.
26// 1. In the appropriate package add the following in the init section of the package. The log level can be changed
27// and any number of default fields can be added as well. The log level specifies the lowest log level that will be
28// in the output while the fields will be automatically added to all log printouts.
29//
30// log.AddPackage(mylog.JSON, log.WarnLevel, log.Fields{"anyFieldName": "any value"})
31//
32//2. In the calling package, just invoke any of the publicly available functions of the logger. Here is an example
33// to write an Info log with additional fields:
34//
35//log.Infow("An example", mylog.Fields{"myStringOutput": "output", "myIntOutput": 2})
36//
37//3. To dynamically change the log level, you can use 1)SetLogLevel from inside your package or 2) SetPackageLogLevel
38// from anywhere or 3) SetAllLogLevel from anywhere.
39//
40
41package log
42
43import (
44 "errors"
45 "fmt"
46 zp "go.uber.org/zap"
47 zc "go.uber.org/zap/zapcore"
48 "path"
49 "runtime"
50 "strings"
51)
52
divyadesai81bb7ba2020-03-11 11:45:23 +000053type LogLevel int8
54
Don Newton7577f072020-01-06 12:41:11 -050055const (
56 // DebugLevel logs a message at debug level
divyadesai81bb7ba2020-03-11 11:45:23 +000057 DebugLevel = LogLevel(iota)
Don Newton7577f072020-01-06 12:41:11 -050058 // InfoLevel logs a message at info level
59 InfoLevel
60 // WarnLevel logs a message at warning level
61 WarnLevel
62 // ErrorLevel logs a message at error level
63 ErrorLevel
Don Newton7577f072020-01-06 12:41:11 -050064 // FatalLevel logs a message, then calls os.Exit(1).
65 FatalLevel
66)
67
68// CONSOLE formats the log for the console, mostly used during development
69const CONSOLE = "console"
70
71// JSON formats the log using json format, mostly used by an automated logging system consumption
72const JSON = "json"
73
74// Logger represents an abstract logging interface. Any logging implementation used
75// will need to abide by this interface
76type Logger interface {
77 Debug(...interface{})
78 Debugln(...interface{})
79 Debugf(string, ...interface{})
80 Debugw(string, Fields)
81
82 Info(...interface{})
83 Infoln(...interface{})
84 Infof(string, ...interface{})
85 Infow(string, Fields)
86
87 Warn(...interface{})
88 Warnln(...interface{})
89 Warnf(string, ...interface{})
90 Warnw(string, Fields)
91
92 Error(...interface{})
93 Errorln(...interface{})
94 Errorf(string, ...interface{})
95 Errorw(string, Fields)
96
97 Fatal(...interface{})
98 Fatalln(...interface{})
99 Fatalf(string, ...interface{})
100 Fatalw(string, Fields)
101
102 With(Fields) Logger
103
104 // The following are added to be able to use this logger as a gRPC LoggerV2 if needed
105 //
106 Warning(...interface{})
107 Warningln(...interface{})
108 Warningf(string, ...interface{})
109
110 // V reports whether verbosity level l is at least the requested verbose level.
divyadesai81bb7ba2020-03-11 11:45:23 +0000111 V(l LogLevel) bool
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800112
113 //Returns the log level of this specific logger
divyadesai81bb7ba2020-03-11 11:45:23 +0000114 GetLogLevel() LogLevel
Don Newton7577f072020-01-06 12:41:11 -0500115}
116
117// Fields is used as key-value pairs for structured logging
118type Fields map[string]interface{}
119
120var defaultLogger *logger
121var cfg zp.Config
122
123var loggers map[string]*logger
124var cfgs map[string]zp.Config
125
126type logger struct {
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800127 log *zp.SugaredLogger
128 parent *zp.Logger
129 packageName string
Don Newton7577f072020-01-06 12:41:11 -0500130}
131
divyadesai81bb7ba2020-03-11 11:45:23 +0000132func logLevelToAtomicLevel(l LogLevel) zp.AtomicLevel {
Don Newton7577f072020-01-06 12:41:11 -0500133 switch l {
134 case DebugLevel:
135 return zp.NewAtomicLevelAt(zc.DebugLevel)
136 case InfoLevel:
137 return zp.NewAtomicLevelAt(zc.InfoLevel)
138 case WarnLevel:
139 return zp.NewAtomicLevelAt(zc.WarnLevel)
140 case ErrorLevel:
141 return zp.NewAtomicLevelAt(zc.ErrorLevel)
Don Newton7577f072020-01-06 12:41:11 -0500142 case FatalLevel:
143 return zp.NewAtomicLevelAt(zc.FatalLevel)
144 }
145 return zp.NewAtomicLevelAt(zc.ErrorLevel)
146}
147
divyadesai81bb7ba2020-03-11 11:45:23 +0000148func logLevelToLevel(l LogLevel) zc.Level {
Don Newton7577f072020-01-06 12:41:11 -0500149 switch l {
150 case DebugLevel:
151 return zc.DebugLevel
152 case InfoLevel:
153 return zc.InfoLevel
154 case WarnLevel:
155 return zc.WarnLevel
156 case ErrorLevel:
157 return zc.ErrorLevel
Don Newton7577f072020-01-06 12:41:11 -0500158 case FatalLevel:
159 return zc.FatalLevel
160 }
161 return zc.ErrorLevel
162}
163
divyadesai81bb7ba2020-03-11 11:45:23 +0000164func levelToLogLevel(l zc.Level) LogLevel {
Don Newton7577f072020-01-06 12:41:11 -0500165 switch l {
166 case zc.DebugLevel:
167 return DebugLevel
168 case zc.InfoLevel:
169 return InfoLevel
170 case zc.WarnLevel:
171 return WarnLevel
172 case zc.ErrorLevel:
173 return ErrorLevel
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800174 case zc.FatalLevel:
175 return FatalLevel
176 }
177 return ErrorLevel
178}
179
divyadesai81bb7ba2020-03-11 11:45:23 +0000180func StringToLogLevel(l string) (LogLevel, error) {
181 switch strings.ToUpper(l) {
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800182 case "DEBUG":
divyadesai81bb7ba2020-03-11 11:45:23 +0000183 return DebugLevel, nil
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800184 case "INFO":
divyadesai81bb7ba2020-03-11 11:45:23 +0000185 return InfoLevel, nil
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800186 case "WARN":
divyadesai81bb7ba2020-03-11 11:45:23 +0000187 return WarnLevel, nil
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800188 case "ERROR":
divyadesai81bb7ba2020-03-11 11:45:23 +0000189 return ErrorLevel, nil
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800190 case "FATAL":
divyadesai81bb7ba2020-03-11 11:45:23 +0000191 return FatalLevel, nil
Don Newton7577f072020-01-06 12:41:11 -0500192 }
divyadesai81bb7ba2020-03-11 11:45:23 +0000193 return 0, errors.New("Given LogLevel is invalid : " + l)
Don Newton7577f072020-01-06 12:41:11 -0500194}
195
divyadesai81bb7ba2020-03-11 11:45:23 +0000196func LogLevelToString(l LogLevel) (string, error) {
197 switch l {
198 case DebugLevel:
199 return "DEBUG", nil
200 case InfoLevel:
201 return "INFO", nil
202 case WarnLevel:
203 return "WARN", nil
204 case ErrorLevel:
205 return "ERROR", nil
206 case FatalLevel:
207 return "FATAL", nil
208 }
209 return "", errors.New("Given LogLevel is invalid " + string(l))
210}
211
212func getDefaultConfig(outputType string, level LogLevel, defaultFields Fields) zp.Config {
Don Newton7577f072020-01-06 12:41:11 -0500213 return zp.Config{
divyadesai81bb7ba2020-03-11 11:45:23 +0000214 Level: logLevelToAtomicLevel(level),
Don Newton7577f072020-01-06 12:41:11 -0500215 Encoding: outputType,
216 Development: true,
217 OutputPaths: []string{"stdout"},
218 ErrorOutputPaths: []string{"stderr"},
219 InitialFields: defaultFields,
220 EncoderConfig: zc.EncoderConfig{
221 LevelKey: "level",
222 MessageKey: "msg",
223 TimeKey: "ts",
divyadesai81bb7ba2020-03-11 11:45:23 +0000224 CallerKey: "caller",
Don Newton7577f072020-01-06 12:41:11 -0500225 StacktraceKey: "stacktrace",
226 LineEnding: zc.DefaultLineEnding,
227 EncodeLevel: zc.LowercaseLevelEncoder,
228 EncodeTime: zc.ISO8601TimeEncoder,
229 EncodeDuration: zc.SecondsDurationEncoder,
230 EncodeCaller: zc.ShortCallerEncoder,
231 },
232 }
233}
234
235// SetLogger needs to be invoked before the logger API can be invoked. This function
236// initialize the default logger (zap's sugaredlogger)
divyadesai81bb7ba2020-03-11 11:45:23 +0000237func SetDefaultLogger(outputType string, level LogLevel, defaultFields Fields) (Logger, error) {
Don Newton7577f072020-01-06 12:41:11 -0500238 // Build a custom config using zap
239 cfg = getDefaultConfig(outputType, level, defaultFields)
240
divyadesai81bb7ba2020-03-11 11:45:23 +0000241 l, err := cfg.Build(zp.AddCallerSkip(1))
Don Newton7577f072020-01-06 12:41:11 -0500242 if err != nil {
243 return nil, err
244 }
245
246 defaultLogger = &logger{
247 log: l.Sugar(),
248 parent: l,
249 }
250
251 return defaultLogger, nil
252}
253
254// AddPackage registers a package to the log map. Each package gets its own logger which allows
255// its config (loglevel) to be changed dynamically without interacting with the other packages.
256// outputType is JSON, level is the lowest level log to output with this logger and defaultFields is a map of
257// key-value pairs to always add to the output.
258// Note: AddPackage also returns a reference to the actual logger. If a calling package uses this reference directly
259//instead of using the publicly available functions in this log package then a number of functionalities will not
260// be available to it, notably log tracing with filename.functionname.linenumber annotation.
261//
262// pkgNames parameter should be used for testing only as this function detects the caller's package.
divyadesai81bb7ba2020-03-11 11:45:23 +0000263func AddPackage(outputType string, level LogLevel, defaultFields Fields, pkgNames ...string) (Logger, error) {
Don Newton7577f072020-01-06 12:41:11 -0500264 if cfgs == nil {
265 cfgs = make(map[string]zp.Config)
266 }
267 if loggers == nil {
268 loggers = make(map[string]*logger)
269 }
270
271 var pkgName string
272 for _, name := range pkgNames {
273 pkgName = name
274 break
275 }
276 if pkgName == "" {
277 pkgName, _, _, _ = getCallerInfo()
278 }
279
280 if _, exist := loggers[pkgName]; exist {
281 return loggers[pkgName], nil
282 }
283
284 cfgs[pkgName] = getDefaultConfig(outputType, level, defaultFields)
285
divyadesai81bb7ba2020-03-11 11:45:23 +0000286 l, err := cfgs[pkgName].Build(zp.AddCallerSkip(1))
Don Newton7577f072020-01-06 12:41:11 -0500287 if err != nil {
288 return nil, err
289 }
290
291 loggers[pkgName] = &logger{
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800292 log: l.Sugar(),
293 parent: l,
294 packageName: pkgName,
Don Newton7577f072020-01-06 12:41:11 -0500295 }
296 return loggers[pkgName], nil
297}
298
299//UpdateAllLoggers create new loggers for all registered pacakges with the defaultFields.
300func UpdateAllLoggers(defaultFields Fields) error {
301 for pkgName, cfg := range cfgs {
302 for k, v := range defaultFields {
303 if cfg.InitialFields == nil {
304 cfg.InitialFields = make(map[string]interface{})
305 }
306 cfg.InitialFields[k] = v
307 }
divyadesai81bb7ba2020-03-11 11:45:23 +0000308 l, err := cfg.Build(zp.AddCallerSkip(1))
Don Newton7577f072020-01-06 12:41:11 -0500309 if err != nil {
310 return err
311 }
312
divyadesai81bb7ba2020-03-11 11:45:23 +0000313 // Update the existing zap logger instance
314 loggers[pkgName].log = l.Sugar()
315 loggers[pkgName].parent = l
Don Newton7577f072020-01-06 12:41:11 -0500316 }
317 return nil
318}
319
320// Return a list of all packages that have individually-configured loggers
321func GetPackageNames() []string {
322 i := 0
323 keys := make([]string, len(loggers))
324 for k := range loggers {
325 keys[i] = k
326 i++
327 }
328 return keys
329}
330
divyadesai81bb7ba2020-03-11 11:45:23 +0000331// UpdateLogger updates the logger associated with a caller's package with supplied defaultFields
332func UpdateLogger(defaultFields Fields) error {
Don Newton7577f072020-01-06 12:41:11 -0500333 pkgName, _, _, _ := getCallerInfo()
334 if _, exist := loggers[pkgName]; !exist {
divyadesai81bb7ba2020-03-11 11:45:23 +0000335 return fmt.Errorf("package-%s-not-registered", pkgName)
Don Newton7577f072020-01-06 12:41:11 -0500336 }
337
338 // Build a new logger
339 if _, exist := cfgs[pkgName]; !exist {
divyadesai81bb7ba2020-03-11 11:45:23 +0000340 return fmt.Errorf("config-%s-not-registered", pkgName)
Don Newton7577f072020-01-06 12:41:11 -0500341 }
342
343 cfg := cfgs[pkgName]
344 for k, v := range defaultFields {
345 if cfg.InitialFields == nil {
346 cfg.InitialFields = make(map[string]interface{})
347 }
348 cfg.InitialFields[k] = v
349 }
divyadesai81bb7ba2020-03-11 11:45:23 +0000350 l, err := cfg.Build(zp.AddCallerSkip(1))
Don Newton7577f072020-01-06 12:41:11 -0500351 if err != nil {
divyadesai81bb7ba2020-03-11 11:45:23 +0000352 return err
Don Newton7577f072020-01-06 12:41:11 -0500353 }
354
divyadesai81bb7ba2020-03-11 11:45:23 +0000355 // Update the existing zap logger instance
356 loggers[pkgName].log = l.Sugar()
357 loggers[pkgName].parent = l
358
359 return nil
Don Newton7577f072020-01-06 12:41:11 -0500360}
361
divyadesai81bb7ba2020-03-11 11:45:23 +0000362func setLevel(cfg zp.Config, level LogLevel) {
Don Newton7577f072020-01-06 12:41:11 -0500363 switch level {
364 case DebugLevel:
365 cfg.Level.SetLevel(zc.DebugLevel)
366 case InfoLevel:
367 cfg.Level.SetLevel(zc.InfoLevel)
368 case WarnLevel:
369 cfg.Level.SetLevel(zc.WarnLevel)
370 case ErrorLevel:
371 cfg.Level.SetLevel(zc.ErrorLevel)
Don Newton7577f072020-01-06 12:41:11 -0500372 case FatalLevel:
373 cfg.Level.SetLevel(zc.FatalLevel)
374 default:
375 cfg.Level.SetLevel(zc.ErrorLevel)
376 }
377}
378
379//SetPackageLogLevel dynamically sets the log level of a given package to level. This is typically invoked at an
380// application level during debugging
divyadesai81bb7ba2020-03-11 11:45:23 +0000381func SetPackageLogLevel(packageName string, level LogLevel) {
Don Newton7577f072020-01-06 12:41:11 -0500382 // Get proper config
383 if cfg, ok := cfgs[packageName]; ok {
384 setLevel(cfg, level)
385 }
386}
387
388//SetAllLogLevel sets the log level of all registered packages to level
divyadesai81bb7ba2020-03-11 11:45:23 +0000389func SetAllLogLevel(level LogLevel) {
Don Newton7577f072020-01-06 12:41:11 -0500390 // Get proper config
391 for _, cfg := range cfgs {
392 setLevel(cfg, level)
393 }
394}
395
396//GetPackageLogLevel returns the current log level of a package.
divyadesai81bb7ba2020-03-11 11:45:23 +0000397func GetPackageLogLevel(packageName ...string) (LogLevel, error) {
Don Newton7577f072020-01-06 12:41:11 -0500398 var name string
399 if len(packageName) == 1 {
400 name = packageName[0]
401 } else {
402 name, _, _, _ = getCallerInfo()
403 }
404 if cfg, ok := cfgs[name]; ok {
divyadesai81bb7ba2020-03-11 11:45:23 +0000405 return levelToLogLevel(cfg.Level.Level()), nil
Don Newton7577f072020-01-06 12:41:11 -0500406 }
divyadesai81bb7ba2020-03-11 11:45:23 +0000407 return 0, fmt.Errorf("unknown-package-%s", name)
Don Newton7577f072020-01-06 12:41:11 -0500408}
409
410//GetDefaultLogLevel gets the log level used for packages that don't have specific loggers
divyadesai81bb7ba2020-03-11 11:45:23 +0000411func GetDefaultLogLevel() LogLevel {
412 return levelToLogLevel(cfg.Level.Level())
Don Newton7577f072020-01-06 12:41:11 -0500413}
414
415//SetLogLevel sets the log level for the logger corresponding to the caller's package
divyadesai81bb7ba2020-03-11 11:45:23 +0000416func SetLogLevel(level LogLevel) error {
Don Newton7577f072020-01-06 12:41:11 -0500417 pkgName, _, _, _ := getCallerInfo()
418 if _, exist := cfgs[pkgName]; !exist {
divyadesai81bb7ba2020-03-11 11:45:23 +0000419 return fmt.Errorf("unregistered-package-%s", pkgName)
Don Newton7577f072020-01-06 12:41:11 -0500420 }
421 cfg := cfgs[pkgName]
422 setLevel(cfg, level)
423 return nil
424}
425
426//SetDefaultLogLevel sets the log level used for packages that don't have specific loggers
divyadesai81bb7ba2020-03-11 11:45:23 +0000427func SetDefaultLogLevel(level LogLevel) {
Don Newton7577f072020-01-06 12:41:11 -0500428 setLevel(cfg, level)
429}
430
431// CleanUp flushed any buffered log entries. Applications should take care to call
432// CleanUp before exiting.
433func CleanUp() error {
434 for _, logger := range loggers {
435 if logger != nil {
436 if logger.parent != nil {
437 if err := logger.parent.Sync(); err != nil {
438 return err
439 }
440 }
441 }
442 }
443 if defaultLogger != nil {
444 if defaultLogger.parent != nil {
445 if err := defaultLogger.parent.Sync(); err != nil {
446 return err
447 }
448 }
449 }
450 return nil
451}
452
453func getCallerInfo() (string, string, string, int) {
454 // Since the caller of a log function is one stack frame before (in terms of stack higher level) the log.go
455 // filename, then first look for the last log.go filename and then grab the caller info one level higher.
456 maxLevel := 3
457 skiplevel := 3 // Level with the most empirical success to see the last log.go stack frame.
458 pc := make([]uintptr, maxLevel)
459 n := runtime.Callers(skiplevel, pc)
460 packageName := ""
461 funcName := ""
462 fileName := ""
463 var line int
464 if n == 0 {
465 return packageName, fileName, funcName, line
466 }
467 frames := runtime.CallersFrames(pc[:n])
468 var frame runtime.Frame
469 var foundFrame runtime.Frame
470 more := true
471 for more {
472 frame, more = frames.Next()
473 _, fileName = path.Split(frame.File)
474 if fileName != "log.go" {
475 foundFrame = frame // First frame after log.go in the frame stack
476 break
477 }
478 }
479 parts := strings.Split(foundFrame.Function, ".")
480 pl := len(parts)
481 if pl >= 2 {
482 funcName = parts[pl-1]
483 if parts[pl-2][0] == '(' {
484 packageName = strings.Join(parts[0:pl-2], ".")
485 } else {
486 packageName = strings.Join(parts[0:pl-1], ".")
487 }
488 }
489
490 if strings.HasSuffix(packageName, ".init") {
491 packageName = strings.TrimSuffix(packageName, ".init")
492 }
493
494 if strings.HasSuffix(fileName, ".go") {
495 fileName = strings.TrimSuffix(fileName, ".go")
496 }
497
498 return packageName, fileName, funcName, foundFrame.Line
499}
500
501func getPackageLevelSugaredLogger() *zp.SugaredLogger {
502 pkgName, fileName, funcName, line := getCallerInfo()
503 if _, exist := loggers[pkgName]; exist {
504 return loggers[pkgName].log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
505 }
506 return defaultLogger.log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
507}
508
509func getPackageLevelLogger() Logger {
510 pkgName, _, _, _ := getCallerInfo()
511 if _, exist := loggers[pkgName]; exist {
512 return loggers[pkgName]
513 }
514 return defaultLogger
515}
516
517func serializeMap(fields Fields) []interface{} {
518 data := make([]interface{}, len(fields)*2)
519 i := 0
520 for k, v := range fields {
521 data[i] = k
522 data[i+1] = v
523 i = i + 2
524 }
525 return data
526}
527
528// With returns a logger initialized with the key-value pairs
529func (l logger) With(keysAndValues Fields) Logger {
530 return logger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
531}
532
533// Debug logs a message at level Debug on the standard logger.
534func (l logger) Debug(args ...interface{}) {
535 l.log.Debug(args...)
536}
537
538// Debugln logs a message at level Debug on the standard logger with a line feed. Default in any case.
539func (l logger) Debugln(args ...interface{}) {
540 l.log.Debug(args...)
541}
542
543// Debugw logs a message at level Debug on the standard logger.
544func (l logger) Debugf(format string, args ...interface{}) {
545 l.log.Debugf(format, args...)
546}
547
548// Debugw logs a message with some additional context. The variadic key-value
549// pairs are treated as they are in With.
550func (l logger) Debugw(msg string, keysAndValues Fields) {
551 l.log.Debugw(msg, serializeMap(keysAndValues)...)
552}
553
554// Info logs a message at level Info on the standard logger.
555func (l logger) Info(args ...interface{}) {
556 l.log.Info(args...)
557}
558
559// Infoln logs a message at level Info on the standard logger with a line feed. Default in any case.
560func (l logger) Infoln(args ...interface{}) {
561 l.log.Info(args...)
562 //msg := fmt.Sprintln(args...)
563 //l.sourced().Info(msg[:len(msg)-1])
564}
565
566// Infof logs a message at level Info on the standard logger.
567func (l logger) Infof(format string, args ...interface{}) {
568 l.log.Infof(format, args...)
569}
570
571// Infow logs a message with some additional context. The variadic key-value
572// pairs are treated as they are in With.
573func (l logger) Infow(msg string, keysAndValues Fields) {
574 l.log.Infow(msg, serializeMap(keysAndValues)...)
575}
576
577// Warn logs a message at level Warn on the standard logger.
578func (l logger) Warn(args ...interface{}) {
579 l.log.Warn(args...)
580}
581
582// Warnln logs a message at level Warn on the standard logger with a line feed. Default in any case.
583func (l logger) Warnln(args ...interface{}) {
584 l.log.Warn(args...)
585}
586
587// Warnf logs a message at level Warn on the standard logger.
588func (l logger) Warnf(format string, args ...interface{}) {
589 l.log.Warnf(format, args...)
590}
591
592// Warnw logs a message with some additional context. The variadic key-value
593// pairs are treated as they are in With.
594func (l logger) Warnw(msg string, keysAndValues Fields) {
595 l.log.Warnw(msg, serializeMap(keysAndValues)...)
596}
597
598// Error logs a message at level Error on the standard logger.
599func (l logger) Error(args ...interface{}) {
600 l.log.Error(args...)
601}
602
603// Errorln logs a message at level Error on the standard logger with a line feed. Default in any case.
604func (l logger) Errorln(args ...interface{}) {
605 l.log.Error(args...)
606}
607
608// Errorf logs a message at level Error on the standard logger.
609func (l logger) Errorf(format string, args ...interface{}) {
610 l.log.Errorf(format, args...)
611}
612
613// Errorw logs a message with some additional context. The variadic key-value
614// pairs are treated as they are in With.
615func (l logger) Errorw(msg string, keysAndValues Fields) {
616 l.log.Errorw(msg, serializeMap(keysAndValues)...)
617}
618
619// Fatal logs a message at level Fatal on the standard logger.
620func (l logger) Fatal(args ...interface{}) {
621 l.log.Fatal(args...)
622}
623
624// Fatalln logs a message at level Fatal on the standard logger with a line feed. Default in any case.
625func (l logger) Fatalln(args ...interface{}) {
626 l.log.Fatal(args...)
627}
628
629// Fatalf logs a message at level Fatal on the standard logger.
630func (l logger) Fatalf(format string, args ...interface{}) {
631 l.log.Fatalf(format, args...)
632}
633
634// Fatalw logs a message with some additional context. The variadic key-value
635// pairs are treated as they are in With.
636func (l logger) Fatalw(msg string, keysAndValues Fields) {
637 l.log.Fatalw(msg, serializeMap(keysAndValues)...)
638}
639
640// Warning logs a message at level Warn on the standard logger.
641func (l logger) Warning(args ...interface{}) {
642 l.log.Warn(args...)
643}
644
645// Warningln logs a message at level Warn on the standard logger with a line feed. Default in any case.
646func (l logger) Warningln(args ...interface{}) {
647 l.log.Warn(args...)
648}
649
650// Warningf logs a message at level Warn on the standard logger.
651func (l logger) Warningf(format string, args ...interface{}) {
652 l.log.Warnf(format, args...)
653}
654
655// V reports whether verbosity level l is at least the requested verbose level.
divyadesai81bb7ba2020-03-11 11:45:23 +0000656func (l logger) V(level LogLevel) bool {
657 return l.parent.Core().Enabled(logLevelToLevel(level))
Don Newton7577f072020-01-06 12:41:11 -0500658}
659
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800660// GetLogLevel returns the current level of the logger
divyadesai81bb7ba2020-03-11 11:45:23 +0000661func (l logger) GetLogLevel() LogLevel {
662 return levelToLogLevel(cfgs[l.packageName].Level.Level())
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800663}
664
Don Newton7577f072020-01-06 12:41:11 -0500665// With returns a logger initialized with the key-value pairs
666func With(keysAndValues Fields) Logger {
667 return logger{log: getPackageLevelSugaredLogger().With(serializeMap(keysAndValues)...), parent: defaultLogger.parent}
668}
669
670// Debug logs a message at level Debug on the standard logger.
671func Debug(args ...interface{}) {
672 getPackageLevelSugaredLogger().Debug(args...)
673}
674
675// Debugln logs a message at level Debug on the standard logger.
676func Debugln(args ...interface{}) {
677 getPackageLevelSugaredLogger().Debug(args...)
678}
679
680// Debugf logs a message at level Debug on the standard logger.
681func Debugf(format string, args ...interface{}) {
682 getPackageLevelSugaredLogger().Debugf(format, args...)
683}
684
685// Debugw logs a message with some additional context. The variadic key-value
686// pairs are treated as they are in With.
687func Debugw(msg string, keysAndValues Fields) {
688 getPackageLevelSugaredLogger().Debugw(msg, serializeMap(keysAndValues)...)
689}
690
691// Info logs a message at level Info on the standard logger.
692func Info(args ...interface{}) {
693 getPackageLevelSugaredLogger().Info(args...)
694}
695
696// Infoln logs a message at level Info on the standard logger.
697func Infoln(args ...interface{}) {
698 getPackageLevelSugaredLogger().Info(args...)
699}
700
701// Infof logs a message at level Info on the standard logger.
702func Infof(format string, args ...interface{}) {
703 getPackageLevelSugaredLogger().Infof(format, args...)
704}
705
706//Infow logs a message with some additional context. The variadic key-value
707//pairs are treated as they are in With.
708func Infow(msg string, keysAndValues Fields) {
709 getPackageLevelSugaredLogger().Infow(msg, serializeMap(keysAndValues)...)
710}
711
712// Warn logs a message at level Warn on the standard logger.
713func Warn(args ...interface{}) {
714 getPackageLevelSugaredLogger().Warn(args...)
715}
716
717// Warnln logs a message at level Warn on the standard logger.
718func Warnln(args ...interface{}) {
719 getPackageLevelSugaredLogger().Warn(args...)
720}
721
722// Warnf logs a message at level Warn on the standard logger.
723func Warnf(format string, args ...interface{}) {
724 getPackageLevelSugaredLogger().Warnf(format, args...)
725}
726
727// Warnw logs a message with some additional context. The variadic key-value
728// pairs are treated as they are in With.
729func Warnw(msg string, keysAndValues Fields) {
730 getPackageLevelSugaredLogger().Warnw(msg, serializeMap(keysAndValues)...)
731}
732
733// Error logs a message at level Error on the standard logger.
734func Error(args ...interface{}) {
735 getPackageLevelSugaredLogger().Error(args...)
736}
737
738// Errorln logs a message at level Error on the standard logger.
739func Errorln(args ...interface{}) {
740 getPackageLevelSugaredLogger().Error(args...)
741}
742
743// Errorf logs a message at level Error on the standard logger.
744func Errorf(format string, args ...interface{}) {
745 getPackageLevelSugaredLogger().Errorf(format, args...)
746}
747
748// Errorw logs a message with some additional context. The variadic key-value
749// pairs are treated as they are in With.
750func Errorw(msg string, keysAndValues Fields) {
751 getPackageLevelSugaredLogger().Errorw(msg, serializeMap(keysAndValues)...)
752}
753
754// Fatal logs a message at level Fatal on the standard logger.
755func Fatal(args ...interface{}) {
756 getPackageLevelSugaredLogger().Fatal(args...)
757}
758
759// Fatalln logs a message at level Fatal on the standard logger.
760func Fatalln(args ...interface{}) {
761 getPackageLevelSugaredLogger().Fatal(args...)
762}
763
764// Fatalf logs a message at level Fatal on the standard logger.
765func Fatalf(format string, args ...interface{}) {
766 getPackageLevelSugaredLogger().Fatalf(format, args...)
767}
768
769// Fatalw logs a message with some additional context. The variadic key-value
770// pairs are treated as they are in With.
771func Fatalw(msg string, keysAndValues Fields) {
772 getPackageLevelSugaredLogger().Fatalw(msg, serializeMap(keysAndValues)...)
773}
774
775// Warning logs a message at level Warn on the standard logger.
776func Warning(args ...interface{}) {
777 getPackageLevelSugaredLogger().Warn(args...)
778}
779
780// Warningln logs a message at level Warn on the standard logger.
781func Warningln(args ...interface{}) {
782 getPackageLevelSugaredLogger().Warn(args...)
783}
784
785// Warningf logs a message at level Warn on the standard logger.
786func Warningf(format string, args ...interface{}) {
787 getPackageLevelSugaredLogger().Warnf(format, args...)
788}
789
790// V reports whether verbosity level l is at least the requested verbose level.
divyadesai81bb7ba2020-03-11 11:45:23 +0000791func V(level LogLevel) bool {
Don Newton7577f072020-01-06 12:41:11 -0500792 return getPackageLevelLogger().V(level)
793}
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800794
795//GetLogLevel returns the log level of the invoking package
divyadesai81bb7ba2020-03-11 11:45:23 +0000796func GetLogLevel() LogLevel {
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800797 return getPackageLevelLogger().GetLogLevel()
798}