1// Copyright (c) 2016 Uber Technologies, Inc. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a copy 4// of this software and associated documentation files (the "Software"), to deal 5// in the Software without restriction, including without limitation the rights 6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7// copies of the Software, and to permit persons to whom the Software is 8// furnished to do so, subject to the following conditions: 9// 10// The above copyright notice and this permission notice shall be included in 11// all copies or substantial portions of the Software. 12// 13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19// THE SOFTWARE. 20 21package zap 22 23import ( 24 "go.uber.org/atomic" 25 "go.uber.org/zap/zapcore" 26) 27 28const ( 29 // DebugLevel logs are typically voluminous, and are usually disabled in 30 // production. 31 DebugLevel = zapcore.DebugLevel 32 // InfoLevel is the default logging priority. 33 InfoLevel = zapcore.InfoLevel 34 // WarnLevel logs are more important than Info, but don't need individual 35 // human review. 36 WarnLevel = zapcore.WarnLevel 37 // ErrorLevel logs are high-priority. If an application is running smoothly, 38 // it shouldn't generate any error-level logs. 39 ErrorLevel = zapcore.ErrorLevel 40 // DPanicLevel logs are particularly important errors. In development the 41 // logger panics after writing the message. 42 DPanicLevel = zapcore.DPanicLevel 43 // PanicLevel logs a message, then panics. 44 PanicLevel = zapcore.PanicLevel 45 // FatalLevel logs a message, then calls os.Exit(1). 46 FatalLevel = zapcore.FatalLevel 47) 48 49// LevelEnablerFunc is a convenient way to implement zapcore.LevelEnabler with 50// an anonymous function. 51// 52// It's particularly useful when splitting log output between different 53// outputs (e.g., standard error and standard out). For sample code, see the 54// package-level AdvancedConfiguration example. 55type LevelEnablerFunc func(zapcore.Level) bool 56 57// Enabled calls the wrapped function. 58func (f LevelEnablerFunc) Enabled(lvl zapcore.Level) bool { return f(lvl) } 59 60// An AtomicLevel is an atomically changeable, dynamic logging level. It lets 61// you safely change the log level of a tree of loggers (the root logger and 62// any children created by adding context) at runtime. 63// 64// The AtomicLevel itself is an http.Handler that serves a JSON endpoint to 65// alter its level. 66// 67// AtomicLevels must be created with the NewAtomicLevel constructor to allocate 68// their internal atomic pointer. 69type AtomicLevel struct { 70 l *atomic.Int32 71} 72 73// NewAtomicLevel creates an AtomicLevel with InfoLevel and above logging 74// enabled. 75func NewAtomicLevel() AtomicLevel { 76 return AtomicLevel{ 77 l: atomic.NewInt32(int32(InfoLevel)), 78 } 79} 80 81// NewAtomicLevelAt is a convenience function that creates an AtomicLevel 82// and then calls SetLevel with the given level. 83func NewAtomicLevelAt(l zapcore.Level) AtomicLevel { 84 a := NewAtomicLevel() 85 a.SetLevel(l) 86 return a 87} 88 89// Enabled implements the zapcore.LevelEnabler interface, which allows the 90// AtomicLevel to be used in place of traditional static levels. 91func (lvl AtomicLevel) Enabled(l zapcore.Level) bool { 92 return lvl.Level().Enabled(l) 93} 94 95// Level returns the minimum enabled log level. 96func (lvl AtomicLevel) Level() zapcore.Level { 97 return zapcore.Level(int8(lvl.l.Load())) 98} 99 100// SetLevel alters the logging level. 101func (lvl AtomicLevel) SetLevel(l zapcore.Level) { 102 lvl.l.Store(int32(l)) 103} 104 105// String returns the string representation of the underlying Level. 106func (lvl AtomicLevel) String() string { 107 return lvl.Level().String() 108} 109 110// UnmarshalText unmarshals the text to an AtomicLevel. It uses the same text 111// representations as the static zapcore.Levels ("debug", "info", "warn", 112// "error", "dpanic", "panic", and "fatal"). 113func (lvl *AtomicLevel) UnmarshalText(text []byte) error { 114 if lvl.l == nil { 115 lvl.l = &atomic.Int32{} 116 } 117 118 var l zapcore.Level 119 if err := l.UnmarshalText(text); err != nil { 120 return err 121 } 122 123 lvl.SetLevel(l) 124 return nil 125} 126 127// MarshalText marshals the AtomicLevel to a byte slice. It uses the same 128// text representation as the static zapcore.Levels ("debug", "info", "warn", 129// "error", "dpanic", "panic", and "fatal"). 130func (lvl AtomicLevel) MarshalText() (text []byte, err error) { 131 return lvl.Level().MarshalText() 132} 133