blob: 33100dcb0498e4b6c35c5321426d1ba9bd80b5b1 [file] [log] [blame]
khenaidoobf6e7bb2018-08-14 22:27:29 -04001/*
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 */
khenaidoo7da372d2018-09-21 16:03:09 -040016
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
khenaidoocfee5f42018-07-19 22:47:38 -040041package log
42
43import (
khenaidoo7da372d2018-09-21 16:03:09 -040044 "errors"
khenaidoo5c11af72018-07-20 17:21:05 -040045 "fmt"
khenaidoocfee5f42018-07-19 22:47:38 -040046 zp "go.uber.org/zap"
47 zc "go.uber.org/zap/zapcore"
khenaidoob9203542018-09-17 22:56:37 -040048 "path"
khenaidoocfee5f42018-07-19 22:47:38 -040049 "runtime"
50 "strings"
khenaidoocfee5f42018-07-19 22:47:38 -040051)
52
53const (
54 // DebugLevel logs a message at debug level
55 DebugLevel = iota
56 // InfoLevel logs a message at info level
57 InfoLevel
58 // WarnLevel logs a message at warning level
59 WarnLevel
60 // ErrorLevel logs a message at error level
61 ErrorLevel
62 // PanicLevel logs a message, then panics.
63 PanicLevel
64 // 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"
khenaidoo5c11af72018-07-20 17:21:05 -040070
khenaidoocfee5f42018-07-19 22:47:38 -040071// 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
khenaidoo7da372d2018-09-21 16:03:09 -0400103
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.
111 V(l int) bool
khenaidoocfee5f42018-07-19 22:47:38 -0400112}
113
khenaidoo7da372d2018-09-21 16:03:09 -0400114// Fields is used as key-value pairs for structured logging
khenaidoocfee5f42018-07-19 22:47:38 -0400115type Fields map[string]interface{}
116
117var defaultLogger *logger
khenaidoob9203542018-09-17 22:56:37 -0400118var cfg zp.Config
119
120var loggers map[string]*logger
121var cfgs map[string]zp.Config
khenaidoocfee5f42018-07-19 22:47:38 -0400122
123type logger struct {
124 log *zp.SugaredLogger
125 parent *zp.Logger
126}
127
khenaidoo6f2fbe32019-01-18 16:16:50 -0500128func intToAtomicLevel(l int) zp.AtomicLevel {
khenaidoocfee5f42018-07-19 22:47:38 -0400129 switch l {
130 case DebugLevel:
131 return zp.NewAtomicLevelAt(zc.DebugLevel)
132 case InfoLevel:
133 return zp.NewAtomicLevelAt(zc.InfoLevel)
134 case WarnLevel:
135 return zp.NewAtomicLevelAt(zc.WarnLevel)
136 case ErrorLevel:
137 return zp.NewAtomicLevelAt(zc.ErrorLevel)
138 case PanicLevel:
139 return zp.NewAtomicLevelAt(zc.PanicLevel)
140 case FatalLevel:
141 return zp.NewAtomicLevelAt(zc.FatalLevel)
142 }
143 return zp.NewAtomicLevelAt(zc.ErrorLevel)
144}
145
khenaidoo6f2fbe32019-01-18 16:16:50 -0500146func intToLevel(l int) zc.Level {
khenaidoo7da372d2018-09-21 16:03:09 -0400147 switch l {
148 case DebugLevel:
149 return zc.DebugLevel
150 case InfoLevel:
khenaidoo6f2fbe32019-01-18 16:16:50 -0500151 return zc.InfoLevel
khenaidoo7da372d2018-09-21 16:03:09 -0400152 case WarnLevel:
153 return zc.WarnLevel
154 case ErrorLevel:
155 return zc.ErrorLevel
156 case PanicLevel:
157 return zc.PanicLevel
158 case FatalLevel:
159 return zc.FatalLevel
160 }
161 return zc.ErrorLevel
162}
163
khenaidoo6f2fbe32019-01-18 16:16:50 -0500164func levelToInt(l zc.Level) int {
165 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
174 case zc.PanicLevel:
175 return PanicLevel
176 case FatalLevel:
177 return FatalLevel
178 }
179 return ErrorLevel
180}
181
khenaidoocfee5f42018-07-19 22:47:38 -0400182func getDefaultConfig(outputType string, level int, defaultFields Fields) zp.Config {
183 return zp.Config{
khenaidoo6f2fbe32019-01-18 16:16:50 -0500184 Level: intToAtomicLevel(level),
khenaidoocfee5f42018-07-19 22:47:38 -0400185 Encoding: outputType,
186 Development: true,
187 OutputPaths: []string{"stdout"},
188 ErrorOutputPaths: []string{"stderr"},
189 InitialFields: defaultFields,
190 EncoderConfig: zc.EncoderConfig{
191 LevelKey: "level",
192 MessageKey: "msg",
193 TimeKey: "ts",
194 StacktraceKey: "stacktrace",
195 LineEnding: zc.DefaultLineEnding,
196 EncodeLevel: zc.LowercaseLevelEncoder,
197 EncodeTime: zc.ISO8601TimeEncoder,
198 EncodeDuration: zc.SecondsDurationEncoder,
199 EncodeCaller: zc.ShortCallerEncoder,
200 },
201 }
202}
203
204// SetLogger needs to be invoked before the logger API can be invoked. This function
205// initialize the default logger (zap's sugaredlogger)
khenaidoob9203542018-09-17 22:56:37 -0400206func SetDefaultLogger(outputType string, level int, defaultFields Fields) (Logger, error) {
khenaidoocfee5f42018-07-19 22:47:38 -0400207 // Build a custom config using zap
khenaidood4d922e2018-08-03 22:35:16 -0400208 cfg = getDefaultConfig(outputType, level, defaultFields)
khenaidoocfee5f42018-07-19 22:47:38 -0400209
210 l, err := cfg.Build()
211 if err != nil {
212 return nil, err
213 }
214
215 defaultLogger = &logger{
216 log: l.Sugar(),
217 parent: l,
218 }
219
220 return defaultLogger, nil
221}
222
khenaidoo7da372d2018-09-21 16:03:09 -0400223// AddPackage registers a package to the log map. Each package gets its own logger which allows
224// its config (loglevel) to be changed dynamically without interacting with the other packages.
225// outputType is JSON, level is the lowest level log to output with this logger and defaultFields is a map of
226// key-value pairs to always add to the output.
227// Note: AddPackage also returns a reference to the actual logger. If a calling package uses this reference directly
228//instead of using the publicly available functions in this log package then a number of functionalities will not
229// be available to it, notably log tracing with filename.functionname.linenumber annotation.
230//
khenaidoo6f2fbe32019-01-18 16:16:50 -0500231// pkgNames parameter should be used for testing only as this function detects the caller's package.
232func AddPackage(outputType string, level int, defaultFields Fields, pkgNames ...string) (Logger, error) {
khenaidoob9203542018-09-17 22:56:37 -0400233 if cfgs == nil {
234 cfgs = make(map[string]zp.Config)
235 }
236 if loggers == nil {
237 loggers = make(map[string]*logger)
238 }
khenaidoo6f2fbe32019-01-18 16:16:50 -0500239
240 var pkgName string
241 for _, name := range pkgNames {
242 pkgName = name
243 break
244 }
245 if pkgName == "" {
246 pkgName, _, _, _ = getCallerInfo()
247 }
khenaidoob9203542018-09-17 22:56:37 -0400248
khenaidoo7da372d2018-09-21 16:03:09 -0400249 if _, exist := loggers[pkgName]; exist {
250 return loggers[pkgName], nil
khenaidoob9203542018-09-17 22:56:37 -0400251 }
khenaidoo7da372d2018-09-21 16:03:09 -0400252
khenaidoob9203542018-09-17 22:56:37 -0400253 cfgs[pkgName] = getDefaultConfig(outputType, level, defaultFields)
254
255 l, err := cfgs[pkgName].Build()
256 if err != nil {
khenaidoo7da372d2018-09-21 16:03:09 -0400257 return nil, err
khenaidoob9203542018-09-17 22:56:37 -0400258 }
259
260 loggers[pkgName] = &logger{
261 log: l.Sugar(),
262 parent: l,
263 }
khenaidoo7da372d2018-09-21 16:03:09 -0400264 return loggers[pkgName], nil
khenaidoob9203542018-09-17 22:56:37 -0400265}
266
khenaidoo7da372d2018-09-21 16:03:09 -0400267//UpdateAllLoggers create new loggers for all registered pacakges with the defaultFields.
khenaidoob9203542018-09-17 22:56:37 -0400268func UpdateAllLoggers(defaultFields Fields) error {
269 for pkgName, cfg := range cfgs {
270 for k, v := range defaultFields {
271 if cfg.InitialFields == nil {
272 cfg.InitialFields = make(map[string]interface{})
273 }
274 cfg.InitialFields[k] = v
275 }
276 l, err := cfg.Build()
277 if err != nil {
278 return err
279 }
280
281 loggers[pkgName] = &logger{
282 log: l.Sugar(),
283 parent: l,
284 }
285 }
286 return nil
287}
288
khenaidoo7da372d2018-09-21 16:03:09 -0400289// UpdateLogger deletes the logger associated with a caller's package and creates a new logger with the
290// defaultFields. If a calling package is holding on to a Logger reference obtained from AddPackage invocation, then
291// that package needs to invoke UpdateLogger if it needs to make changes to the default fields and obtain a new logger
292// reference
293func UpdateLogger(defaultFields Fields) (Logger, error) {
294 pkgName, _, _, _ := getCallerInfo()
295 if _, exist := loggers[pkgName]; !exist {
296 return nil, errors.New(fmt.Sprintf("package-%s-not-registered", pkgName))
297 }
khenaidoob9203542018-09-17 22:56:37 -0400298
khenaidoo7da372d2018-09-21 16:03:09 -0400299 // Build a new logger
300 if _, exist := cfgs[pkgName]; !exist {
301 return nil, errors.New(fmt.Sprintf("config-%s-not-registered", pkgName))
302 }
303
304 cfg := cfgs[pkgName]
305 for k, v := range defaultFields {
306 if cfg.InitialFields == nil {
307 cfg.InitialFields = make(map[string]interface{})
308 }
309 cfg.InitialFields[k] = v
310 }
311 l, err := cfg.Build()
312 if err != nil {
313 return nil, err
314 }
315
316 // Set the logger
317 loggers[pkgName] = &logger{
318 log: l.Sugar(),
319 parent: l,
320 }
321 return loggers[pkgName], nil
322}
323
khenaidoo6f2fbe32019-01-18 16:16:50 -0500324func setLevel(cfg zp.Config, level int) {
khenaidoo7da372d2018-09-21 16:03:09 -0400325 switch level {
326 case DebugLevel:
327 cfg.Level.SetLevel(zc.DebugLevel)
328 case InfoLevel:
329 cfg.Level.SetLevel(zc.InfoLevel)
330 case WarnLevel:
331 cfg.Level.SetLevel(zc.WarnLevel)
332 case ErrorLevel:
333 cfg.Level.SetLevel(zc.ErrorLevel)
334 case PanicLevel:
335 cfg.Level.SetLevel(zc.PanicLevel)
336 case FatalLevel:
337 cfg.Level.SetLevel(zc.FatalLevel)
338 default:
339 cfg.Level.SetLevel(zc.ErrorLevel)
340 }
khenaidoo6f2fbe32019-01-18 16:16:50 -0500341}
342
343//SetPackageLogLevel dynamically sets the log level of a given package to level. This is typically invoked at an
344// application level during debugging
345func SetPackageLogLevel(packageName string, level int) {
346 // Get proper config
347 if cfg, ok := cfgs[packageName]; ok {
348 setLevel(cfg, level)
349 }
350}
351
352//SetAllLogLevel sets the log level of all registered packages to level
353func SetAllLogLevel(level int) {
354 // Get proper config
355 for _, cfg := range cfgs {
356 setLevel(cfg, level)
357 }
358}
359
360//GetPackageLogLevel returns the current log level of a package.
khenaidoo910204f2019-04-08 17:56:40 -0400361func GetPackageLogLevel(packageName ...string) (int, error) {
362 var name string
363 if len(packageName) == 1 {
364 name = packageName[0]
365 } else {
366 name, _, _, _ = getCallerInfo()
367 }
368 if cfg, ok := cfgs[name]; ok {
khenaidoo6f2fbe32019-01-18 16:16:50 -0500369 return levelToInt(cfg.Level.Level()), nil
370 }
khenaidoo910204f2019-04-08 17:56:40 -0400371 return 0, errors.New(fmt.Sprintf("unknown-package-%s", name))
khenaidoo6f2fbe32019-01-18 16:16:50 -0500372}
373
374//SetLogLevel sets the log level for the logger corresponding to the caller's package
375func SetLogLevel(level int) error {
376 pkgName, _, _, _ := getCallerInfo()
377 if _, exist := cfgs[pkgName]; !exist {
378 return errors.New(fmt.Sprintf("unregistered-package-%s", pkgName))
379 }
380 cfg := cfgs[pkgName]
381 setLevel(cfg, level)
khenaidoo7da372d2018-09-21 16:03:09 -0400382 return nil
383}
384
khenaidoocfee5f42018-07-19 22:47:38 -0400385// CleanUp flushed any buffered log entries. Applications should take care to call
386// CleanUp before exiting.
387func CleanUp() error {
khenaidoob9203542018-09-17 22:56:37 -0400388 for _, logger := range loggers {
389 if logger != nil {
390 if logger.parent != nil {
391 if err := logger.parent.Sync(); err != nil {
392 return err
393 }
394 }
395 }
396 }
khenaidoocfee5f42018-07-19 22:47:38 -0400397 if defaultLogger != nil {
398 if defaultLogger.parent != nil {
399 if err := defaultLogger.parent.Sync(); err != nil {
400 return err
401 }
402 }
403 }
404 return nil
405}
406
khenaidoo7da372d2018-09-21 16:03:09 -0400407func getCallerInfo() (string, string, string, int) {
khenaidoo2c6f1672018-09-20 23:14:41 -0400408 // Since the caller of a log function is one stack frame before (in terms of stack higher level) the log.go
409 // filename, then first look for the last log.go filename and then grab the caller info one level higher.
410 maxLevel := 3
khenaidoo7da372d2018-09-21 16:03:09 -0400411 skiplevel := 3 // Level with the most empirical success to see the last log.go stack frame.
khenaidoo2c6f1672018-09-20 23:14:41 -0400412 pc := make([]uintptr, maxLevel)
413 n := runtime.Callers(skiplevel, pc)
khenaidoob9203542018-09-17 22:56:37 -0400414 packageName := ""
khenaidoo2c6f1672018-09-20 23:14:41 -0400415 funcName := ""
416 fileName := ""
417 var line int
418 if n == 0 {
419 return packageName, fileName, funcName, line
420 }
421 frames := runtime.CallersFrames(pc[:n])
422 var frame runtime.Frame
423 var foundFrame runtime.Frame
424 more := true
425 for more {
426 frame, more = frames.Next()
427 _, fileName = path.Split(frame.File)
428 if fileName != "log.go" {
429 foundFrame = frame // First frame after log.go in the frame stack
430 break
431 }
432 }
433 parts := strings.Split(foundFrame.Function, ".")
434 pl := len(parts)
435 if pl >= 2 {
436 funcName = parts[pl-1]
437 if parts[pl-2][0] == '(' {
438 packageName = strings.Join(parts[0:pl-2], ".")
439 } else {
440 packageName = strings.Join(parts[0:pl-1], ".")
441 }
khenaidoocfee5f42018-07-19 22:47:38 -0400442 }
443
khenaidoo2c6f1672018-09-20 23:14:41 -0400444 if strings.HasSuffix(packageName, ".init") {
khenaidoo7da372d2018-09-21 16:03:09 -0400445 packageName = strings.TrimSuffix(packageName, ".init")
khenaidoob9203542018-09-17 22:56:37 -0400446 }
447
448 if strings.HasSuffix(fileName, ".go") {
khenaidoo7da372d2018-09-21 16:03:09 -0400449 fileName = strings.TrimSuffix(fileName, ".go")
khenaidoob9203542018-09-17 22:56:37 -0400450 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400451
452 return packageName, fileName, funcName, foundFrame.Line
khenaidoob9203542018-09-17 22:56:37 -0400453}
454
khenaidoo7da372d2018-09-21 16:03:09 -0400455func getPackageLevelSugaredLogger() *zp.SugaredLogger {
khenaidoob9203542018-09-17 22:56:37 -0400456 pkgName, fileName, funcName, line := getCallerInfo()
457 if _, exist := loggers[pkgName]; exist {
458 return loggers[pkgName].log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
459 }
460 return defaultLogger.log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
461}
khenaidoocfee5f42018-07-19 22:47:38 -0400462
khenaidoo7da372d2018-09-21 16:03:09 -0400463func getPackageLevelLogger() Logger {
464 pkgName, _, _, _ := getCallerInfo()
465 if _, exist := loggers[pkgName]; exist {
466 return loggers[pkgName]
467 }
468 return defaultLogger
469}
470
khenaidoocfee5f42018-07-19 22:47:38 -0400471func serializeMap(fields Fields) []interface{} {
472 data := make([]interface{}, len(fields)*2)
473 i := 0
474 for k, v := range fields {
475 data[i] = k
476 data[i+1] = v
477 i = i + 2
478 }
479 return data
480}
481
482// With returns a logger initialized with the key-value pairs
483func (l logger) With(keysAndValues Fields) Logger {
484 return logger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
485}
486
487// Debug logs a message at level Debug on the standard logger.
488func (l logger) Debug(args ...interface{}) {
489 l.log.Debug(args...)
490}
491
492// Debugln logs a message at level Debug on the standard logger with a line feed. Default in any case.
493func (l logger) Debugln(args ...interface{}) {
494 l.log.Debug(args...)
495}
496
497// Debugw logs a message at level Debug on the standard logger.
498func (l logger) Debugf(format string, args ...interface{}) {
499 l.log.Debugf(format, args...)
500}
501
502// Debugw logs a message with some additional context. The variadic key-value
503// pairs are treated as they are in With.
504func (l logger) Debugw(msg string, keysAndValues Fields) {
505 l.log.Debugw(msg, serializeMap(keysAndValues)...)
506}
507
508// Info logs a message at level Info on the standard logger.
509func (l logger) Info(args ...interface{}) {
510 l.log.Info(args...)
511}
512
513// Infoln logs a message at level Info on the standard logger with a line feed. Default in any case.
514func (l logger) Infoln(args ...interface{}) {
515 l.log.Info(args...)
516 //msg := fmt.Sprintln(args...)
517 //l.sourced().Info(msg[:len(msg)-1])
518}
519
520// Infof logs a message at level Info on the standard logger.
521func (l logger) Infof(format string, args ...interface{}) {
522 l.log.Infof(format, args...)
523}
524
525// Infow logs a message with some additional context. The variadic key-value
526// pairs are treated as they are in With.
527func (l logger) Infow(msg string, keysAndValues Fields) {
528 l.log.Infow(msg, serializeMap(keysAndValues)...)
529}
530
531// Warn logs a message at level Warn on the standard logger.
532func (l logger) Warn(args ...interface{}) {
533 l.log.Warn(args...)
534}
535
536// Warnln logs a message at level Warn on the standard logger with a line feed. Default in any case.
537func (l logger) Warnln(args ...interface{}) {
538 l.log.Warn(args...)
539}
540
541// Warnf logs a message at level Warn on the standard logger.
542func (l logger) Warnf(format string, args ...interface{}) {
543 l.log.Warnf(format, args...)
544}
545
546// Warnw logs a message with some additional context. The variadic key-value
547// pairs are treated as they are in With.
548func (l logger) Warnw(msg string, keysAndValues Fields) {
549 l.log.Warnw(msg, serializeMap(keysAndValues)...)
550}
551
552// Error logs a message at level Error on the standard logger.
553func (l logger) Error(args ...interface{}) {
554 l.log.Error(args...)
555}
556
557// Errorln logs a message at level Error on the standard logger with a line feed. Default in any case.
558func (l logger) Errorln(args ...interface{}) {
559 l.log.Error(args...)
560}
561
562// Errorf logs a message at level Error on the standard logger.
563func (l logger) Errorf(format string, args ...interface{}) {
564 l.log.Errorf(format, args...)
565}
566
567// Errorw logs a message with some additional context. The variadic key-value
568// pairs are treated as they are in With.
569func (l logger) Errorw(msg string, keysAndValues Fields) {
570 l.log.Errorw(msg, serializeMap(keysAndValues)...)
571}
572
573// Fatal logs a message at level Fatal on the standard logger.
574func (l logger) Fatal(args ...interface{}) {
575 l.log.Fatal(args...)
576}
577
578// Fatalln logs a message at level Fatal on the standard logger with a line feed. Default in any case.
579func (l logger) Fatalln(args ...interface{}) {
580 l.log.Fatal(args...)
581}
582
583// Fatalf logs a message at level Fatal on the standard logger.
584func (l logger) Fatalf(format string, args ...interface{}) {
585 l.log.Fatalf(format, args...)
586}
587
588// Fatalw logs a message with some additional context. The variadic key-value
589// pairs are treated as they are in With.
590func (l logger) Fatalw(msg string, keysAndValues Fields) {
591 l.log.Fatalw(msg, serializeMap(keysAndValues)...)
592}
593
khenaidoo7da372d2018-09-21 16:03:09 -0400594// Warning logs a message at level Warn on the standard logger.
595func (l logger) Warning(args ...interface{}) {
596 l.log.Warn(args...)
597}
598
599// Warningln logs a message at level Warn on the standard logger with a line feed. Default in any case.
600func (l logger) Warningln(args ...interface{}) {
601 l.log.Warn(args...)
602}
603
604// Warningf logs a message at level Warn on the standard logger.
605func (l logger) Warningf(format string, args ...interface{}) {
606 l.log.Warnf(format, args...)
607}
608
609// V reports whether verbosity level l is at least the requested verbose level.
610func (l logger) V(level int) bool {
khenaidoo6f2fbe32019-01-18 16:16:50 -0500611 return l.parent.Core().Enabled(intToLevel(level))
khenaidoo7da372d2018-09-21 16:03:09 -0400612}
613
khenaidoocfee5f42018-07-19 22:47:38 -0400614// With returns a logger initialized with the key-value pairs
615func With(keysAndValues Fields) Logger {
khenaidoo7da372d2018-09-21 16:03:09 -0400616 return logger{log: getPackageLevelSugaredLogger().With(serializeMap(keysAndValues)...), parent: defaultLogger.parent}
khenaidoocfee5f42018-07-19 22:47:38 -0400617}
618
619// Debug logs a message at level Debug on the standard logger.
620func Debug(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400621 getPackageLevelSugaredLogger().Debug(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400622}
623
624// Debugln logs a message at level Debug on the standard logger.
625func Debugln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400626 getPackageLevelSugaredLogger().Debug(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400627}
628
629// Debugf logs a message at level Debug on the standard logger.
630func Debugf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400631 getPackageLevelSugaredLogger().Debugf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400632}
633
634// Debugw logs a message with some additional context. The variadic key-value
635// pairs are treated as they are in With.
636func Debugw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400637 getPackageLevelSugaredLogger().Debugw(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400638}
639
640// Info logs a message at level Info on the standard logger.
641func Info(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400642 getPackageLevelSugaredLogger().Info(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400643}
644
645// Infoln logs a message at level Info on the standard logger.
646func Infoln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400647 getPackageLevelSugaredLogger().Info(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400648}
649
650// Infof logs a message at level Info on the standard logger.
651func Infof(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400652 getPackageLevelSugaredLogger().Infof(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400653}
654
655//Infow logs a message with some additional context. The variadic key-value
656//pairs are treated as they are in With.
657func Infow(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400658 getPackageLevelSugaredLogger().Infow(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400659}
660
661// Warn logs a message at level Warn on the standard logger.
662func Warn(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400663 getPackageLevelSugaredLogger().Warn(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400664}
665
666// Warnln logs a message at level Warn on the standard logger.
667func Warnln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400668 getPackageLevelSugaredLogger().Warn(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400669}
670
671// Warnf logs a message at level Warn on the standard logger.
672func Warnf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400673 getPackageLevelSugaredLogger().Warnf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400674}
675
676// Warnw logs a message with some additional context. The variadic key-value
677// pairs are treated as they are in With.
678func Warnw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400679 getPackageLevelSugaredLogger().Warnw(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400680}
681
682// Error logs a message at level Error on the standard logger.
683func Error(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400684 getPackageLevelSugaredLogger().Error(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400685}
686
687// Errorln logs a message at level Error on the standard logger.
688func Errorln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400689 getPackageLevelSugaredLogger().Error(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400690}
691
692// Errorf logs a message at level Error on the standard logger.
693func Errorf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400694 getPackageLevelSugaredLogger().Errorf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400695}
696
697// Errorw logs a message with some additional context. The variadic key-value
698// pairs are treated as they are in With.
699func Errorw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400700 getPackageLevelSugaredLogger().Errorw(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400701}
702
703// Fatal logs a message at level Fatal on the standard logger.
704func Fatal(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400705 getPackageLevelSugaredLogger().Fatal(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400706}
707
708// Fatalln logs a message at level Fatal on the standard logger.
709func Fatalln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400710 getPackageLevelSugaredLogger().Fatal(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400711}
712
713// Fatalf logs a message at level Fatal on the standard logger.
714func Fatalf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400715 getPackageLevelSugaredLogger().Fatalf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400716}
717
718// Fatalw logs a message with some additional context. The variadic key-value
719// pairs are treated as they are in With.
720func Fatalw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400721 getPackageLevelSugaredLogger().Fatalw(msg, serializeMap(keysAndValues)...)
722}
723
724// Warning logs a message at level Warn on the standard logger.
725func Warning(args ...interface{}) {
726 getPackageLevelSugaredLogger().Warn(args...)
727}
728
729// Warningln logs a message at level Warn on the standard logger.
730func Warningln(args ...interface{}) {
731 getPackageLevelSugaredLogger().Warn(args...)
732}
733
734// Warningf logs a message at level Warn on the standard logger.
735func Warningf(format string, args ...interface{}) {
736 getPackageLevelSugaredLogger().Warnf(format, args...)
737}
738
739// V reports whether verbosity level l is at least the requested verbose level.
740func V(level int) bool {
741 return getPackageLevelLogger().V(level)
khenaidoocfee5f42018-07-19 22:47:38 -0400742}