blob: 6b7087fd3203f3e37d673754d7a0c1bab99bce75 [file] [log] [blame]
Scott Baker2c1c4822019-10-16 11:02:41 -07001/*
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
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +000053type LogLevel int8
54
Scott Baker2c1c4822019-10-16 11:02:41 -070055const (
56 // DebugLevel logs a message at debug level
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +000057 DebugLevel = LogLevel(iota)
Scott Baker2c1c4822019-10-16 11:02:41 -070058 // 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
Scott Baker2c1c4822019-10-16 11:02:41 -070064 // 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.
Scott Bakerd7c25f42020-02-21 08:12:06 -0800111 V(l LogLevel) bool
khenaidoob332f9b2020-01-16 16:25:26 -0500112
113 //Returns the log level of this specific logger
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000114 GetLogLevel() LogLevel
Scott Baker2c1c4822019-10-16 11:02:41 -0700115}
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 {
khenaidoob332f9b2020-01-16 16:25:26 -0500127 log *zp.SugaredLogger
128 parent *zp.Logger
129 packageName string
Scott Baker2c1c4822019-10-16 11:02:41 -0700130}
131
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000132func logLevelToAtomicLevel(l LogLevel) zp.AtomicLevel {
Scott Baker2c1c4822019-10-16 11:02:41 -0700133 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)
Scott Baker2c1c4822019-10-16 11:02:41 -0700142 case FatalLevel:
143 return zp.NewAtomicLevelAt(zc.FatalLevel)
144 }
145 return zp.NewAtomicLevelAt(zc.ErrorLevel)
146}
147
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000148func logLevelToLevel(l LogLevel) zc.Level {
Scott Baker2c1c4822019-10-16 11:02:41 -0700149 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
Scott Baker2c1c4822019-10-16 11:02:41 -0700158 case FatalLevel:
159 return zc.FatalLevel
160 }
161 return zc.ErrorLevel
162}
163
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000164func levelToLogLevel(l zc.Level) LogLevel {
Scott Baker2c1c4822019-10-16 11:02:41 -0700165 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
Rohan Agrawal6a99a452020-01-14 07:58:25 +0000174 case zc.FatalLevel:
175 return FatalLevel
176 }
177 return ErrorLevel
178}
179
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000180func StringToLogLevel(l string) (LogLevel, error) {
181 switch strings.ToUpper(l) {
Rohan Agrawal6a99a452020-01-14 07:58:25 +0000182 case "DEBUG":
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000183 return DebugLevel, nil
Rohan Agrawal6a99a452020-01-14 07:58:25 +0000184 case "INFO":
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000185 return InfoLevel, nil
Rohan Agrawal6a99a452020-01-14 07:58:25 +0000186 case "WARN":
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000187 return WarnLevel, nil
Rohan Agrawal6a99a452020-01-14 07:58:25 +0000188 case "ERROR":
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000189 return ErrorLevel, nil
Rohan Agrawal6a99a452020-01-14 07:58:25 +0000190 case "FATAL":
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000191 return FatalLevel, nil
Scott Baker2c1c4822019-10-16 11:02:41 -0700192 }
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000193 return 0, errors.New("Given LogLevel is invalid : " + l)
Scott Baker2c1c4822019-10-16 11:02:41 -0700194}
195
divyadesai8bf96862020-02-07 12:24:26 +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
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000212func getDefaultConfig(outputType string, level LogLevel, defaultFields Fields) zp.Config {
Scott Baker2c1c4822019-10-16 11:02:41 -0700213 return zp.Config{
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000214 Level: logLevelToAtomicLevel(level),
Scott Baker2c1c4822019-10-16 11:02:41 -0700215 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",
Girish Kumarc9b0e712020-02-27 17:50:52 +0000224 CallerKey: "caller",
Scott Baker2c1c4822019-10-16 11:02:41 -0700225 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
Rohan Agrawalee87e642020-04-14 10:22:18 +0000235func ConstructZapConfig(outputType string, level LogLevel, fields Fields) zp.Config {
236 return getDefaultConfig(outputType, level, fields)
237}
238
Scott Baker2c1c4822019-10-16 11:02:41 -0700239// SetLogger needs to be invoked before the logger API can be invoked. This function
240// initialize the default logger (zap's sugaredlogger)
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000241func SetDefaultLogger(outputType string, level LogLevel, defaultFields Fields) (Logger, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700242 // Build a custom config using zap
243 cfg = getDefaultConfig(outputType, level, defaultFields)
244
Girish Kumarc9b0e712020-02-27 17:50:52 +0000245 l, err := cfg.Build(zp.AddCallerSkip(1))
Scott Baker2c1c4822019-10-16 11:02:41 -0700246 if err != nil {
247 return nil, err
248 }
249
250 defaultLogger = &logger{
251 log: l.Sugar(),
252 parent: l,
253 }
254
255 return defaultLogger, nil
256}
257
258// AddPackage registers a package to the log map. Each package gets its own logger which allows
259// its config (loglevel) to be changed dynamically without interacting with the other packages.
260// outputType is JSON, level is the lowest level log to output with this logger and defaultFields is a map of
261// key-value pairs to always add to the output.
262// Note: AddPackage also returns a reference to the actual logger. If a calling package uses this reference directly
263//instead of using the publicly available functions in this log package then a number of functionalities will not
264// be available to it, notably log tracing with filename.functionname.linenumber annotation.
265//
266// pkgNames parameter should be used for testing only as this function detects the caller's package.
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000267func AddPackage(outputType string, level LogLevel, defaultFields Fields, pkgNames ...string) (Logger, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700268 if cfgs == nil {
269 cfgs = make(map[string]zp.Config)
270 }
271 if loggers == nil {
272 loggers = make(map[string]*logger)
273 }
274
275 var pkgName string
276 for _, name := range pkgNames {
277 pkgName = name
278 break
279 }
280 if pkgName == "" {
281 pkgName, _, _, _ = getCallerInfo()
282 }
283
284 if _, exist := loggers[pkgName]; exist {
285 return loggers[pkgName], nil
286 }
287
288 cfgs[pkgName] = getDefaultConfig(outputType, level, defaultFields)
289
Girish Kumarc9b0e712020-02-27 17:50:52 +0000290 l, err := cfgs[pkgName].Build(zp.AddCallerSkip(1))
Scott Baker2c1c4822019-10-16 11:02:41 -0700291 if err != nil {
292 return nil, err
293 }
294
295 loggers[pkgName] = &logger{
khenaidoob332f9b2020-01-16 16:25:26 -0500296 log: l.Sugar(),
297 parent: l,
298 packageName: pkgName,
Scott Baker2c1c4822019-10-16 11:02:41 -0700299 }
300 return loggers[pkgName], nil
301}
302
303//UpdateAllLoggers create new loggers for all registered pacakges with the defaultFields.
304func UpdateAllLoggers(defaultFields Fields) error {
305 for pkgName, cfg := range cfgs {
306 for k, v := range defaultFields {
307 if cfg.InitialFields == nil {
308 cfg.InitialFields = make(map[string]interface{})
309 }
310 cfg.InitialFields[k] = v
311 }
Girish Kumarc9b0e712020-02-27 17:50:52 +0000312 l, err := cfg.Build(zp.AddCallerSkip(1))
Scott Baker2c1c4822019-10-16 11:02:41 -0700313 if err != nil {
314 return err
315 }
316
Girish Kumarc9b0e712020-02-27 17:50:52 +0000317 // Update the existing zap logger instance
318 loggers[pkgName].log = l.Sugar()
319 loggers[pkgName].parent = l
Scott Baker2c1c4822019-10-16 11:02:41 -0700320 }
321 return nil
322}
323
324// Return a list of all packages that have individually-configured loggers
325func GetPackageNames() []string {
326 i := 0
327 keys := make([]string, len(loggers))
328 for k := range loggers {
329 keys[i] = k
330 i++
331 }
332 return keys
333}
334
Girish Kumarc9b0e712020-02-27 17:50:52 +0000335// UpdateLogger updates the logger associated with a caller's package with supplied defaultFields
336func UpdateLogger(defaultFields Fields) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700337 pkgName, _, _, _ := getCallerInfo()
338 if _, exist := loggers[pkgName]; !exist {
Girish Kumarc9b0e712020-02-27 17:50:52 +0000339 return fmt.Errorf("package-%s-not-registered", pkgName)
Scott Baker2c1c4822019-10-16 11:02:41 -0700340 }
341
342 // Build a new logger
343 if _, exist := cfgs[pkgName]; !exist {
Girish Kumarc9b0e712020-02-27 17:50:52 +0000344 return fmt.Errorf("config-%s-not-registered", pkgName)
Scott Baker2c1c4822019-10-16 11:02:41 -0700345 }
346
347 cfg := cfgs[pkgName]
348 for k, v := range defaultFields {
349 if cfg.InitialFields == nil {
350 cfg.InitialFields = make(map[string]interface{})
351 }
352 cfg.InitialFields[k] = v
353 }
Girish Kumarc9b0e712020-02-27 17:50:52 +0000354 l, err := cfg.Build(zp.AddCallerSkip(1))
Scott Baker2c1c4822019-10-16 11:02:41 -0700355 if err != nil {
Girish Kumarc9b0e712020-02-27 17:50:52 +0000356 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700357 }
358
Girish Kumarc9b0e712020-02-27 17:50:52 +0000359 // Update the existing zap logger instance
360 loggers[pkgName].log = l.Sugar()
361 loggers[pkgName].parent = l
362
363 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -0700364}
365
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000366func setLevel(cfg zp.Config, level LogLevel) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700367 switch level {
368 case DebugLevel:
369 cfg.Level.SetLevel(zc.DebugLevel)
370 case InfoLevel:
371 cfg.Level.SetLevel(zc.InfoLevel)
372 case WarnLevel:
373 cfg.Level.SetLevel(zc.WarnLevel)
374 case ErrorLevel:
375 cfg.Level.SetLevel(zc.ErrorLevel)
Scott Baker2c1c4822019-10-16 11:02:41 -0700376 case FatalLevel:
377 cfg.Level.SetLevel(zc.FatalLevel)
378 default:
379 cfg.Level.SetLevel(zc.ErrorLevel)
380 }
381}
382
383//SetPackageLogLevel dynamically sets the log level of a given package to level. This is typically invoked at an
384// application level during debugging
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000385func SetPackageLogLevel(packageName string, level LogLevel) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700386 // Get proper config
387 if cfg, ok := cfgs[packageName]; ok {
388 setLevel(cfg, level)
389 }
390}
391
392//SetAllLogLevel sets the log level of all registered packages to level
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000393func SetAllLogLevel(level LogLevel) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700394 // Get proper config
395 for _, cfg := range cfgs {
396 setLevel(cfg, level)
397 }
398}
399
400//GetPackageLogLevel returns the current log level of a package.
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000401func GetPackageLogLevel(packageName ...string) (LogLevel, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700402 var name string
403 if len(packageName) == 1 {
404 name = packageName[0]
405 } else {
406 name, _, _, _ = getCallerInfo()
407 }
408 if cfg, ok := cfgs[name]; ok {
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000409 return levelToLogLevel(cfg.Level.Level()), nil
Scott Baker2c1c4822019-10-16 11:02:41 -0700410 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800411 return 0, fmt.Errorf("unknown-package-%s", name)
Scott Baker2c1c4822019-10-16 11:02:41 -0700412}
413
414//GetDefaultLogLevel gets the log level used for packages that don't have specific loggers
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000415func GetDefaultLogLevel() LogLevel {
416 return levelToLogLevel(cfg.Level.Level())
Scott Baker2c1c4822019-10-16 11:02:41 -0700417}
418
419//SetLogLevel sets the log level for the logger corresponding to the caller's package
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000420func SetLogLevel(level LogLevel) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700421 pkgName, _, _, _ := getCallerInfo()
422 if _, exist := cfgs[pkgName]; !exist {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800423 return fmt.Errorf("unregistered-package-%s", pkgName)
Scott Baker2c1c4822019-10-16 11:02:41 -0700424 }
425 cfg := cfgs[pkgName]
426 setLevel(cfg, level)
427 return nil
428}
429
430//SetDefaultLogLevel sets the log level used for packages that don't have specific loggers
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000431func SetDefaultLogLevel(level LogLevel) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700432 setLevel(cfg, level)
433}
434
435// CleanUp flushed any buffered log entries. Applications should take care to call
436// CleanUp before exiting.
437func CleanUp() error {
438 for _, logger := range loggers {
439 if logger != nil {
440 if logger.parent != nil {
441 if err := logger.parent.Sync(); err != nil {
442 return err
443 }
444 }
445 }
446 }
447 if defaultLogger != nil {
448 if defaultLogger.parent != nil {
449 if err := defaultLogger.parent.Sync(); err != nil {
450 return err
451 }
452 }
453 }
454 return nil
455}
456
457func getCallerInfo() (string, string, string, int) {
458 // Since the caller of a log function is one stack frame before (in terms of stack higher level) the log.go
459 // filename, then first look for the last log.go filename and then grab the caller info one level higher.
460 maxLevel := 3
461 skiplevel := 3 // Level with the most empirical success to see the last log.go stack frame.
462 pc := make([]uintptr, maxLevel)
463 n := runtime.Callers(skiplevel, pc)
464 packageName := ""
465 funcName := ""
466 fileName := ""
467 var line int
468 if n == 0 {
469 return packageName, fileName, funcName, line
470 }
471 frames := runtime.CallersFrames(pc[:n])
472 var frame runtime.Frame
473 var foundFrame runtime.Frame
474 more := true
475 for more {
476 frame, more = frames.Next()
477 _, fileName = path.Split(frame.File)
478 if fileName != "log.go" {
479 foundFrame = frame // First frame after log.go in the frame stack
480 break
481 }
482 }
483 parts := strings.Split(foundFrame.Function, ".")
484 pl := len(parts)
485 if pl >= 2 {
486 funcName = parts[pl-1]
487 if parts[pl-2][0] == '(' {
488 packageName = strings.Join(parts[0:pl-2], ".")
489 } else {
490 packageName = strings.Join(parts[0:pl-1], ".")
491 }
492 }
493
494 if strings.HasSuffix(packageName, ".init") {
495 packageName = strings.TrimSuffix(packageName, ".init")
496 }
497
498 if strings.HasSuffix(fileName, ".go") {
499 fileName = strings.TrimSuffix(fileName, ".go")
500 }
501
502 return packageName, fileName, funcName, foundFrame.Line
503}
504
505func getPackageLevelSugaredLogger() *zp.SugaredLogger {
Girish Kumare6f45e82020-03-20 10:46:54 +0000506 pkgName, _, _, _ := getCallerInfo()
Scott Baker2c1c4822019-10-16 11:02:41 -0700507 if _, exist := loggers[pkgName]; exist {
Girish Kumare6f45e82020-03-20 10:46:54 +0000508 return loggers[pkgName].log
Scott Baker2c1c4822019-10-16 11:02:41 -0700509 }
Girish Kumare6f45e82020-03-20 10:46:54 +0000510 return defaultLogger.log
Scott Baker2c1c4822019-10-16 11:02:41 -0700511}
512
513func getPackageLevelLogger() Logger {
514 pkgName, _, _, _ := getCallerInfo()
515 if _, exist := loggers[pkgName]; exist {
516 return loggers[pkgName]
517 }
518 return defaultLogger
519}
520
521func serializeMap(fields Fields) []interface{} {
522 data := make([]interface{}, len(fields)*2)
523 i := 0
524 for k, v := range fields {
525 data[i] = k
526 data[i+1] = v
527 i = i + 2
528 }
529 return data
530}
531
532// With returns a logger initialized with the key-value pairs
533func (l logger) With(keysAndValues Fields) Logger {
534 return logger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
535}
536
537// Debug logs a message at level Debug on the standard logger.
538func (l logger) Debug(args ...interface{}) {
539 l.log.Debug(args...)
540}
541
542// Debugln logs a message at level Debug on the standard logger with a line feed. Default in any case.
543func (l logger) Debugln(args ...interface{}) {
544 l.log.Debug(args...)
545}
546
547// Debugw logs a message at level Debug on the standard logger.
548func (l logger) Debugf(format string, args ...interface{}) {
549 l.log.Debugf(format, args...)
550}
551
552// Debugw logs a message with some additional context. The variadic key-value
553// pairs are treated as they are in With.
554func (l logger) Debugw(msg string, keysAndValues Fields) {
555 l.log.Debugw(msg, serializeMap(keysAndValues)...)
556}
557
558// Info logs a message at level Info on the standard logger.
559func (l logger) Info(args ...interface{}) {
560 l.log.Info(args...)
561}
562
563// Infoln logs a message at level Info on the standard logger with a line feed. Default in any case.
564func (l logger) Infoln(args ...interface{}) {
565 l.log.Info(args...)
566 //msg := fmt.Sprintln(args...)
567 //l.sourced().Info(msg[:len(msg)-1])
568}
569
570// Infof logs a message at level Info on the standard logger.
571func (l logger) Infof(format string, args ...interface{}) {
572 l.log.Infof(format, args...)
573}
574
575// Infow logs a message with some additional context. The variadic key-value
576// pairs are treated as they are in With.
577func (l logger) Infow(msg string, keysAndValues Fields) {
578 l.log.Infow(msg, serializeMap(keysAndValues)...)
579}
580
581// Warn logs a message at level Warn on the standard logger.
582func (l logger) Warn(args ...interface{}) {
583 l.log.Warn(args...)
584}
585
586// Warnln logs a message at level Warn on the standard logger with a line feed. Default in any case.
587func (l logger) Warnln(args ...interface{}) {
588 l.log.Warn(args...)
589}
590
591// Warnf logs a message at level Warn on the standard logger.
592func (l logger) Warnf(format string, args ...interface{}) {
593 l.log.Warnf(format, args...)
594}
595
596// Warnw logs a message with some additional context. The variadic key-value
597// pairs are treated as they are in With.
598func (l logger) Warnw(msg string, keysAndValues Fields) {
599 l.log.Warnw(msg, serializeMap(keysAndValues)...)
600}
601
602// Error logs a message at level Error on the standard logger.
603func (l logger) Error(args ...interface{}) {
604 l.log.Error(args...)
605}
606
607// Errorln logs a message at level Error on the standard logger with a line feed. Default in any case.
608func (l logger) Errorln(args ...interface{}) {
609 l.log.Error(args...)
610}
611
612// Errorf logs a message at level Error on the standard logger.
613func (l logger) Errorf(format string, args ...interface{}) {
614 l.log.Errorf(format, args...)
615}
616
617// Errorw logs a message with some additional context. The variadic key-value
618// pairs are treated as they are in With.
619func (l logger) Errorw(msg string, keysAndValues Fields) {
620 l.log.Errorw(msg, serializeMap(keysAndValues)...)
621}
622
623// Fatal logs a message at level Fatal on the standard logger.
624func (l logger) Fatal(args ...interface{}) {
625 l.log.Fatal(args...)
626}
627
628// Fatalln logs a message at level Fatal on the standard logger with a line feed. Default in any case.
629func (l logger) Fatalln(args ...interface{}) {
630 l.log.Fatal(args...)
631}
632
633// Fatalf logs a message at level Fatal on the standard logger.
634func (l logger) Fatalf(format string, args ...interface{}) {
635 l.log.Fatalf(format, args...)
636}
637
638// Fatalw logs a message with some additional context. The variadic key-value
639// pairs are treated as they are in With.
640func (l logger) Fatalw(msg string, keysAndValues Fields) {
641 l.log.Fatalw(msg, serializeMap(keysAndValues)...)
642}
643
644// Warning logs a message at level Warn on the standard logger.
645func (l logger) Warning(args ...interface{}) {
646 l.log.Warn(args...)
647}
648
649// Warningln logs a message at level Warn on the standard logger with a line feed. Default in any case.
650func (l logger) Warningln(args ...interface{}) {
651 l.log.Warn(args...)
652}
653
654// Warningf logs a message at level Warn on the standard logger.
655func (l logger) Warningf(format string, args ...interface{}) {
656 l.log.Warnf(format, args...)
657}
658
659// V reports whether verbosity level l is at least the requested verbose level.
Scott Bakerd7c25f42020-02-21 08:12:06 -0800660func (l logger) V(level LogLevel) bool {
661 return l.parent.Core().Enabled(logLevelToLevel(level))
Scott Baker2c1c4822019-10-16 11:02:41 -0700662}
663
khenaidoob332f9b2020-01-16 16:25:26 -0500664// GetLogLevel returns the current level of the logger
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000665func (l logger) GetLogLevel() LogLevel {
666 return levelToLogLevel(cfgs[l.packageName].Level.Level())
khenaidoob332f9b2020-01-16 16:25:26 -0500667}
668
Scott Baker2c1c4822019-10-16 11:02:41 -0700669// With returns a logger initialized with the key-value pairs
670func With(keysAndValues Fields) Logger {
671 return logger{log: getPackageLevelSugaredLogger().With(serializeMap(keysAndValues)...), parent: defaultLogger.parent}
672}
673
674// Debug logs a message at level Debug on the standard logger.
675func Debug(args ...interface{}) {
676 getPackageLevelSugaredLogger().Debug(args...)
677}
678
679// Debugln logs a message at level Debug on the standard logger.
680func Debugln(args ...interface{}) {
681 getPackageLevelSugaredLogger().Debug(args...)
682}
683
684// Debugf logs a message at level Debug on the standard logger.
685func Debugf(format string, args ...interface{}) {
686 getPackageLevelSugaredLogger().Debugf(format, args...)
687}
688
689// Debugw logs a message with some additional context. The variadic key-value
690// pairs are treated as they are in With.
691func Debugw(msg string, keysAndValues Fields) {
692 getPackageLevelSugaredLogger().Debugw(msg, serializeMap(keysAndValues)...)
693}
694
695// Info logs a message at level Info on the standard logger.
696func Info(args ...interface{}) {
697 getPackageLevelSugaredLogger().Info(args...)
698}
699
700// Infoln logs a message at level Info on the standard logger.
701func Infoln(args ...interface{}) {
702 getPackageLevelSugaredLogger().Info(args...)
703}
704
705// Infof logs a message at level Info on the standard logger.
706func Infof(format string, args ...interface{}) {
707 getPackageLevelSugaredLogger().Infof(format, args...)
708}
709
710//Infow logs a message with some additional context. The variadic key-value
711//pairs are treated as they are in With.
712func Infow(msg string, keysAndValues Fields) {
713 getPackageLevelSugaredLogger().Infow(msg, serializeMap(keysAndValues)...)
714}
715
716// Warn logs a message at level Warn on the standard logger.
717func Warn(args ...interface{}) {
718 getPackageLevelSugaredLogger().Warn(args...)
719}
720
721// Warnln logs a message at level Warn on the standard logger.
722func Warnln(args ...interface{}) {
723 getPackageLevelSugaredLogger().Warn(args...)
724}
725
726// Warnf logs a message at level Warn on the standard logger.
727func Warnf(format string, args ...interface{}) {
728 getPackageLevelSugaredLogger().Warnf(format, args...)
729}
730
731// Warnw logs a message with some additional context. The variadic key-value
732// pairs are treated as they are in With.
733func Warnw(msg string, keysAndValues Fields) {
734 getPackageLevelSugaredLogger().Warnw(msg, serializeMap(keysAndValues)...)
735}
736
737// Error logs a message at level Error on the standard logger.
738func Error(args ...interface{}) {
739 getPackageLevelSugaredLogger().Error(args...)
740}
741
742// Errorln logs a message at level Error on the standard logger.
743func Errorln(args ...interface{}) {
744 getPackageLevelSugaredLogger().Error(args...)
745}
746
747// Errorf logs a message at level Error on the standard logger.
748func Errorf(format string, args ...interface{}) {
749 getPackageLevelSugaredLogger().Errorf(format, args...)
750}
751
752// Errorw logs a message with some additional context. The variadic key-value
753// pairs are treated as they are in With.
754func Errorw(msg string, keysAndValues Fields) {
755 getPackageLevelSugaredLogger().Errorw(msg, serializeMap(keysAndValues)...)
756}
757
758// Fatal logs a message at level Fatal on the standard logger.
759func Fatal(args ...interface{}) {
760 getPackageLevelSugaredLogger().Fatal(args...)
761}
762
763// Fatalln logs a message at level Fatal on the standard logger.
764func Fatalln(args ...interface{}) {
765 getPackageLevelSugaredLogger().Fatal(args...)
766}
767
768// Fatalf logs a message at level Fatal on the standard logger.
769func Fatalf(format string, args ...interface{}) {
770 getPackageLevelSugaredLogger().Fatalf(format, args...)
771}
772
773// Fatalw logs a message with some additional context. The variadic key-value
774// pairs are treated as they are in With.
775func Fatalw(msg string, keysAndValues Fields) {
776 getPackageLevelSugaredLogger().Fatalw(msg, serializeMap(keysAndValues)...)
777}
778
779// Warning logs a message at level Warn on the standard logger.
780func Warning(args ...interface{}) {
781 getPackageLevelSugaredLogger().Warn(args...)
782}
783
784// Warningln logs a message at level Warn on the standard logger.
785func Warningln(args ...interface{}) {
786 getPackageLevelSugaredLogger().Warn(args...)
787}
788
789// Warningf logs a message at level Warn on the standard logger.
790func Warningf(format string, args ...interface{}) {
791 getPackageLevelSugaredLogger().Warnf(format, args...)
792}
793
794// V reports whether verbosity level l is at least the requested verbose level.
Scott Bakerd7c25f42020-02-21 08:12:06 -0800795func V(level LogLevel) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700796 return getPackageLevelLogger().V(level)
797}
khenaidoob332f9b2020-01-16 16:25:26 -0500798
799//GetLogLevel returns the log level of the invoking package
Rohan Agrawal0c62b5d2020-02-04 09:56:21 +0000800func GetLogLevel() LogLevel {
khenaidoob332f9b2020-01-16 16:25:26 -0500801 return getPackageLevelLogger().GetLogLevel()
802}