blob: 43567e3fdc06e94b519af199cfd9ce2f4c93b8c5 [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
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
Don Newton7577f072020-01-06 12:41:11 -050062 // FatalLevel logs a message, then calls os.Exit(1).
63 FatalLevel
64)
65
66// CONSOLE formats the log for the console, mostly used during development
67const CONSOLE = "console"
68
69// JSON formats the log using json format, mostly used by an automated logging system consumption
70const JSON = "json"
71
72// Logger represents an abstract logging interface. Any logging implementation used
73// will need to abide by this interface
74type Logger interface {
75 Debug(...interface{})
76 Debugln(...interface{})
77 Debugf(string, ...interface{})
78 Debugw(string, Fields)
79
80 Info(...interface{})
81 Infoln(...interface{})
82 Infof(string, ...interface{})
83 Infow(string, Fields)
84
85 Warn(...interface{})
86 Warnln(...interface{})
87 Warnf(string, ...interface{})
88 Warnw(string, Fields)
89
90 Error(...interface{})
91 Errorln(...interface{})
92 Errorf(string, ...interface{})
93 Errorw(string, Fields)
94
95 Fatal(...interface{})
96 Fatalln(...interface{})
97 Fatalf(string, ...interface{})
98 Fatalw(string, Fields)
99
100 With(Fields) Logger
101
102 // The following are added to be able to use this logger as a gRPC LoggerV2 if needed
103 //
104 Warning(...interface{})
105 Warningln(...interface{})
106 Warningf(string, ...interface{})
107
108 // V reports whether verbosity level l is at least the requested verbose level.
109 V(l int) bool
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800110
111 //Returns the log level of this specific logger
112 GetLogLevel() int
Don Newton7577f072020-01-06 12:41:11 -0500113}
114
115// Fields is used as key-value pairs for structured logging
116type Fields map[string]interface{}
117
118var defaultLogger *logger
119var cfg zp.Config
120
121var loggers map[string]*logger
122var cfgs map[string]zp.Config
123
124type logger struct {
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800125 log *zp.SugaredLogger
126 parent *zp.Logger
127 packageName string
Don Newton7577f072020-01-06 12:41:11 -0500128}
129
130func intToAtomicLevel(l int) zp.AtomicLevel {
131 switch l {
132 case DebugLevel:
133 return zp.NewAtomicLevelAt(zc.DebugLevel)
134 case InfoLevel:
135 return zp.NewAtomicLevelAt(zc.InfoLevel)
136 case WarnLevel:
137 return zp.NewAtomicLevelAt(zc.WarnLevel)
138 case ErrorLevel:
139 return zp.NewAtomicLevelAt(zc.ErrorLevel)
Don Newton7577f072020-01-06 12:41:11 -0500140 case FatalLevel:
141 return zp.NewAtomicLevelAt(zc.FatalLevel)
142 }
143 return zp.NewAtomicLevelAt(zc.ErrorLevel)
144}
145
146func intToLevel(l int) zc.Level {
147 switch l {
148 case DebugLevel:
149 return zc.DebugLevel
150 case InfoLevel:
151 return zc.InfoLevel
152 case WarnLevel:
153 return zc.WarnLevel
154 case ErrorLevel:
155 return zc.ErrorLevel
Don Newton7577f072020-01-06 12:41:11 -0500156 case FatalLevel:
157 return zc.FatalLevel
158 }
159 return zc.ErrorLevel
160}
161
162func levelToInt(l zc.Level) int {
163 switch l {
164 case zc.DebugLevel:
165 return DebugLevel
166 case zc.InfoLevel:
167 return InfoLevel
168 case zc.WarnLevel:
169 return WarnLevel
170 case zc.ErrorLevel:
171 return ErrorLevel
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800172 case zc.FatalLevel:
173 return FatalLevel
174 }
175 return ErrorLevel
176}
177
178func StringToInt(l string) int {
179 switch l {
180 case "DEBUG":
181 return DebugLevel
182 case "INFO":
183 return InfoLevel
184 case "WARN":
185 return WarnLevel
186 case "ERROR":
187 return ErrorLevel
188 case "FATAL":
Don Newton7577f072020-01-06 12:41:11 -0500189 return FatalLevel
190 }
191 return ErrorLevel
192}
193
194func getDefaultConfig(outputType string, level int, defaultFields Fields) zp.Config {
195 return zp.Config{
196 Level: intToAtomicLevel(level),
197 Encoding: outputType,
198 Development: true,
199 OutputPaths: []string{"stdout"},
200 ErrorOutputPaths: []string{"stderr"},
201 InitialFields: defaultFields,
202 EncoderConfig: zc.EncoderConfig{
203 LevelKey: "level",
204 MessageKey: "msg",
205 TimeKey: "ts",
206 StacktraceKey: "stacktrace",
207 LineEnding: zc.DefaultLineEnding,
208 EncodeLevel: zc.LowercaseLevelEncoder,
209 EncodeTime: zc.ISO8601TimeEncoder,
210 EncodeDuration: zc.SecondsDurationEncoder,
211 EncodeCaller: zc.ShortCallerEncoder,
212 },
213 }
214}
215
216// SetLogger needs to be invoked before the logger API can be invoked. This function
217// initialize the default logger (zap's sugaredlogger)
218func SetDefaultLogger(outputType string, level int, defaultFields Fields) (Logger, error) {
219 // Build a custom config using zap
220 cfg = getDefaultConfig(outputType, level, defaultFields)
221
222 l, err := cfg.Build()
223 if err != nil {
224 return nil, err
225 }
226
227 defaultLogger = &logger{
228 log: l.Sugar(),
229 parent: l,
230 }
231
232 return defaultLogger, nil
233}
234
235// AddPackage registers a package to the log map. Each package gets its own logger which allows
236// its config (loglevel) to be changed dynamically without interacting with the other packages.
237// outputType is JSON, level is the lowest level log to output with this logger and defaultFields is a map of
238// key-value pairs to always add to the output.
239// Note: AddPackage also returns a reference to the actual logger. If a calling package uses this reference directly
240//instead of using the publicly available functions in this log package then a number of functionalities will not
241// be available to it, notably log tracing with filename.functionname.linenumber annotation.
242//
243// pkgNames parameter should be used for testing only as this function detects the caller's package.
244func AddPackage(outputType string, level int, defaultFields Fields, pkgNames ...string) (Logger, error) {
245 if cfgs == nil {
246 cfgs = make(map[string]zp.Config)
247 }
248 if loggers == nil {
249 loggers = make(map[string]*logger)
250 }
251
252 var pkgName string
253 for _, name := range pkgNames {
254 pkgName = name
255 break
256 }
257 if pkgName == "" {
258 pkgName, _, _, _ = getCallerInfo()
259 }
260
261 if _, exist := loggers[pkgName]; exist {
262 return loggers[pkgName], nil
263 }
264
265 cfgs[pkgName] = getDefaultConfig(outputType, level, defaultFields)
266
267 l, err := cfgs[pkgName].Build()
268 if err != nil {
269 return nil, err
270 }
271
272 loggers[pkgName] = &logger{
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800273 log: l.Sugar(),
274 parent: l,
275 packageName: pkgName,
Don Newton7577f072020-01-06 12:41:11 -0500276 }
277 return loggers[pkgName], nil
278}
279
280//UpdateAllLoggers create new loggers for all registered pacakges with the defaultFields.
281func UpdateAllLoggers(defaultFields Fields) error {
282 for pkgName, cfg := range cfgs {
283 for k, v := range defaultFields {
284 if cfg.InitialFields == nil {
285 cfg.InitialFields = make(map[string]interface{})
286 }
287 cfg.InitialFields[k] = v
288 }
289 l, err := cfg.Build()
290 if err != nil {
291 return err
292 }
293
294 loggers[pkgName] = &logger{
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800295 log: l.Sugar(),
296 parent: l,
297 packageName: pkgName,
Don Newton7577f072020-01-06 12:41:11 -0500298 }
299 }
300 return nil
301}
302
303// Return a list of all packages that have individually-configured loggers
304func GetPackageNames() []string {
305 i := 0
306 keys := make([]string, len(loggers))
307 for k := range loggers {
308 keys[i] = k
309 i++
310 }
311 return keys
312}
313
314// UpdateLogger deletes the logger associated with a caller's package and creates a new logger with the
315// defaultFields. If a calling package is holding on to a Logger reference obtained from AddPackage invocation, then
316// that package needs to invoke UpdateLogger if it needs to make changes to the default fields and obtain a new logger
317// reference
318func UpdateLogger(defaultFields Fields) (Logger, error) {
319 pkgName, _, _, _ := getCallerInfo()
320 if _, exist := loggers[pkgName]; !exist {
321 return nil, errors.New(fmt.Sprintf("package-%s-not-registered", pkgName))
322 }
323
324 // Build a new logger
325 if _, exist := cfgs[pkgName]; !exist {
326 return nil, errors.New(fmt.Sprintf("config-%s-not-registered", pkgName))
327 }
328
329 cfg := cfgs[pkgName]
330 for k, v := range defaultFields {
331 if cfg.InitialFields == nil {
332 cfg.InitialFields = make(map[string]interface{})
333 }
334 cfg.InitialFields[k] = v
335 }
336 l, err := cfg.Build()
337 if err != nil {
338 return nil, err
339 }
340
341 // Set the logger
342 loggers[pkgName] = &logger{
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800343 log: l.Sugar(),
344 parent: l,
345 packageName: pkgName,
Don Newton7577f072020-01-06 12:41:11 -0500346 }
347 return loggers[pkgName], nil
348}
349
350func setLevel(cfg zp.Config, level int) {
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)
Don Newton7577f072020-01-06 12:41:11 -0500360 case FatalLevel:
361 cfg.Level.SetLevel(zc.FatalLevel)
362 default:
363 cfg.Level.SetLevel(zc.ErrorLevel)
364 }
365}
366
367//SetPackageLogLevel dynamically sets the log level of a given package to level. This is typically invoked at an
368// application level during debugging
369func SetPackageLogLevel(packageName string, level int) {
370 // Get proper config
371 if cfg, ok := cfgs[packageName]; ok {
372 setLevel(cfg, level)
373 }
374}
375
376//SetAllLogLevel sets the log level of all registered packages to level
377func SetAllLogLevel(level int) {
378 // Get proper config
379 for _, cfg := range cfgs {
380 setLevel(cfg, level)
381 }
382}
383
384//GetPackageLogLevel returns the current log level of a package.
385func GetPackageLogLevel(packageName ...string) (int, error) {
386 var name string
387 if len(packageName) == 1 {
388 name = packageName[0]
389 } else {
390 name, _, _, _ = getCallerInfo()
391 }
392 if cfg, ok := cfgs[name]; ok {
393 return levelToInt(cfg.Level.Level()), nil
394 }
395 return 0, errors.New(fmt.Sprintf("unknown-package-%s", name))
396}
397
398//GetDefaultLogLevel gets the log level used for packages that don't have specific loggers
399func GetDefaultLogLevel() int {
400 return levelToInt(cfg.Level.Level())
401}
402
403//SetLogLevel sets the log level for the logger corresponding to the caller's package
404func SetLogLevel(level int) error {
405 pkgName, _, _, _ := getCallerInfo()
406 if _, exist := cfgs[pkgName]; !exist {
407 return errors.New(fmt.Sprintf("unregistered-package-%s", pkgName))
408 }
409 cfg := cfgs[pkgName]
410 setLevel(cfg, level)
411 return nil
412}
413
414//SetDefaultLogLevel sets the log level used for packages that don't have specific loggers
415func SetDefaultLogLevel(level int) {
416 setLevel(cfg, level)
417}
418
419// CleanUp flushed any buffered log entries. Applications should take care to call
420// CleanUp before exiting.
421func CleanUp() error {
422 for _, logger := range loggers {
423 if logger != nil {
424 if logger.parent != nil {
425 if err := logger.parent.Sync(); err != nil {
426 return err
427 }
428 }
429 }
430 }
431 if defaultLogger != nil {
432 if defaultLogger.parent != nil {
433 if err := defaultLogger.parent.Sync(); err != nil {
434 return err
435 }
436 }
437 }
438 return nil
439}
440
441func getCallerInfo() (string, string, string, int) {
442 // Since the caller of a log function is one stack frame before (in terms of stack higher level) the log.go
443 // filename, then first look for the last log.go filename and then grab the caller info one level higher.
444 maxLevel := 3
445 skiplevel := 3 // Level with the most empirical success to see the last log.go stack frame.
446 pc := make([]uintptr, maxLevel)
447 n := runtime.Callers(skiplevel, pc)
448 packageName := ""
449 funcName := ""
450 fileName := ""
451 var line int
452 if n == 0 {
453 return packageName, fileName, funcName, line
454 }
455 frames := runtime.CallersFrames(pc[:n])
456 var frame runtime.Frame
457 var foundFrame runtime.Frame
458 more := true
459 for more {
460 frame, more = frames.Next()
461 _, fileName = path.Split(frame.File)
462 if fileName != "log.go" {
463 foundFrame = frame // First frame after log.go in the frame stack
464 break
465 }
466 }
467 parts := strings.Split(foundFrame.Function, ".")
468 pl := len(parts)
469 if pl >= 2 {
470 funcName = parts[pl-1]
471 if parts[pl-2][0] == '(' {
472 packageName = strings.Join(parts[0:pl-2], ".")
473 } else {
474 packageName = strings.Join(parts[0:pl-1], ".")
475 }
476 }
477
478 if strings.HasSuffix(packageName, ".init") {
479 packageName = strings.TrimSuffix(packageName, ".init")
480 }
481
482 if strings.HasSuffix(fileName, ".go") {
483 fileName = strings.TrimSuffix(fileName, ".go")
484 }
485
486 return packageName, fileName, funcName, foundFrame.Line
487}
488
489func getPackageLevelSugaredLogger() *zp.SugaredLogger {
490 pkgName, fileName, funcName, line := getCallerInfo()
491 if _, exist := loggers[pkgName]; exist {
492 return loggers[pkgName].log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
493 }
494 return defaultLogger.log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
495}
496
497func getPackageLevelLogger() Logger {
498 pkgName, _, _, _ := getCallerInfo()
499 if _, exist := loggers[pkgName]; exist {
500 return loggers[pkgName]
501 }
502 return defaultLogger
503}
504
505func serializeMap(fields Fields) []interface{} {
506 data := make([]interface{}, len(fields)*2)
507 i := 0
508 for k, v := range fields {
509 data[i] = k
510 data[i+1] = v
511 i = i + 2
512 }
513 return data
514}
515
516// With returns a logger initialized with the key-value pairs
517func (l logger) With(keysAndValues Fields) Logger {
518 return logger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
519}
520
521// Debug logs a message at level Debug on the standard logger.
522func (l logger) Debug(args ...interface{}) {
523 l.log.Debug(args...)
524}
525
526// Debugln logs a message at level Debug on the standard logger with a line feed. Default in any case.
527func (l logger) Debugln(args ...interface{}) {
528 l.log.Debug(args...)
529}
530
531// Debugw logs a message at level Debug on the standard logger.
532func (l logger) Debugf(format string, args ...interface{}) {
533 l.log.Debugf(format, args...)
534}
535
536// Debugw logs a message with some additional context. The variadic key-value
537// pairs are treated as they are in With.
538func (l logger) Debugw(msg string, keysAndValues Fields) {
539 l.log.Debugw(msg, serializeMap(keysAndValues)...)
540}
541
542// Info logs a message at level Info on the standard logger.
543func (l logger) Info(args ...interface{}) {
544 l.log.Info(args...)
545}
546
547// Infoln logs a message at level Info on the standard logger with a line feed. Default in any case.
548func (l logger) Infoln(args ...interface{}) {
549 l.log.Info(args...)
550 //msg := fmt.Sprintln(args...)
551 //l.sourced().Info(msg[:len(msg)-1])
552}
553
554// Infof logs a message at level Info on the standard logger.
555func (l logger) Infof(format string, args ...interface{}) {
556 l.log.Infof(format, args...)
557}
558
559// Infow logs a message with some additional context. The variadic key-value
560// pairs are treated as they are in With.
561func (l logger) Infow(msg string, keysAndValues Fields) {
562 l.log.Infow(msg, serializeMap(keysAndValues)...)
563}
564
565// Warn logs a message at level Warn on the standard logger.
566func (l logger) Warn(args ...interface{}) {
567 l.log.Warn(args...)
568}
569
570// Warnln logs a message at level Warn on the standard logger with a line feed. Default in any case.
571func (l logger) Warnln(args ...interface{}) {
572 l.log.Warn(args...)
573}
574
575// Warnf logs a message at level Warn on the standard logger.
576func (l logger) Warnf(format string, args ...interface{}) {
577 l.log.Warnf(format, args...)
578}
579
580// Warnw logs a message with some additional context. The variadic key-value
581// pairs are treated as they are in With.
582func (l logger) Warnw(msg string, keysAndValues Fields) {
583 l.log.Warnw(msg, serializeMap(keysAndValues)...)
584}
585
586// Error logs a message at level Error on the standard logger.
587func (l logger) Error(args ...interface{}) {
588 l.log.Error(args...)
589}
590
591// Errorln logs a message at level Error on the standard logger with a line feed. Default in any case.
592func (l logger) Errorln(args ...interface{}) {
593 l.log.Error(args...)
594}
595
596// Errorf logs a message at level Error on the standard logger.
597func (l logger) Errorf(format string, args ...interface{}) {
598 l.log.Errorf(format, args...)
599}
600
601// Errorw logs a message with some additional context. The variadic key-value
602// pairs are treated as they are in With.
603func (l logger) Errorw(msg string, keysAndValues Fields) {
604 l.log.Errorw(msg, serializeMap(keysAndValues)...)
605}
606
607// Fatal logs a message at level Fatal on the standard logger.
608func (l logger) Fatal(args ...interface{}) {
609 l.log.Fatal(args...)
610}
611
612// Fatalln logs a message at level Fatal on the standard logger with a line feed. Default in any case.
613func (l logger) Fatalln(args ...interface{}) {
614 l.log.Fatal(args...)
615}
616
617// Fatalf logs a message at level Fatal on the standard logger.
618func (l logger) Fatalf(format string, args ...interface{}) {
619 l.log.Fatalf(format, args...)
620}
621
622// Fatalw logs a message with some additional context. The variadic key-value
623// pairs are treated as they are in With.
624func (l logger) Fatalw(msg string, keysAndValues Fields) {
625 l.log.Fatalw(msg, serializeMap(keysAndValues)...)
626}
627
628// Warning logs a message at level Warn on the standard logger.
629func (l logger) Warning(args ...interface{}) {
630 l.log.Warn(args...)
631}
632
633// Warningln logs a message at level Warn on the standard logger with a line feed. Default in any case.
634func (l logger) Warningln(args ...interface{}) {
635 l.log.Warn(args...)
636}
637
638// Warningf logs a message at level Warn on the standard logger.
639func (l logger) Warningf(format string, args ...interface{}) {
640 l.log.Warnf(format, args...)
641}
642
643// V reports whether verbosity level l is at least the requested verbose level.
644func (l logger) V(level int) bool {
645 return l.parent.Core().Enabled(intToLevel(level))
646}
647
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800648// GetLogLevel returns the current level of the logger
649func (l logger) GetLogLevel() int {
650 return levelToInt(cfgs[l.packageName].Level.Level())
651}
652
Don Newton7577f072020-01-06 12:41:11 -0500653// With returns a logger initialized with the key-value pairs
654func With(keysAndValues Fields) Logger {
655 return logger{log: getPackageLevelSugaredLogger().With(serializeMap(keysAndValues)...), parent: defaultLogger.parent}
656}
657
658// Debug logs a message at level Debug on the standard logger.
659func Debug(args ...interface{}) {
660 getPackageLevelSugaredLogger().Debug(args...)
661}
662
663// Debugln logs a message at level Debug on the standard logger.
664func Debugln(args ...interface{}) {
665 getPackageLevelSugaredLogger().Debug(args...)
666}
667
668// Debugf logs a message at level Debug on the standard logger.
669func Debugf(format string, args ...interface{}) {
670 getPackageLevelSugaredLogger().Debugf(format, args...)
671}
672
673// Debugw logs a message with some additional context. The variadic key-value
674// pairs are treated as they are in With.
675func Debugw(msg string, keysAndValues Fields) {
676 getPackageLevelSugaredLogger().Debugw(msg, serializeMap(keysAndValues)...)
677}
678
679// Info logs a message at level Info on the standard logger.
680func Info(args ...interface{}) {
681 getPackageLevelSugaredLogger().Info(args...)
682}
683
684// Infoln logs a message at level Info on the standard logger.
685func Infoln(args ...interface{}) {
686 getPackageLevelSugaredLogger().Info(args...)
687}
688
689// Infof logs a message at level Info on the standard logger.
690func Infof(format string, args ...interface{}) {
691 getPackageLevelSugaredLogger().Infof(format, args...)
692}
693
694//Infow logs a message with some additional context. The variadic key-value
695//pairs are treated as they are in With.
696func Infow(msg string, keysAndValues Fields) {
697 getPackageLevelSugaredLogger().Infow(msg, serializeMap(keysAndValues)...)
698}
699
700// Warn logs a message at level Warn on the standard logger.
701func Warn(args ...interface{}) {
702 getPackageLevelSugaredLogger().Warn(args...)
703}
704
705// Warnln logs a message at level Warn on the standard logger.
706func Warnln(args ...interface{}) {
707 getPackageLevelSugaredLogger().Warn(args...)
708}
709
710// Warnf logs a message at level Warn on the standard logger.
711func Warnf(format string, args ...interface{}) {
712 getPackageLevelSugaredLogger().Warnf(format, args...)
713}
714
715// Warnw logs a message with some additional context. The variadic key-value
716// pairs are treated as they are in With.
717func Warnw(msg string, keysAndValues Fields) {
718 getPackageLevelSugaredLogger().Warnw(msg, serializeMap(keysAndValues)...)
719}
720
721// Error logs a message at level Error on the standard logger.
722func Error(args ...interface{}) {
723 getPackageLevelSugaredLogger().Error(args...)
724}
725
726// Errorln logs a message at level Error on the standard logger.
727func Errorln(args ...interface{}) {
728 getPackageLevelSugaredLogger().Error(args...)
729}
730
731// Errorf logs a message at level Error on the standard logger.
732func Errorf(format string, args ...interface{}) {
733 getPackageLevelSugaredLogger().Errorf(format, args...)
734}
735
736// Errorw logs a message with some additional context. The variadic key-value
737// pairs are treated as they are in With.
738func Errorw(msg string, keysAndValues Fields) {
739 getPackageLevelSugaredLogger().Errorw(msg, serializeMap(keysAndValues)...)
740}
741
742// Fatal logs a message at level Fatal on the standard logger.
743func Fatal(args ...interface{}) {
744 getPackageLevelSugaredLogger().Fatal(args...)
745}
746
747// Fatalln logs a message at level Fatal on the standard logger.
748func Fatalln(args ...interface{}) {
749 getPackageLevelSugaredLogger().Fatal(args...)
750}
751
752// Fatalf logs a message at level Fatal on the standard logger.
753func Fatalf(format string, args ...interface{}) {
754 getPackageLevelSugaredLogger().Fatalf(format, args...)
755}
756
757// Fatalw logs a message with some additional context. The variadic key-value
758// pairs are treated as they are in With.
759func Fatalw(msg string, keysAndValues Fields) {
760 getPackageLevelSugaredLogger().Fatalw(msg, serializeMap(keysAndValues)...)
761}
762
763// Warning logs a message at level Warn on the standard logger.
764func Warning(args ...interface{}) {
765 getPackageLevelSugaredLogger().Warn(args...)
766}
767
768// Warningln logs a message at level Warn on the standard logger.
769func Warningln(args ...interface{}) {
770 getPackageLevelSugaredLogger().Warn(args...)
771}
772
773// Warningf logs a message at level Warn on the standard logger.
774func Warningf(format string, args ...interface{}) {
775 getPackageLevelSugaredLogger().Warnf(format, args...)
776}
777
778// V reports whether verbosity level l is at least the requested verbose level.
779func V(level int) bool {
780 return getPackageLevelLogger().V(level)
781}
David K. Bainbridgeaea73cd2020-01-27 10:44:50 -0800782
783//GetLogLevel returns the log level of the invoking package
784func GetLogLevel() int {
785 return getPackageLevelLogger().GetLogLevel()
786}