Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/go.uber.org/zap/global.go
2872 views
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 = 1
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
}
170
171