blob: 69e22a43fed7be451cdbcc416070cfb32f96be16 [file] [log] [blame]
William Kurkianea869482019-04-09 15:16:11 -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 */
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 Agrawal02f784d2020-02-14 09:34:02 +000053type LogLevel int8
54
William Kurkianea869482019-04-09 15:16:11 -040055const (
56 // DebugLevel logs a message at debug level
Rohan Agrawal02f784d2020-02-14 09:34:02 +000057 DebugLevel = LogLevel(iota)
William Kurkianea869482019-04-09 15:16:11 -040058 // 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
William Kurkianea869482019-04-09 15:16:11 -040064 // 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.
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000111 V(l LogLevel) bool
Esin Karamanccb714b2019-11-29 15:02:06 +0000112
113 //Returns the log level of this specific logger
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000114 GetLogLevel() LogLevel
William Kurkianea869482019-04-09 15:16:11 -0400115}
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 {
Esin Karamanccb714b2019-11-29 15:02:06 +0000127 log *zp.SugaredLogger
128 parent *zp.Logger
129 packageName string
William Kurkianea869482019-04-09 15:16:11 -0400130}
131
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000132func logLevelToAtomicLevel(l LogLevel) zp.AtomicLevel {
William Kurkianea869482019-04-09 15:16:11 -0400133 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)
William Kurkianea869482019-04-09 15:16:11 -0400142 case FatalLevel:
143 return zp.NewAtomicLevelAt(zc.FatalLevel)
144 }
145 return zp.NewAtomicLevelAt(zc.ErrorLevel)
146}
147
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000148func logLevelToLevel(l LogLevel) zc.Level {
William Kurkianea869482019-04-09 15:16:11 -0400149 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
William Kurkianea869482019-04-09 15:16:11 -0400158 case FatalLevel:
159 return zc.FatalLevel
160 }
161 return zc.ErrorLevel
162}
163
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000164func levelToLogLevel(l zc.Level) LogLevel {
William Kurkianea869482019-04-09 15:16:11 -0400165 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
Esin Karamanccb714b2019-11-29 15:02:06 +0000174 case zc.FatalLevel:
175 return FatalLevel
176 }
177 return ErrorLevel
178}
179
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000180func StringToLogLevel(l string) (LogLevel, error) {
181 switch strings.ToUpper(l) {
Esin Karamanccb714b2019-11-29 15:02:06 +0000182 case "DEBUG":
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000183 return DebugLevel, nil
Esin Karamanccb714b2019-11-29 15:02:06 +0000184 case "INFO":
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000185 return InfoLevel, nil
Esin Karamanccb714b2019-11-29 15:02:06 +0000186 case "WARN":
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000187 return WarnLevel, nil
Esin Karamanccb714b2019-11-29 15:02:06 +0000188 case "ERROR":
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000189 return ErrorLevel, nil
Esin Karamanccb714b2019-11-29 15:02:06 +0000190 case "FATAL":
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000191 return FatalLevel, nil
William Kurkianea869482019-04-09 15:16:11 -0400192 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000193 return 0, errors.New("Given LogLevel is invalid : " + l)
William Kurkianea869482019-04-09 15:16:11 -0400194}
195
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000196func getDefaultConfig(outputType string, level LogLevel, defaultFields Fields) zp.Config {
William Kurkianea869482019-04-09 15:16:11 -0400197 return zp.Config{
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000198 Level: logLevelToAtomicLevel(level),
William Kurkianea869482019-04-09 15:16:11 -0400199 Encoding: outputType,
200 Development: true,
201 OutputPaths: []string{"stdout"},
202 ErrorOutputPaths: []string{"stderr"},
203 InitialFields: defaultFields,
204 EncoderConfig: zc.EncoderConfig{
205 LevelKey: "level",
206 MessageKey: "msg",
207 TimeKey: "ts",
208 StacktraceKey: "stacktrace",
209 LineEnding: zc.DefaultLineEnding,
210 EncodeLevel: zc.LowercaseLevelEncoder,
211 EncodeTime: zc.ISO8601TimeEncoder,
212 EncodeDuration: zc.SecondsDurationEncoder,
213 EncodeCaller: zc.ShortCallerEncoder,
214 },
215 }
216}
217
218// SetLogger needs to be invoked before the logger API can be invoked. This function
219// initialize the default logger (zap's sugaredlogger)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000220func SetDefaultLogger(outputType string, level LogLevel, defaultFields Fields) (Logger, error) {
William Kurkianea869482019-04-09 15:16:11 -0400221 // Build a custom config using zap
222 cfg = getDefaultConfig(outputType, level, defaultFields)
223
224 l, err := cfg.Build()
225 if err != nil {
226 return nil, err
227 }
228
229 defaultLogger = &logger{
230 log: l.Sugar(),
231 parent: l,
232 }
233
234 return defaultLogger, nil
235}
236
237// AddPackage registers a package to the log map. Each package gets its own logger which allows
238// its config (loglevel) to be changed dynamically without interacting with the other packages.
239// outputType is JSON, level is the lowest level log to output with this logger and defaultFields is a map of
240// key-value pairs to always add to the output.
241// Note: AddPackage also returns a reference to the actual logger. If a calling package uses this reference directly
242//instead of using the publicly available functions in this log package then a number of functionalities will not
243// be available to it, notably log tracing with filename.functionname.linenumber annotation.
244//
245// pkgNames parameter should be used for testing only as this function detects the caller's package.
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000246func AddPackage(outputType string, level LogLevel, defaultFields Fields, pkgNames ...string) (Logger, error) {
William Kurkianea869482019-04-09 15:16:11 -0400247 if cfgs == nil {
248 cfgs = make(map[string]zp.Config)
249 }
250 if loggers == nil {
251 loggers = make(map[string]*logger)
252 }
253
254 var pkgName string
255 for _, name := range pkgNames {
256 pkgName = name
257 break
258 }
259 if pkgName == "" {
260 pkgName, _, _, _ = getCallerInfo()
261 }
262
263 if _, exist := loggers[pkgName]; exist {
264 return loggers[pkgName], nil
265 }
266
267 cfgs[pkgName] = getDefaultConfig(outputType, level, defaultFields)
268
269 l, err := cfgs[pkgName].Build()
270 if err != nil {
271 return nil, err
272 }
273
274 loggers[pkgName] = &logger{
Esin Karamanccb714b2019-11-29 15:02:06 +0000275 log: l.Sugar(),
276 parent: l,
277 packageName: pkgName,
William Kurkianea869482019-04-09 15:16:11 -0400278 }
279 return loggers[pkgName], nil
280}
281
282//UpdateAllLoggers create new loggers for all registered pacakges with the defaultFields.
283func UpdateAllLoggers(defaultFields Fields) error {
284 for pkgName, cfg := range cfgs {
285 for k, v := range defaultFields {
286 if cfg.InitialFields == nil {
287 cfg.InitialFields = make(map[string]interface{})
288 }
289 cfg.InitialFields[k] = v
290 }
291 l, err := cfg.Build()
292 if err != nil {
293 return err
294 }
295
296 loggers[pkgName] = &logger{
Esin Karamanccb714b2019-11-29 15:02:06 +0000297 log: l.Sugar(),
298 parent: l,
299 packageName: pkgName,
William Kurkianea869482019-04-09 15:16:11 -0400300 }
301 }
302 return nil
303}
304
kdarapub26b4502019-10-05 03:02:33 +0530305// Return a list of all packages that have individually-configured loggers
306func GetPackageNames() []string {
307 i := 0
308 keys := make([]string, len(loggers))
309 for k := range loggers {
310 keys[i] = k
311 i++
312 }
313 return keys
314}
315
William Kurkianea869482019-04-09 15:16:11 -0400316// UpdateLogger deletes the logger associated with a caller's package and creates a new logger with the
317// defaultFields. If a calling package is holding on to a Logger reference obtained from AddPackage invocation, then
318// that package needs to invoke UpdateLogger if it needs to make changes to the default fields and obtain a new logger
319// reference
320func UpdateLogger(defaultFields Fields) (Logger, error) {
321 pkgName, _, _, _ := getCallerInfo()
322 if _, exist := loggers[pkgName]; !exist {
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000323 return nil, fmt.Errorf("package-%s-not-registered", pkgName)
William Kurkianea869482019-04-09 15:16:11 -0400324 }
325
326 // Build a new logger
327 if _, exist := cfgs[pkgName]; !exist {
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000328 return nil, fmt.Errorf("config-%s-not-registered", pkgName)
William Kurkianea869482019-04-09 15:16:11 -0400329 }
330
331 cfg := cfgs[pkgName]
332 for k, v := range defaultFields {
333 if cfg.InitialFields == nil {
334 cfg.InitialFields = make(map[string]interface{})
335 }
336 cfg.InitialFields[k] = v
337 }
338 l, err := cfg.Build()
339 if err != nil {
340 return nil, err
341 }
342
343 // Set the logger
344 loggers[pkgName] = &logger{
Esin Karamanccb714b2019-11-29 15:02:06 +0000345 log: l.Sugar(),
346 parent: l,
347 packageName: pkgName,
William Kurkianea869482019-04-09 15:16:11 -0400348 }
349 return loggers[pkgName], nil
350}
351
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000352func setLevel(cfg zp.Config, level LogLevel) {
William Kurkianea869482019-04-09 15:16:11 -0400353 switch level {
354 case DebugLevel:
355 cfg.Level.SetLevel(zc.DebugLevel)
356 case InfoLevel:
357 cfg.Level.SetLevel(zc.InfoLevel)
358 case WarnLevel:
359 cfg.Level.SetLevel(zc.WarnLevel)
360 case ErrorLevel:
361 cfg.Level.SetLevel(zc.ErrorLevel)
William Kurkianea869482019-04-09 15:16:11 -0400362 case FatalLevel:
363 cfg.Level.SetLevel(zc.FatalLevel)
364 default:
365 cfg.Level.SetLevel(zc.ErrorLevel)
366 }
367}
368
369//SetPackageLogLevel dynamically sets the log level of a given package to level. This is typically invoked at an
370// application level during debugging
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000371func SetPackageLogLevel(packageName string, level LogLevel) {
William Kurkianea869482019-04-09 15:16:11 -0400372 // Get proper config
373 if cfg, ok := cfgs[packageName]; ok {
374 setLevel(cfg, level)
375 }
376}
377
378//SetAllLogLevel sets the log level of all registered packages to level
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000379func SetAllLogLevel(level LogLevel) {
William Kurkianea869482019-04-09 15:16:11 -0400380 // Get proper config
381 for _, cfg := range cfgs {
382 setLevel(cfg, level)
383 }
384}
385
386//GetPackageLogLevel returns the current log level of a package.
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000387func GetPackageLogLevel(packageName ...string) (LogLevel, error) {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400388 var name string
389 if len(packageName) == 1 {
390 name = packageName[0]
391 } else {
392 name, _, _, _ = getCallerInfo()
393 }
394 if cfg, ok := cfgs[name]; ok {
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000395 return levelToLogLevel(cfg.Level.Level()), nil
William Kurkianea869482019-04-09 15:16:11 -0400396 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000397 return 0, fmt.Errorf("unknown-package-%s", name)
William Kurkianea869482019-04-09 15:16:11 -0400398}
399
kdarapub26b4502019-10-05 03:02:33 +0530400//GetDefaultLogLevel gets the log level used for packages that don't have specific loggers
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000401func GetDefaultLogLevel() LogLevel {
402 return levelToLogLevel(cfg.Level.Level())
kdarapub26b4502019-10-05 03:02:33 +0530403}
404
William Kurkianea869482019-04-09 15:16:11 -0400405//SetLogLevel sets the log level for the logger corresponding to the caller's package
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000406func SetLogLevel(level LogLevel) error {
William Kurkianea869482019-04-09 15:16:11 -0400407 pkgName, _, _, _ := getCallerInfo()
408 if _, exist := cfgs[pkgName]; !exist {
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000409 return fmt.Errorf("unregistered-package-%s", pkgName)
William Kurkianea869482019-04-09 15:16:11 -0400410 }
411 cfg := cfgs[pkgName]
412 setLevel(cfg, level)
413 return nil
414}
415
kdarapub26b4502019-10-05 03:02:33 +0530416//SetDefaultLogLevel sets the log level used for packages that don't have specific loggers
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000417func SetDefaultLogLevel(level LogLevel) {
kdarapub26b4502019-10-05 03:02:33 +0530418 setLevel(cfg, level)
419}
420
William Kurkianea869482019-04-09 15:16:11 -0400421// CleanUp flushed any buffered log entries. Applications should take care to call
422// CleanUp before exiting.
423func CleanUp() error {
424 for _, logger := range loggers {
425 if logger != nil {
426 if logger.parent != nil {
427 if err := logger.parent.Sync(); err != nil {
428 return err
429 }
430 }
431 }
432 }
433 if defaultLogger != nil {
434 if defaultLogger.parent != nil {
435 if err := defaultLogger.parent.Sync(); err != nil {
436 return err
437 }
438 }
439 }
440 return nil
441}
442
443func getCallerInfo() (string, string, string, int) {
444 // Since the caller of a log function is one stack frame before (in terms of stack higher level) the log.go
445 // filename, then first look for the last log.go filename and then grab the caller info one level higher.
446 maxLevel := 3
447 skiplevel := 3 // Level with the most empirical success to see the last log.go stack frame.
448 pc := make([]uintptr, maxLevel)
449 n := runtime.Callers(skiplevel, pc)
450 packageName := ""
451 funcName := ""
452 fileName := ""
453 var line int
454 if n == 0 {
455 return packageName, fileName, funcName, line
456 }
457 frames := runtime.CallersFrames(pc[:n])
458 var frame runtime.Frame
459 var foundFrame runtime.Frame
460 more := true
461 for more {
462 frame, more = frames.Next()
463 _, fileName = path.Split(frame.File)
464 if fileName != "log.go" {
465 foundFrame = frame // First frame after log.go in the frame stack
466 break
467 }
468 }
469 parts := strings.Split(foundFrame.Function, ".")
470 pl := len(parts)
471 if pl >= 2 {
472 funcName = parts[pl-1]
473 if parts[pl-2][0] == '(' {
474 packageName = strings.Join(parts[0:pl-2], ".")
475 } else {
476 packageName = strings.Join(parts[0:pl-1], ".")
477 }
478 }
479
480 if strings.HasSuffix(packageName, ".init") {
481 packageName = strings.TrimSuffix(packageName, ".init")
482 }
483
484 if strings.HasSuffix(fileName, ".go") {
485 fileName = strings.TrimSuffix(fileName, ".go")
486 }
487
488 return packageName, fileName, funcName, foundFrame.Line
489}
490
491func getPackageLevelSugaredLogger() *zp.SugaredLogger {
492 pkgName, fileName, funcName, line := getCallerInfo()
493 if _, exist := loggers[pkgName]; exist {
494 return loggers[pkgName].log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
495 }
496 return defaultLogger.log.With("caller", fmt.Sprintf("%s.%s:%d", fileName, funcName, line))
497}
498
499func getPackageLevelLogger() Logger {
500 pkgName, _, _, _ := getCallerInfo()
501 if _, exist := loggers[pkgName]; exist {
502 return loggers[pkgName]
503 }
504 return defaultLogger
505}
506
507func serializeMap(fields Fields) []interface{} {
508 data := make([]interface{}, len(fields)*2)
509 i := 0
510 for k, v := range fields {
511 data[i] = k
512 data[i+1] = v
513 i = i + 2
514 }
515 return data
516}
517
518// With returns a logger initialized with the key-value pairs
519func (l logger) With(keysAndValues Fields) Logger {
520 return logger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
521}
522
523// Debug logs a message at level Debug on the standard logger.
524func (l logger) Debug(args ...interface{}) {
525 l.log.Debug(args...)
526}
527
528// Debugln logs a message at level Debug on the standard logger with a line feed. Default in any case.
529func (l logger) Debugln(args ...interface{}) {
530 l.log.Debug(args...)
531}
532
533// Debugw logs a message at level Debug on the standard logger.
534func (l logger) Debugf(format string, args ...interface{}) {
535 l.log.Debugf(format, args...)
536}
537
538// Debugw logs a message with some additional context. The variadic key-value
539// pairs are treated as they are in With.
540func (l logger) Debugw(msg string, keysAndValues Fields) {
541 l.log.Debugw(msg, serializeMap(keysAndValues)...)
542}
543
544// Info logs a message at level Info on the standard logger.
545func (l logger) Info(args ...interface{}) {
546 l.log.Info(args...)
547}
548
549// Infoln logs a message at level Info on the standard logger with a line feed. Default in any case.
550func (l logger) Infoln(args ...interface{}) {
551 l.log.Info(args...)
552 //msg := fmt.Sprintln(args...)
553 //l.sourced().Info(msg[:len(msg)-1])
554}
555
556// Infof logs a message at level Info on the standard logger.
557func (l logger) Infof(format string, args ...interface{}) {
558 l.log.Infof(format, args...)
559}
560
561// Infow logs a message with some additional context. The variadic key-value
562// pairs are treated as they are in With.
563func (l logger) Infow(msg string, keysAndValues Fields) {
564 l.log.Infow(msg, serializeMap(keysAndValues)...)
565}
566
567// Warn logs a message at level Warn on the standard logger.
568func (l logger) Warn(args ...interface{}) {
569 l.log.Warn(args...)
570}
571
572// Warnln logs a message at level Warn on the standard logger with a line feed. Default in any case.
573func (l logger) Warnln(args ...interface{}) {
574 l.log.Warn(args...)
575}
576
577// Warnf logs a message at level Warn on the standard logger.
578func (l logger) Warnf(format string, args ...interface{}) {
579 l.log.Warnf(format, args...)
580}
581
582// Warnw logs a message with some additional context. The variadic key-value
583// pairs are treated as they are in With.
584func (l logger) Warnw(msg string, keysAndValues Fields) {
585 l.log.Warnw(msg, serializeMap(keysAndValues)...)
586}
587
588// Error logs a message at level Error on the standard logger.
589func (l logger) Error(args ...interface{}) {
590 l.log.Error(args...)
591}
592
593// Errorln logs a message at level Error on the standard logger with a line feed. Default in any case.
594func (l logger) Errorln(args ...interface{}) {
595 l.log.Error(args...)
596}
597
598// Errorf logs a message at level Error on the standard logger.
599func (l logger) Errorf(format string, args ...interface{}) {
600 l.log.Errorf(format, args...)
601}
602
603// Errorw logs a message with some additional context. The variadic key-value
604// pairs are treated as they are in With.
605func (l logger) Errorw(msg string, keysAndValues Fields) {
606 l.log.Errorw(msg, serializeMap(keysAndValues)...)
607}
608
609// Fatal logs a message at level Fatal on the standard logger.
610func (l logger) Fatal(args ...interface{}) {
611 l.log.Fatal(args...)
612}
613
614// Fatalln logs a message at level Fatal on the standard logger with a line feed. Default in any case.
615func (l logger) Fatalln(args ...interface{}) {
616 l.log.Fatal(args...)
617}
618
619// Fatalf logs a message at level Fatal on the standard logger.
620func (l logger) Fatalf(format string, args ...interface{}) {
621 l.log.Fatalf(format, args...)
622}
623
624// Fatalw logs a message with some additional context. The variadic key-value
625// pairs are treated as they are in With.
626func (l logger) Fatalw(msg string, keysAndValues Fields) {
627 l.log.Fatalw(msg, serializeMap(keysAndValues)...)
628}
629
630// Warning logs a message at level Warn on the standard logger.
631func (l logger) Warning(args ...interface{}) {
632 l.log.Warn(args...)
633}
634
635// Warningln logs a message at level Warn on the standard logger with a line feed. Default in any case.
636func (l logger) Warningln(args ...interface{}) {
637 l.log.Warn(args...)
638}
639
640// Warningf logs a message at level Warn on the standard logger.
641func (l logger) Warningf(format string, args ...interface{}) {
642 l.log.Warnf(format, args...)
643}
644
645// V reports whether verbosity level l is at least the requested verbose level.
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000646func (l logger) V(level LogLevel) bool {
647 return l.parent.Core().Enabled(logLevelToLevel(level))
William Kurkianea869482019-04-09 15:16:11 -0400648}
649
Esin Karamanccb714b2019-11-29 15:02:06 +0000650// GetLogLevel returns the current level of the logger
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000651func (l logger) GetLogLevel() LogLevel {
652 return levelToLogLevel(cfgs[l.packageName].Level.Level())
Esin Karamanccb714b2019-11-29 15:02:06 +0000653}
654
William Kurkianea869482019-04-09 15:16:11 -0400655// With returns a logger initialized with the key-value pairs
656func With(keysAndValues Fields) Logger {
657 return logger{log: getPackageLevelSugaredLogger().With(serializeMap(keysAndValues)...), parent: defaultLogger.parent}
658}
659
660// Debug logs a message at level Debug on the standard logger.
661func Debug(args ...interface{}) {
662 getPackageLevelSugaredLogger().Debug(args...)
663}
664
665// Debugln logs a message at level Debug on the standard logger.
666func Debugln(args ...interface{}) {
667 getPackageLevelSugaredLogger().Debug(args...)
668}
669
670// Debugf logs a message at level Debug on the standard logger.
671func Debugf(format string, args ...interface{}) {
672 getPackageLevelSugaredLogger().Debugf(format, args...)
673}
674
675// Debugw logs a message with some additional context. The variadic key-value
676// pairs are treated as they are in With.
677func Debugw(msg string, keysAndValues Fields) {
678 getPackageLevelSugaredLogger().Debugw(msg, serializeMap(keysAndValues)...)
679}
680
681// Info logs a message at level Info on the standard logger.
682func Info(args ...interface{}) {
683 getPackageLevelSugaredLogger().Info(args...)
684}
685
686// Infoln logs a message at level Info on the standard logger.
687func Infoln(args ...interface{}) {
688 getPackageLevelSugaredLogger().Info(args...)
689}
690
691// Infof logs a message at level Info on the standard logger.
692func Infof(format string, args ...interface{}) {
693 getPackageLevelSugaredLogger().Infof(format, args...)
694}
695
696//Infow logs a message with some additional context. The variadic key-value
697//pairs are treated as they are in With.
698func Infow(msg string, keysAndValues Fields) {
699 getPackageLevelSugaredLogger().Infow(msg, serializeMap(keysAndValues)...)
700}
701
702// Warn logs a message at level Warn on the standard logger.
703func Warn(args ...interface{}) {
704 getPackageLevelSugaredLogger().Warn(args...)
705}
706
707// Warnln logs a message at level Warn on the standard logger.
708func Warnln(args ...interface{}) {
709 getPackageLevelSugaredLogger().Warn(args...)
710}
711
712// Warnf logs a message at level Warn on the standard logger.
713func Warnf(format string, args ...interface{}) {
714 getPackageLevelSugaredLogger().Warnf(format, args...)
715}
716
717// Warnw logs a message with some additional context. The variadic key-value
718// pairs are treated as they are in With.
719func Warnw(msg string, keysAndValues Fields) {
720 getPackageLevelSugaredLogger().Warnw(msg, serializeMap(keysAndValues)...)
721}
722
723// Error logs a message at level Error on the standard logger.
724func Error(args ...interface{}) {
725 getPackageLevelSugaredLogger().Error(args...)
726}
727
728// Errorln logs a message at level Error on the standard logger.
729func Errorln(args ...interface{}) {
730 getPackageLevelSugaredLogger().Error(args...)
731}
732
733// Errorf logs a message at level Error on the standard logger.
734func Errorf(format string, args ...interface{}) {
735 getPackageLevelSugaredLogger().Errorf(format, args...)
736}
737
738// Errorw logs a message with some additional context. The variadic key-value
739// pairs are treated as they are in With.
740func Errorw(msg string, keysAndValues Fields) {
741 getPackageLevelSugaredLogger().Errorw(msg, serializeMap(keysAndValues)...)
742}
743
744// Fatal logs a message at level Fatal on the standard logger.
745func Fatal(args ...interface{}) {
746 getPackageLevelSugaredLogger().Fatal(args...)
747}
748
749// Fatalln logs a message at level Fatal on the standard logger.
750func Fatalln(args ...interface{}) {
751 getPackageLevelSugaredLogger().Fatal(args...)
752}
753
754// Fatalf logs a message at level Fatal on the standard logger.
755func Fatalf(format string, args ...interface{}) {
756 getPackageLevelSugaredLogger().Fatalf(format, args...)
757}
758
759// Fatalw logs a message with some additional context. The variadic key-value
760// pairs are treated as they are in With.
761func Fatalw(msg string, keysAndValues Fields) {
762 getPackageLevelSugaredLogger().Fatalw(msg, serializeMap(keysAndValues)...)
763}
764
765// Warning logs a message at level Warn on the standard logger.
766func Warning(args ...interface{}) {
767 getPackageLevelSugaredLogger().Warn(args...)
768}
769
770// Warningln logs a message at level Warn on the standard logger.
771func Warningln(args ...interface{}) {
772 getPackageLevelSugaredLogger().Warn(args...)
773}
774
775// Warningf logs a message at level Warn on the standard logger.
776func Warningf(format string, args ...interface{}) {
777 getPackageLevelSugaredLogger().Warnf(format, args...)
778}
779
780// V reports whether verbosity level l is at least the requested verbose level.
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000781func V(level LogLevel) bool {
William Kurkianea869482019-04-09 15:16:11 -0400782 return getPackageLevelLogger().V(level)
783}
Esin Karamanccb714b2019-11-29 15:02:06 +0000784
785//GetLogLevel returns the log level of the invoking package
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000786func GetLogLevel() LogLevel {
Esin Karamanccb714b2019-11-29 15:02:06 +0000787 return getPackageLevelLogger().GetLogLevel()
788}