1
18
19 package grpclog
20
21 import (
22 "encoding/json"
23 "fmt"
24 "io"
25 "log"
26 "os"
27 "strconv"
28 "strings"
29
30 "google.golang.org/grpc/internal/grpclog"
31 )
32
33
34 type LoggerV2 interface {
35
36 Info(args ...any)
37
38 Infoln(args ...any)
39
40 Infof(format string, args ...any)
41
42 Warning(args ...any)
43
44 Warningln(args ...any)
45
46 Warningf(format string, args ...any)
47
48 Error(args ...any)
49
50 Errorln(args ...any)
51
52 Errorf(format string, args ...any)
53
54
55
56 Fatal(args ...any)
57
58
59
60 Fatalln(args ...any)
61
62
63
64 Fatalf(format string, args ...any)
65
66 V(l int) bool
67 }
68
69
70
71 func SetLoggerV2(l LoggerV2) {
72 if _, ok := l.(*componentData); ok {
73 panic("cannot use component logger as grpclog logger")
74 }
75 grpclog.Logger = l
76 grpclog.DepthLogger, _ = l.(grpclog.DepthLoggerV2)
77 }
78
79 const (
80
81 infoLog int = iota
82
83 warningLog
84
85 errorLog
86
87 fatalLog
88 )
89
90
91 var severityName = []string{
92 infoLog: "INFO",
93 warningLog: "WARNING",
94 errorLog: "ERROR",
95 fatalLog: "FATAL",
96 }
97
98
99 type loggerT struct {
100 m []*log.Logger
101 v int
102 jsonFormat bool
103 }
104
105
106
107
108
109
110 func NewLoggerV2(infoW, warningW, errorW io.Writer) LoggerV2 {
111 return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{})
112 }
113
114
115
116 func NewLoggerV2WithVerbosity(infoW, warningW, errorW io.Writer, v int) LoggerV2 {
117 return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{verbose: v})
118 }
119
120 type loggerV2Config struct {
121 verbose int
122 jsonFormat bool
123 }
124
125 func newLoggerV2WithConfig(infoW, warningW, errorW io.Writer, c loggerV2Config) LoggerV2 {
126 var m []*log.Logger
127 flag := log.LstdFlags
128 if c.jsonFormat {
129 flag = 0
130 }
131 m = append(m, log.New(infoW, "", flag))
132 m = append(m, log.New(io.MultiWriter(infoW, warningW), "", flag))
133 ew := io.MultiWriter(infoW, warningW, errorW)
134 m = append(m, log.New(ew, "", flag))
135 m = append(m, log.New(ew, "", flag))
136 return &loggerT{m: m, v: c.verbose, jsonFormat: c.jsonFormat}
137 }
138
139
140
141 func newLoggerV2() LoggerV2 {
142 errorW := io.Discard
143 warningW := io.Discard
144 infoW := io.Discard
145
146 logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL")
147 switch logLevel {
148 case "", "ERROR", "error":
149 errorW = os.Stderr
150 case "WARNING", "warning":
151 warningW = os.Stderr
152 case "INFO", "info":
153 infoW = os.Stderr
154 }
155
156 var v int
157 vLevel := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL")
158 if vl, err := strconv.Atoi(vLevel); err == nil {
159 v = vl
160 }
161
162 jsonFormat := strings.EqualFold(os.Getenv("GRPC_GO_LOG_FORMATTER"), "json")
163
164 return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{
165 verbose: v,
166 jsonFormat: jsonFormat,
167 })
168 }
169
170 func (g *loggerT) output(severity int, s string) {
171 sevStr := severityName[severity]
172 if !g.jsonFormat {
173 g.m[severity].Output(2, fmt.Sprintf("%v: %v", sevStr, s))
174 return
175 }
176
177
178 b, _ := json.Marshal(map[string]string{
179 "severity": sevStr,
180 "message": s,
181 })
182 g.m[severity].Output(2, string(b))
183 }
184
185 func (g *loggerT) Info(args ...any) {
186 g.output(infoLog, fmt.Sprint(args...))
187 }
188
189 func (g *loggerT) Infoln(args ...any) {
190 g.output(infoLog, fmt.Sprintln(args...))
191 }
192
193 func (g *loggerT) Infof(format string, args ...any) {
194 g.output(infoLog, fmt.Sprintf(format, args...))
195 }
196
197 func (g *loggerT) Warning(args ...any) {
198 g.output(warningLog, fmt.Sprint(args...))
199 }
200
201 func (g *loggerT) Warningln(args ...any) {
202 g.output(warningLog, fmt.Sprintln(args...))
203 }
204
205 func (g *loggerT) Warningf(format string, args ...any) {
206 g.output(warningLog, fmt.Sprintf(format, args...))
207 }
208
209 func (g *loggerT) Error(args ...any) {
210 g.output(errorLog, fmt.Sprint(args...))
211 }
212
213 func (g *loggerT) Errorln(args ...any) {
214 g.output(errorLog, fmt.Sprintln(args...))
215 }
216
217 func (g *loggerT) Errorf(format string, args ...any) {
218 g.output(errorLog, fmt.Sprintf(format, args...))
219 }
220
221 func (g *loggerT) Fatal(args ...any) {
222 g.output(fatalLog, fmt.Sprint(args...))
223 os.Exit(1)
224 }
225
226 func (g *loggerT) Fatalln(args ...any) {
227 g.output(fatalLog, fmt.Sprintln(args...))
228 os.Exit(1)
229 }
230
231 func (g *loggerT) Fatalf(format string, args ...any) {
232 g.output(fatalLog, fmt.Sprintf(format, args...))
233 os.Exit(1)
234 }
235
236 func (g *loggerT) V(l int) bool {
237 return l <= g.v
238 }
239
240
241
242
243
244
245
246
247
248 type DepthLoggerV2 interface {
249 LoggerV2
250
251 InfoDepth(depth int, args ...any)
252
253 WarningDepth(depth int, args ...any)
254
255 ErrorDepth(depth int, args ...any)
256
257 FatalDepth(depth int, args ...any)
258 }
259
View as plain text