| // Copyright (c) 2016 Uber Technologies, Inc. |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a copy |
| // of this software and associated documentation files (the "Software"), to deal |
| // in the Software without restriction, including without limitation the rights |
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| // copies of the Software, and to permit persons to whom the Software is |
| // furnished to do so, subject to the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included in |
| // all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| // THE SOFTWARE. |
| |
| package zapcore |
| |
| import ( |
| "bytes" |
| "errors" |
| "fmt" |
| ) |
| |
| var errUnmarshalNilLevel = errors.New("can't unmarshal a nil *Level") |
| |
| // A Level is a logging priority. Higher levels are more important. |
| type Level int8 |
| |
| const ( |
| // DebugLevel logs are typically voluminous, and are usually disabled in |
| // production. |
| DebugLevel Level = iota - 1 |
| // InfoLevel is the default logging priority. |
| InfoLevel |
| // WarnLevel logs are more important than Info, but don't need individual |
| // human review. |
| WarnLevel |
| // ErrorLevel logs are high-priority. If an application is running smoothly, |
| // it shouldn't generate any error-level logs. |
| ErrorLevel |
| // DPanicLevel logs are particularly important errors. In development the |
| // logger panics after writing the message. |
| DPanicLevel |
| // PanicLevel logs a message, then panics. |
| PanicLevel |
| // FatalLevel logs a message, then calls os.Exit(1). |
| FatalLevel |
| |
| _minLevel = DebugLevel |
| _maxLevel = FatalLevel |
| ) |
| |
| // String returns a lower-case ASCII representation of the log level. |
| func (l Level) String() string { |
| switch l { |
| case DebugLevel: |
| return "debug" |
| case InfoLevel: |
| return "info" |
| case WarnLevel: |
| return "warn" |
| case ErrorLevel: |
| return "error" |
| case DPanicLevel: |
| return "dpanic" |
| case PanicLevel: |
| return "panic" |
| case FatalLevel: |
| return "fatal" |
| default: |
| return fmt.Sprintf("Level(%d)", l) |
| } |
| } |
| |
| // CapitalString returns an all-caps ASCII representation of the log level. |
| func (l Level) CapitalString() string { |
| // Printing levels in all-caps is common enough that we should export this |
| // functionality. |
| switch l { |
| case DebugLevel: |
| return "DEBUG" |
| case InfoLevel: |
| return "INFO" |
| case WarnLevel: |
| return "WARN" |
| case ErrorLevel: |
| return "ERROR" |
| case DPanicLevel: |
| return "DPANIC" |
| case PanicLevel: |
| return "PANIC" |
| case FatalLevel: |
| return "FATAL" |
| default: |
| return fmt.Sprintf("LEVEL(%d)", l) |
| } |
| } |
| |
| // MarshalText marshals the Level to text. Note that the text representation |
| // drops the -Level suffix (see example). |
| func (l Level) MarshalText() ([]byte, error) { |
| return []byte(l.String()), nil |
| } |
| |
| // UnmarshalText unmarshals text to a level. Like MarshalText, UnmarshalText |
| // expects the text representation of a Level to drop the -Level suffix (see |
| // example). |
| // |
| // In particular, this makes it easy to configure logging levels using YAML, |
| // TOML, or JSON files. |
| func (l *Level) UnmarshalText(text []byte) error { |
| if l == nil { |
| return errUnmarshalNilLevel |
| } |
| if !l.unmarshalText(text) && !l.unmarshalText(bytes.ToLower(text)) { |
| return fmt.Errorf("unrecognized level: %q", text) |
| } |
| return nil |
| } |
| |
| func (l *Level) unmarshalText(text []byte) bool { |
| switch string(text) { |
| case "debug", "DEBUG": |
| *l = DebugLevel |
| case "info", "INFO", "": // make the zero value useful |
| *l = InfoLevel |
| case "warn", "WARN": |
| *l = WarnLevel |
| case "error", "ERROR": |
| *l = ErrorLevel |
| case "dpanic", "DPANIC": |
| *l = DPanicLevel |
| case "panic", "PANIC": |
| *l = PanicLevel |
| case "fatal", "FATAL": |
| *l = FatalLevel |
| default: |
| return false |
| } |
| return true |
| } |
| |
| // Set sets the level for the flag.Value interface. |
| func (l *Level) Set(s string) error { |
| return l.UnmarshalText([]byte(s)) |
| } |
| |
| // Get gets the level for the flag.Getter interface. |
| func (l *Level) Get() interface{} { |
| return *l |
| } |
| |
| // Enabled returns true if the given level is at or above this level. |
| func (l Level) Enabled(lvl Level) bool { |
| return lvl >= l |
| } |
| |
| // LevelEnabler decides whether a given logging level is enabled when logging a |
| // message. |
| // |
| // Enablers are intended to be used to implement deterministic filters; |
| // concerns like sampling are better implemented as a Core. |
| // |
| // Each concrete Level value implements a static LevelEnabler which returns |
| // true for itself and all higher logging levels. For example WarnLevel.Enabled() |
| // will return true for WarnLevel, ErrorLevel, DPanicLevel, PanicLevel, and |
| // FatalLevel, but return false for InfoLevel and DebugLevel. |
| type LevelEnabler interface { |
| Enabled(Level) bool |
| } |