Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / go.uber.org / zap / global.go
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
21 package zap
22
23 import (
24         "bytes"
25         "fmt"
26         "log"
27         "os"
28         "sync"
29
30         "go.uber.org/zap/zapcore"
31 )
32
33 const (
34         _stdLogDefaultDepth      = 2
35         _loggerWriterDepth       = 2
36         _programmerErrorTemplate = "You've found a bug in zap! Please file a bug at " +
37                 "https://github.com/uber-go/zap/issues/new and reference this error: %v"
38 )
39
40 var (
41         _globalMu sync.RWMutex
42         _globalL  = NewNop()
43         _globalS  = _globalL.Sugar()
44 )
45
46 // L returns the global Logger, which can be reconfigured with ReplaceGlobals.
47 // It's safe for concurrent use.
48 func L() *Logger {
49         _globalMu.RLock()
50         l := _globalL
51         _globalMu.RUnlock()
52         return l
53 }
54
55 // S returns the global SugaredLogger, which can be reconfigured with
56 // ReplaceGlobals. It's safe for concurrent use.
57 func S() *SugaredLogger {
58         _globalMu.RLock()
59         s := _globalS
60         _globalMu.RUnlock()
61         return s
62 }
63
64 // ReplaceGlobals replaces the global Logger and SugaredLogger, and returns a
65 // function to restore the original values. It's safe for concurrent use.
66 func ReplaceGlobals(logger *Logger) func() {
67         _globalMu.Lock()
68         prev := _globalL
69         _globalL = logger
70         _globalS = logger.Sugar()
71         _globalMu.Unlock()
72         return func() { ReplaceGlobals(prev) }
73 }
74
75 // NewStdLog returns a *log.Logger which writes to the supplied zap Logger at
76 // InfoLevel. To redirect the standard library's package-global logging
77 // functions, use RedirectStdLog instead.
78 func NewStdLog(l *Logger) *log.Logger {
79         logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
80         f := logger.Info
81         return log.New(&loggerWriter{f}, "" /* prefix */, 0 /* flags */)
82 }
83
84 // NewStdLogAt returns *log.Logger which writes to supplied zap logger at
85 // required level.
86 func NewStdLogAt(l *Logger, level zapcore.Level) (*log.Logger, error) {
87         logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
88         logFunc, err := levelToFunc(logger, level)
89         if err != nil {
90                 return nil, err
91         }
92         return log.New(&loggerWriter{logFunc}, "" /* prefix */, 0 /* flags */), nil
93 }
94
95 // RedirectStdLog redirects output from the standard library's package-global
96 // logger to the supplied logger at InfoLevel. Since zap already handles caller
97 // annotations, timestamps, etc., it automatically disables the standard
98 // library's annotations and prefixing.
99 //
100 // It returns a function to restore the original prefix and flags and reset the
101 // standard library's output to os.Stderr.
102 func RedirectStdLog(l *Logger) func() {
103         f, err := redirectStdLogAt(l, InfoLevel)
104         if err != nil {
105                 // Can't get here, since passing InfoLevel to redirectStdLogAt always
106                 // works.
107                 panic(fmt.Sprintf(_programmerErrorTemplate, err))
108         }
109         return f
110 }
111
112 // RedirectStdLogAt redirects output from the standard library's package-global
113 // logger to the supplied logger at the specified level. Since zap already
114 // handles caller annotations, timestamps, etc., it automatically disables the
115 // standard library's annotations and prefixing.
116 //
117 // It returns a function to restore the original prefix and flags and reset the
118 // standard library's output to os.Stderr.
119 func RedirectStdLogAt(l *Logger, level zapcore.Level) (func(), error) {
120         return redirectStdLogAt(l, level)
121 }
122
123 func redirectStdLogAt(l *Logger, level zapcore.Level) (func(), error) {
124         flags := log.Flags()
125         prefix := log.Prefix()
126         log.SetFlags(0)
127         log.SetPrefix("")
128         logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
129         logFunc, err := levelToFunc(logger, level)
130         if err != nil {
131                 return nil, err
132         }
133         log.SetOutput(&loggerWriter{logFunc})
134         return func() {
135                 log.SetFlags(flags)
136                 log.SetPrefix(prefix)
137                 log.SetOutput(os.Stderr)
138         }, nil
139 }
140
141 func levelToFunc(logger *Logger, lvl zapcore.Level) (func(string, ...Field), error) {
142         switch lvl {
143         case DebugLevel:
144                 return logger.Debug, nil
145         case InfoLevel:
146                 return logger.Info, nil
147         case WarnLevel:
148                 return logger.Warn, nil
149         case ErrorLevel:
150                 return logger.Error, nil
151         case DPanicLevel:
152                 return logger.DPanic, nil
153         case PanicLevel:
154                 return logger.Panic, nil
155         case FatalLevel:
156                 return logger.Fatal, nil
157         }
158         return nil, fmt.Errorf("unrecognized level: %q", lvl)
159 }
160
161 type loggerWriter struct {
162         logFunc func(msg string, fields ...Field)
163 }
164
165 func (l *loggerWriter) Write(p []byte) (int, error) {
166         p = bytes.TrimSpace(p)
167         l.logFunc(string(p))
168         return len(p), nil
169 }