blob: 0128b7d02a348bd18b0649a3161bb35af2815994 [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
khenaidoo7da372d2018-09-21 16:03:09 -0400128func parseAtomicLevel(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
khenaidoo7da372d2018-09-21 16:03:09 -0400146func parseLevel(l int) zc.Level {
147 switch l {
148 case DebugLevel:
149 return zc.DebugLevel
150 case InfoLevel:
151 return InfoLevel
152 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
khenaidoocfee5f42018-07-19 22:47:38 -0400164func getDefaultConfig(outputType string, level int, defaultFields Fields) zp.Config {
165 return zp.Config{
khenaidoo7da372d2018-09-21 16:03:09 -0400166 Level: parseAtomicLevel(level),
khenaidoocfee5f42018-07-19 22:47:38 -0400167 Encoding: outputType,
168 Development: true,
169 OutputPaths: []string{"stdout"},
170 ErrorOutputPaths: []string{"stderr"},
171 InitialFields: defaultFields,
172 EncoderConfig: zc.EncoderConfig{
173 LevelKey: "level",
174 MessageKey: "msg",
175 TimeKey: "ts",
176 StacktraceKey: "stacktrace",
177 LineEnding: zc.DefaultLineEnding,
178 EncodeLevel: zc.LowercaseLevelEncoder,
179 EncodeTime: zc.ISO8601TimeEncoder,
180 EncodeDuration: zc.SecondsDurationEncoder,
181 EncodeCaller: zc.ShortCallerEncoder,
182 },
183 }
184}
185
186// SetLogger needs to be invoked before the logger API can be invoked. This function
187// initialize the default logger (zap's sugaredlogger)
khenaidoob9203542018-09-17 22:56:37 -0400188func SetDefaultLogger(outputType string, level int, defaultFields Fields) (Logger, error) {
khenaidoocfee5f42018-07-19 22:47:38 -0400189 // Build a custom config using zap
khenaidood4d922e2018-08-03 22:35:16 -0400190 cfg = getDefaultConfig(outputType, level, defaultFields)
khenaidoocfee5f42018-07-19 22:47:38 -0400191
192 l, err := cfg.Build()
193 if err != nil {
194 return nil, err
195 }
196
197 defaultLogger = &logger{
198 log: l.Sugar(),
199 parent: l,
200 }
201
202 return defaultLogger, nil
203}
204
khenaidoo7da372d2018-09-21 16:03:09 -0400205// AddPackage registers a package to the log map. Each package gets its own logger which allows
206// its config (loglevel) to be changed dynamically without interacting with the other packages.
207// outputType is JSON, level is the lowest level log to output with this logger and defaultFields is a map of
208// key-value pairs to always add to the output.
209// Note: AddPackage also returns a reference to the actual logger. If a calling package uses this reference directly
210//instead of using the publicly available functions in this log package then a number of functionalities will not
211// be available to it, notably log tracing with filename.functionname.linenumber annotation.
212//
213func AddPackage(outputType string, level int, defaultFields Fields) (Logger, error) {
khenaidoob9203542018-09-17 22:56:37 -0400214 if cfgs == nil {
215 cfgs = make(map[string]zp.Config)
216 }
217 if loggers == nil {
218 loggers = make(map[string]*logger)
219 }
220 pkgName, _, _, _ := getCallerInfo()
221
khenaidoo7da372d2018-09-21 16:03:09 -0400222 if _, exist := loggers[pkgName]; exist {
223 return loggers[pkgName], nil
khenaidoob9203542018-09-17 22:56:37 -0400224 }
khenaidoo7da372d2018-09-21 16:03:09 -0400225
khenaidoob9203542018-09-17 22:56:37 -0400226 cfgs[pkgName] = getDefaultConfig(outputType, level, defaultFields)
227
228 l, err := cfgs[pkgName].Build()
229 if err != nil {
khenaidoo7da372d2018-09-21 16:03:09 -0400230 return nil, err
khenaidoob9203542018-09-17 22:56:37 -0400231 }
232
233 loggers[pkgName] = &logger{
234 log: l.Sugar(),
235 parent: l,
236 }
khenaidoo7da372d2018-09-21 16:03:09 -0400237 return loggers[pkgName], nil
khenaidoob9203542018-09-17 22:56:37 -0400238}
239
khenaidoo7da372d2018-09-21 16:03:09 -0400240//UpdateAllLoggers create new loggers for all registered pacakges with the defaultFields.
khenaidoob9203542018-09-17 22:56:37 -0400241func UpdateAllLoggers(defaultFields Fields) error {
242 for pkgName, cfg := range cfgs {
243 for k, v := range defaultFields {
244 if cfg.InitialFields == nil {
245 cfg.InitialFields = make(map[string]interface{})
246 }
247 cfg.InitialFields[k] = v
248 }
249 l, err := cfg.Build()
250 if err != nil {
251 return err
252 }
253
254 loggers[pkgName] = &logger{
255 log: l.Sugar(),
256 parent: l,
257 }
258 }
259 return nil
260}
261
khenaidoo7da372d2018-09-21 16:03:09 -0400262// UpdateLogger deletes the logger associated with a caller's package and creates a new logger with the
263// defaultFields. If a calling package is holding on to a Logger reference obtained from AddPackage invocation, then
264// that package needs to invoke UpdateLogger if it needs to make changes to the default fields and obtain a new logger
265// reference
266func UpdateLogger(defaultFields Fields) (Logger, error) {
267 pkgName, _, _, _ := getCallerInfo()
268 if _, exist := loggers[pkgName]; !exist {
269 return nil, errors.New(fmt.Sprintf("package-%s-not-registered", pkgName))
270 }
khenaidoob9203542018-09-17 22:56:37 -0400271
khenaidoo7da372d2018-09-21 16:03:09 -0400272 // Build a new logger
273 if _, exist := cfgs[pkgName]; !exist {
274 return nil, errors.New(fmt.Sprintf("config-%s-not-registered", pkgName))
275 }
276
277 cfg := cfgs[pkgName]
278 for k, v := range defaultFields {
279 if cfg.InitialFields == nil {
280 cfg.InitialFields = make(map[string]interface{})
281 }
282 cfg.InitialFields[k] = v
283 }
284 l, err := cfg.Build()
285 if err != nil {
286 return nil, err
287 }
288
289 // Set the logger
290 loggers[pkgName] = &logger{
291 log: l.Sugar(),
292 parent: l,
293 }
294 return loggers[pkgName], nil
295}
296
297//SetPackageLogLevel dynamically sets the log level of a given package to level. This is typically invoked at an
298// application level during debugging
khenaidoob9203542018-09-17 22:56:37 -0400299func SetPackageLogLevel(packageName string, level int) {
300 // Get proper config
301 if cfg, ok := cfgs[packageName]; ok {
302 switch level {
303 case DebugLevel:
304 cfg.Level.SetLevel(zc.DebugLevel)
305 case InfoLevel:
306 cfg.Level.SetLevel(zc.InfoLevel)
307 case WarnLevel:
308 cfg.Level.SetLevel(zc.WarnLevel)
309 case ErrorLevel:
310 cfg.Level.SetLevel(zc.ErrorLevel)
311 case PanicLevel:
312 cfg.Level.SetLevel(zc.PanicLevel)
313 case FatalLevel:
314 cfg.Level.SetLevel(zc.FatalLevel)
315 default:
316 cfg.Level.SetLevel(zc.ErrorLevel)
317 }
khenaidood4d922e2018-08-03 22:35:16 -0400318 }
319}
320
khenaidoo7da372d2018-09-21 16:03:09 -0400321//SetAllLogLevel sets the log level of all registered packages to level
khenaidoo2c6f1672018-09-20 23:14:41 -0400322func SetAllLogLevel(level int) {
323 // Get proper config
khenaidoo7da372d2018-09-21 16:03:09 -0400324 for _, cfg := range cfgs {
khenaidoo2c6f1672018-09-20 23:14:41 -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 }
341 }
342}
343
khenaidoo7da372d2018-09-21 16:03:09 -0400344//SetLogLevel sets the log level for the logger corresponding to the caller's package
345func SetLogLevel(level int) error {
346 pkgName, _, _, _ := getCallerInfo()
347 if _, exist := cfgs[pkgName]; !exist {
348 return errors.New(fmt.Sprint("unregistered-package-%s", pkgName))
349 }
350 cfg := cfgs[pkgName]
351 switch level {
352 case DebugLevel:
353 cfg.Level.SetLevel(zc.DebugLevel)
354 case InfoLevel:
355 cfg.Level.SetLevel(zc.InfoLevel)
356 case WarnLevel:
357 cfg.Level.SetLevel(zc.WarnLevel)
358 case ErrorLevel:
359 cfg.Level.SetLevel(zc.ErrorLevel)
360 case PanicLevel:
361 cfg.Level.SetLevel(zc.PanicLevel)
362 case FatalLevel:
363 cfg.Level.SetLevel(zc.FatalLevel)
364 default:
365 cfg.Level.SetLevel(zc.ErrorLevel)
366 }
367 return nil
368}
369
khenaidoocfee5f42018-07-19 22:47:38 -0400370// CleanUp flushed any buffered log entries. Applications should take care to call
371// CleanUp before exiting.
372func CleanUp() error {
khenaidoob9203542018-09-17 22:56:37 -0400373 for _, logger := range loggers {
374 if logger != nil {
375 if logger.parent != nil {
376 if err := logger.parent.Sync(); err != nil {
377 return err
378 }
379 }
380 }
381 }
khenaidoocfee5f42018-07-19 22:47:38 -0400382 if defaultLogger != nil {
383 if defaultLogger.parent != nil {
384 if err := defaultLogger.parent.Sync(); err != nil {
385 return err
386 }
387 }
388 }
389 return nil
390}
391
khenaidoo7da372d2018-09-21 16:03:09 -0400392func getCallerInfo() (string, string, string, int) {
khenaidoo2c6f1672018-09-20 23:14:41 -0400393 // Since the caller of a log function is one stack frame before (in terms of stack higher level) the log.go
394 // filename, then first look for the last log.go filename and then grab the caller info one level higher.
395 maxLevel := 3
khenaidoo7da372d2018-09-21 16:03:09 -0400396 skiplevel := 3 // Level with the most empirical success to see the last log.go stack frame.
khenaidoo2c6f1672018-09-20 23:14:41 -0400397 pc := make([]uintptr, maxLevel)
398 n := runtime.Callers(skiplevel, pc)
khenaidoob9203542018-09-17 22:56:37 -0400399 packageName := ""
khenaidoo2c6f1672018-09-20 23:14:41 -0400400 funcName := ""
401 fileName := ""
402 var line int
403 if n == 0 {
404 return packageName, fileName, funcName, line
405 }
406 frames := runtime.CallersFrames(pc[:n])
407 var frame runtime.Frame
408 var foundFrame runtime.Frame
409 more := true
410 for more {
411 frame, more = frames.Next()
412 _, fileName = path.Split(frame.File)
413 if fileName != "log.go" {
414 foundFrame = frame // First frame after log.go in the frame stack
415 break
416 }
417 }
418 parts := strings.Split(foundFrame.Function, ".")
419 pl := len(parts)
420 if pl >= 2 {
421 funcName = parts[pl-1]
422 if parts[pl-2][0] == '(' {
423 packageName = strings.Join(parts[0:pl-2], ".")
424 } else {
425 packageName = strings.Join(parts[0:pl-1], ".")
426 }
khenaidoocfee5f42018-07-19 22:47:38 -0400427 }
428
khenaidoo2c6f1672018-09-20 23:14:41 -0400429 if strings.HasSuffix(packageName, ".init") {
khenaidoo7da372d2018-09-21 16:03:09 -0400430 packageName = strings.TrimSuffix(packageName, ".init")
khenaidoob9203542018-09-17 22:56:37 -0400431 }
432
433 if strings.HasSuffix(fileName, ".go") {
khenaidoo7da372d2018-09-21 16:03:09 -0400434 fileName = strings.TrimSuffix(fileName, ".go")
khenaidoob9203542018-09-17 22:56:37 -0400435 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400436
437 return packageName, fileName, funcName, foundFrame.Line
khenaidoob9203542018-09-17 22:56:37 -0400438}
439
khenaidoo7da372d2018-09-21 16:03:09 -0400440func getPackageLevelSugaredLogger() *zp.SugaredLogger {
khenaidoob9203542018-09-17 22:56:37 -0400441 pkgName, fileName, funcName, line := getCallerInfo()
442 if _, exist := loggers[pkgName]; exist {
443 return loggers[pkgName].log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
444 }
445 return defaultLogger.log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
446}
khenaidoocfee5f42018-07-19 22:47:38 -0400447
khenaidoo7da372d2018-09-21 16:03:09 -0400448func getPackageLevelLogger() Logger {
449 pkgName, _, _, _ := getCallerInfo()
450 if _, exist := loggers[pkgName]; exist {
451 return loggers[pkgName]
452 }
453 return defaultLogger
454}
455
khenaidoocfee5f42018-07-19 22:47:38 -0400456func serializeMap(fields Fields) []interface{} {
457 data := make([]interface{}, len(fields)*2)
458 i := 0
459 for k, v := range fields {
460 data[i] = k
461 data[i+1] = v
462 i = i + 2
463 }
464 return data
465}
466
467// With returns a logger initialized with the key-value pairs
468func (l logger) With(keysAndValues Fields) Logger {
469 return logger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
470}
471
472// Debug logs a message at level Debug on the standard logger.
473func (l logger) Debug(args ...interface{}) {
474 l.log.Debug(args...)
475}
476
477// Debugln logs a message at level Debug on the standard logger with a line feed. Default in any case.
478func (l logger) Debugln(args ...interface{}) {
479 l.log.Debug(args...)
480}
481
482// Debugw logs a message at level Debug on the standard logger.
483func (l logger) Debugf(format string, args ...interface{}) {
484 l.log.Debugf(format, args...)
485}
486
487// Debugw logs a message with some additional context. The variadic key-value
488// pairs are treated as they are in With.
489func (l logger) Debugw(msg string, keysAndValues Fields) {
490 l.log.Debugw(msg, serializeMap(keysAndValues)...)
491}
492
493// Info logs a message at level Info on the standard logger.
494func (l logger) Info(args ...interface{}) {
495 l.log.Info(args...)
496}
497
498// Infoln logs a message at level Info on the standard logger with a line feed. Default in any case.
499func (l logger) Infoln(args ...interface{}) {
500 l.log.Info(args...)
501 //msg := fmt.Sprintln(args...)
502 //l.sourced().Info(msg[:len(msg)-1])
503}
504
505// Infof logs a message at level Info on the standard logger.
506func (l logger) Infof(format string, args ...interface{}) {
507 l.log.Infof(format, args...)
508}
509
510// Infow logs a message with some additional context. The variadic key-value
511// pairs are treated as they are in With.
512func (l logger) Infow(msg string, keysAndValues Fields) {
513 l.log.Infow(msg, serializeMap(keysAndValues)...)
514}
515
516// Warn logs a message at level Warn on the standard logger.
517func (l logger) Warn(args ...interface{}) {
518 l.log.Warn(args...)
519}
520
521// Warnln logs a message at level Warn on the standard logger with a line feed. Default in any case.
522func (l logger) Warnln(args ...interface{}) {
523 l.log.Warn(args...)
524}
525
526// Warnf logs a message at level Warn on the standard logger.
527func (l logger) Warnf(format string, args ...interface{}) {
528 l.log.Warnf(format, args...)
529}
530
531// Warnw logs a message with some additional context. The variadic key-value
532// pairs are treated as they are in With.
533func (l logger) Warnw(msg string, keysAndValues Fields) {
534 l.log.Warnw(msg, serializeMap(keysAndValues)...)
535}
536
537// Error logs a message at level Error on the standard logger.
538func (l logger) Error(args ...interface{}) {
539 l.log.Error(args...)
540}
541
542// Errorln logs a message at level Error on the standard logger with a line feed. Default in any case.
543func (l logger) Errorln(args ...interface{}) {
544 l.log.Error(args...)
545}
546
547// Errorf logs a message at level Error on the standard logger.
548func (l logger) Errorf(format string, args ...interface{}) {
549 l.log.Errorf(format, args...)
550}
551
552// Errorw logs a message with some additional context. The variadic key-value
553// pairs are treated as they are in With.
554func (l logger) Errorw(msg string, keysAndValues Fields) {
555 l.log.Errorw(msg, serializeMap(keysAndValues)...)
556}
557
558// Fatal logs a message at level Fatal on the standard logger.
559func (l logger) Fatal(args ...interface{}) {
560 l.log.Fatal(args...)
561}
562
563// Fatalln logs a message at level Fatal on the standard logger with a line feed. Default in any case.
564func (l logger) Fatalln(args ...interface{}) {
565 l.log.Fatal(args...)
566}
567
568// Fatalf logs a message at level Fatal on the standard logger.
569func (l logger) Fatalf(format string, args ...interface{}) {
570 l.log.Fatalf(format, args...)
571}
572
573// Fatalw logs a message with some additional context. The variadic key-value
574// pairs are treated as they are in With.
575func (l logger) Fatalw(msg string, keysAndValues Fields) {
576 l.log.Fatalw(msg, serializeMap(keysAndValues)...)
577}
578
khenaidoo7da372d2018-09-21 16:03:09 -0400579// Warning logs a message at level Warn on the standard logger.
580func (l logger) Warning(args ...interface{}) {
581 l.log.Warn(args...)
582}
583
584// Warningln logs a message at level Warn on the standard logger with a line feed. Default in any case.
585func (l logger) Warningln(args ...interface{}) {
586 l.log.Warn(args...)
587}
588
589// Warningf logs a message at level Warn on the standard logger.
590func (l logger) Warningf(format string, args ...interface{}) {
591 l.log.Warnf(format, args...)
592}
593
594// V reports whether verbosity level l is at least the requested verbose level.
595func (l logger) V(level int) bool {
596 return l.parent.Core().Enabled(parseLevel(level))
597}
598
khenaidoocfee5f42018-07-19 22:47:38 -0400599// With returns a logger initialized with the key-value pairs
600func With(keysAndValues Fields) Logger {
khenaidoo7da372d2018-09-21 16:03:09 -0400601 return logger{log: getPackageLevelSugaredLogger().With(serializeMap(keysAndValues)...), parent: defaultLogger.parent}
khenaidoocfee5f42018-07-19 22:47:38 -0400602}
603
604// Debug logs a message at level Debug on the standard logger.
605func Debug(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400606 getPackageLevelSugaredLogger().Debug(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400607}
608
609// Debugln logs a message at level Debug on the standard logger.
610func Debugln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400611 getPackageLevelSugaredLogger().Debug(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400612}
613
614// Debugf logs a message at level Debug on the standard logger.
615func Debugf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400616 getPackageLevelSugaredLogger().Debugf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400617}
618
619// Debugw logs a message with some additional context. The variadic key-value
620// pairs are treated as they are in With.
621func Debugw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400622 getPackageLevelSugaredLogger().Debugw(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400623}
624
625// Info logs a message at level Info on the standard logger.
626func Info(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400627 getPackageLevelSugaredLogger().Info(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400628}
629
630// Infoln logs a message at level Info on the standard logger.
631func Infoln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400632 getPackageLevelSugaredLogger().Info(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400633}
634
635// Infof logs a message at level Info on the standard logger.
636func Infof(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400637 getPackageLevelSugaredLogger().Infof(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400638}
639
640//Infow logs a message with some additional context. The variadic key-value
641//pairs are treated as they are in With.
642func Infow(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400643 getPackageLevelSugaredLogger().Infow(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400644}
645
646// Warn logs a message at level Warn on the standard logger.
647func Warn(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400648 getPackageLevelSugaredLogger().Warn(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400649}
650
651// Warnln logs a message at level Warn on the standard logger.
652func Warnln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400653 getPackageLevelSugaredLogger().Warn(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400654}
655
656// Warnf logs a message at level Warn on the standard logger.
657func Warnf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400658 getPackageLevelSugaredLogger().Warnf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400659}
660
661// Warnw logs a message with some additional context. The variadic key-value
662// pairs are treated as they are in With.
663func Warnw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400664 getPackageLevelSugaredLogger().Warnw(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400665}
666
667// Error logs a message at level Error on the standard logger.
668func Error(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400669 getPackageLevelSugaredLogger().Error(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400670}
671
672// Errorln logs a message at level Error on the standard logger.
673func Errorln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400674 getPackageLevelSugaredLogger().Error(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400675}
676
677// Errorf logs a message at level Error on the standard logger.
678func Errorf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400679 getPackageLevelSugaredLogger().Errorf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400680}
681
682// Errorw logs a message with some additional context. The variadic key-value
683// pairs are treated as they are in With.
684func Errorw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400685 getPackageLevelSugaredLogger().Errorw(msg, serializeMap(keysAndValues)...)
khenaidoocfee5f42018-07-19 22:47:38 -0400686}
687
688// Fatal logs a message at level Fatal on the standard logger.
689func Fatal(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400690 getPackageLevelSugaredLogger().Fatal(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400691}
692
693// Fatalln logs a message at level Fatal on the standard logger.
694func Fatalln(args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400695 getPackageLevelSugaredLogger().Fatal(args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400696}
697
698// Fatalf logs a message at level Fatal on the standard logger.
699func Fatalf(format string, args ...interface{}) {
khenaidoo7da372d2018-09-21 16:03:09 -0400700 getPackageLevelSugaredLogger().Fatalf(format, args...)
khenaidoocfee5f42018-07-19 22:47:38 -0400701}
702
703// Fatalw logs a message with some additional context. The variadic key-value
704// pairs are treated as they are in With.
705func Fatalw(msg string, keysAndValues Fields) {
khenaidoo7da372d2018-09-21 16:03:09 -0400706 getPackageLevelSugaredLogger().Fatalw(msg, serializeMap(keysAndValues)...)
707}
708
709// Warning logs a message at level Warn on the standard logger.
710func Warning(args ...interface{}) {
711 getPackageLevelSugaredLogger().Warn(args...)
712}
713
714// Warningln logs a message at level Warn on the standard logger.
715func Warningln(args ...interface{}) {
716 getPackageLevelSugaredLogger().Warn(args...)
717}
718
719// Warningf logs a message at level Warn on the standard logger.
720func Warningf(format string, args ...interface{}) {
721 getPackageLevelSugaredLogger().Warnf(format, args...)
722}
723
724// V reports whether verbosity level l is at least the requested verbose level.
725func V(level int) bool {
726 return getPackageLevelLogger().V(level)
khenaidoocfee5f42018-07-19 22:47:38 -0400727}