diff options
Diffstat (limited to 'vendor/github.com/sirupsen/logrus/entry.go')
-rw-r--r-- | vendor/github.com/sirupsen/logrus/entry.go | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go new file mode 100644 index 0000000..71cdbbc --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/entry.go | |||
@@ -0,0 +1,442 @@ | |||
1 | package logrus | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "context" | ||
6 | "fmt" | ||
7 | "os" | ||
8 | "reflect" | ||
9 | "runtime" | ||
10 | "strings" | ||
11 | "sync" | ||
12 | "time" | ||
13 | ) | ||
14 | |||
15 | var ( | ||
16 | |||
17 | // qualified package name, cached at first use | ||
18 | logrusPackage string | ||
19 | |||
20 | // Positions in the call stack when tracing to report the calling method | ||
21 | minimumCallerDepth int | ||
22 | |||
23 | // Used for caller information initialisation | ||
24 | callerInitOnce sync.Once | ||
25 | ) | ||
26 | |||
27 | const ( | ||
28 | maximumCallerDepth int = 25 | ||
29 | knownLogrusFrames int = 4 | ||
30 | ) | ||
31 | |||
32 | func init() { | ||
33 | // start at the bottom of the stack before the package-name cache is primed | ||
34 | minimumCallerDepth = 1 | ||
35 | } | ||
36 | |||
37 | // Defines the key when adding errors using WithError. | ||
38 | var ErrorKey = "error" | ||
39 | |||
40 | // An entry is the final or intermediate Logrus logging entry. It contains all | ||
41 | // the fields passed with WithField{,s}. It's finally logged when Trace, Debug, | ||
42 | // Info, Warn, Error, Fatal or Panic is called on it. These objects can be | ||
43 | // reused and passed around as much as you wish to avoid field duplication. | ||
44 | type Entry struct { | ||
45 | Logger *Logger | ||
46 | |||
47 | // Contains all the fields set by the user. | ||
48 | Data Fields | ||
49 | |||
50 | // Time at which the log entry was created | ||
51 | Time time.Time | ||
52 | |||
53 | // Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic | ||
54 | // This field will be set on entry firing and the value will be equal to the one in Logger struct field. | ||
55 | Level Level | ||
56 | |||
57 | // Calling method, with package name | ||
58 | Caller *runtime.Frame | ||
59 | |||
60 | // Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic | ||
61 | Message string | ||
62 | |||
63 | // When formatter is called in entry.log(), a Buffer may be set to entry | ||
64 | Buffer *bytes.Buffer | ||
65 | |||
66 | // Contains the context set by the user. Useful for hook processing etc. | ||
67 | Context context.Context | ||
68 | |||
69 | // err may contain a field formatting error | ||
70 | err string | ||
71 | } | ||
72 | |||
73 | func NewEntry(logger *Logger) *Entry { | ||
74 | return &Entry{ | ||
75 | Logger: logger, | ||
76 | // Default is three fields, plus one optional. Give a little extra room. | ||
77 | Data: make(Fields, 6), | ||
78 | } | ||
79 | } | ||
80 | |||
81 | func (entry *Entry) Dup() *Entry { | ||
82 | data := make(Fields, len(entry.Data)) | ||
83 | for k, v := range entry.Data { | ||
84 | data[k] = v | ||
85 | } | ||
86 | return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err} | ||
87 | } | ||
88 | |||
89 | // Returns the bytes representation of this entry from the formatter. | ||
90 | func (entry *Entry) Bytes() ([]byte, error) { | ||
91 | return entry.Logger.Formatter.Format(entry) | ||
92 | } | ||
93 | |||
94 | // Returns the string representation from the reader and ultimately the | ||
95 | // formatter. | ||
96 | func (entry *Entry) String() (string, error) { | ||
97 | serialized, err := entry.Bytes() | ||
98 | if err != nil { | ||
99 | return "", err | ||
100 | } | ||
101 | str := string(serialized) | ||
102 | return str, nil | ||
103 | } | ||
104 | |||
105 | // Add an error as single field (using the key defined in ErrorKey) to the Entry. | ||
106 | func (entry *Entry) WithError(err error) *Entry { | ||
107 | return entry.WithField(ErrorKey, err) | ||
108 | } | ||
109 | |||
110 | // Add a context to the Entry. | ||
111 | func (entry *Entry) WithContext(ctx context.Context) *Entry { | ||
112 | dataCopy := make(Fields, len(entry.Data)) | ||
113 | for k, v := range entry.Data { | ||
114 | dataCopy[k] = v | ||
115 | } | ||
116 | return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx} | ||
117 | } | ||
118 | |||
119 | // Add a single field to the Entry. | ||
120 | func (entry *Entry) WithField(key string, value interface{}) *Entry { | ||
121 | return entry.WithFields(Fields{key: value}) | ||
122 | } | ||
123 | |||
124 | // Add a map of fields to the Entry. | ||
125 | func (entry *Entry) WithFields(fields Fields) *Entry { | ||
126 | data := make(Fields, len(entry.Data)+len(fields)) | ||
127 | for k, v := range entry.Data { | ||
128 | data[k] = v | ||
129 | } | ||
130 | fieldErr := entry.err | ||
131 | for k, v := range fields { | ||
132 | isErrField := false | ||
133 | if t := reflect.TypeOf(v); t != nil { | ||
134 | switch { | ||
135 | case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func: | ||
136 | isErrField = true | ||
137 | } | ||
138 | } | ||
139 | if isErrField { | ||
140 | tmp := fmt.Sprintf("can not add field %q", k) | ||
141 | if fieldErr != "" { | ||
142 | fieldErr = entry.err + ", " + tmp | ||
143 | } else { | ||
144 | fieldErr = tmp | ||
145 | } | ||
146 | } else { | ||
147 | data[k] = v | ||
148 | } | ||
149 | } | ||
150 | return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context} | ||
151 | } | ||
152 | |||
153 | // Overrides the time of the Entry. | ||
154 | func (entry *Entry) WithTime(t time.Time) *Entry { | ||
155 | dataCopy := make(Fields, len(entry.Data)) | ||
156 | for k, v := range entry.Data { | ||
157 | dataCopy[k] = v | ||
158 | } | ||
159 | return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context} | ||
160 | } | ||
161 | |||
162 | // getPackageName reduces a fully qualified function name to the package name | ||
163 | // There really ought to be to be a better way... | ||
164 | func getPackageName(f string) string { | ||
165 | for { | ||
166 | lastPeriod := strings.LastIndex(f, ".") | ||
167 | lastSlash := strings.LastIndex(f, "/") | ||
168 | if lastPeriod > lastSlash { | ||
169 | f = f[:lastPeriod] | ||
170 | } else { | ||
171 | break | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return f | ||
176 | } | ||
177 | |||
178 | // getCaller retrieves the name of the first non-logrus calling function | ||
179 | func getCaller() *runtime.Frame { | ||
180 | // cache this package's fully-qualified name | ||
181 | callerInitOnce.Do(func() { | ||
182 | pcs := make([]uintptr, maximumCallerDepth) | ||
183 | _ = runtime.Callers(0, pcs) | ||
184 | |||
185 | // dynamic get the package name and the minimum caller depth | ||
186 | for i := 0; i < maximumCallerDepth; i++ { | ||
187 | funcName := runtime.FuncForPC(pcs[i]).Name() | ||
188 | if strings.Contains(funcName, "getCaller") { | ||
189 | logrusPackage = getPackageName(funcName) | ||
190 | break | ||
191 | } | ||
192 | } | ||
193 | |||
194 | minimumCallerDepth = knownLogrusFrames | ||
195 | }) | ||
196 | |||
197 | // Restrict the lookback frames to avoid runaway lookups | ||
198 | pcs := make([]uintptr, maximumCallerDepth) | ||
199 | depth := runtime.Callers(minimumCallerDepth, pcs) | ||
200 | frames := runtime.CallersFrames(pcs[:depth]) | ||
201 | |||
202 | for f, again := frames.Next(); again; f, again = frames.Next() { | ||
203 | pkg := getPackageName(f.Function) | ||
204 | |||
205 | // If the caller isn't part of this package, we're done | ||
206 | if pkg != logrusPackage { | ||
207 | return &f //nolint:scopelint | ||
208 | } | ||
209 | } | ||
210 | |||
211 | // if we got here, we failed to find the caller's context | ||
212 | return nil | ||
213 | } | ||
214 | |||
215 | func (entry Entry) HasCaller() (has bool) { | ||
216 | return entry.Logger != nil && | ||
217 | entry.Logger.ReportCaller && | ||
218 | entry.Caller != nil | ||
219 | } | ||
220 | |||
221 | func (entry *Entry) log(level Level, msg string) { | ||
222 | var buffer *bytes.Buffer | ||
223 | |||
224 | newEntry := entry.Dup() | ||
225 | |||
226 | if newEntry.Time.IsZero() { | ||
227 | newEntry.Time = time.Now() | ||
228 | } | ||
229 | |||
230 | newEntry.Level = level | ||
231 | newEntry.Message = msg | ||
232 | |||
233 | newEntry.Logger.mu.Lock() | ||
234 | reportCaller := newEntry.Logger.ReportCaller | ||
235 | bufPool := newEntry.getBufferPool() | ||
236 | newEntry.Logger.mu.Unlock() | ||
237 | |||
238 | if reportCaller { | ||
239 | newEntry.Caller = getCaller() | ||
240 | } | ||
241 | |||
242 | newEntry.fireHooks() | ||
243 | buffer = bufPool.Get() | ||
244 | defer func() { | ||
245 | newEntry.Buffer = nil | ||
246 | buffer.Reset() | ||
247 | bufPool.Put(buffer) | ||
248 | }() | ||
249 | buffer.Reset() | ||
250 | newEntry.Buffer = buffer | ||
251 | |||
252 | newEntry.write() | ||
253 | |||
254 | newEntry.Buffer = nil | ||
255 | |||
256 | // To avoid Entry#log() returning a value that only would make sense for | ||
257 | // panic() to use in Entry#Panic(), we avoid the allocation by checking | ||
258 | // directly here. | ||
259 | if level <= PanicLevel { | ||
260 | panic(newEntry) | ||
261 | } | ||
262 | } | ||
263 | |||
264 | func (entry *Entry) getBufferPool() (pool BufferPool) { | ||
265 | if entry.Logger.BufferPool != nil { | ||
266 | return entry.Logger.BufferPool | ||
267 | } | ||
268 | return bufferPool | ||
269 | } | ||
270 | |||
271 | func (entry *Entry) fireHooks() { | ||
272 | var tmpHooks LevelHooks | ||
273 | entry.Logger.mu.Lock() | ||
274 | tmpHooks = make(LevelHooks, len(entry.Logger.Hooks)) | ||
275 | for k, v := range entry.Logger.Hooks { | ||
276 | tmpHooks[k] = v | ||
277 | } | ||
278 | entry.Logger.mu.Unlock() | ||
279 | |||
280 | err := tmpHooks.Fire(entry.Level, entry) | ||
281 | if err != nil { | ||
282 | fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) | ||
283 | } | ||
284 | } | ||
285 | |||
286 | func (entry *Entry) write() { | ||
287 | entry.Logger.mu.Lock() | ||
288 | defer entry.Logger.mu.Unlock() | ||
289 | serialized, err := entry.Logger.Formatter.Format(entry) | ||
290 | if err != nil { | ||
291 | fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) | ||
292 | return | ||
293 | } | ||
294 | if _, err := entry.Logger.Out.Write(serialized); err != nil { | ||
295 | fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) | ||
296 | } | ||
297 | } | ||
298 | |||
299 | // Log will log a message at the level given as parameter. | ||
300 | // Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. | ||
301 | // For this behaviour Entry.Panic or Entry.Fatal should be used instead. | ||
302 | func (entry *Entry) Log(level Level, args ...interface{}) { | ||
303 | if entry.Logger.IsLevelEnabled(level) { | ||
304 | entry.log(level, fmt.Sprint(args...)) | ||
305 | } | ||
306 | } | ||
307 | |||
308 | func (entry *Entry) Trace(args ...interface{}) { | ||
309 | entry.Log(TraceLevel, args...) | ||
310 | } | ||
311 | |||
312 | func (entry *Entry) Debug(args ...interface{}) { | ||
313 | entry.Log(DebugLevel, args...) | ||
314 | } | ||
315 | |||
316 | func (entry *Entry) Print(args ...interface{}) { | ||
317 | entry.Info(args...) | ||
318 | } | ||
319 | |||
320 | func (entry *Entry) Info(args ...interface{}) { | ||
321 | entry.Log(InfoLevel, args...) | ||
322 | } | ||
323 | |||
324 | func (entry *Entry) Warn(args ...interface{}) { | ||
325 | entry.Log(WarnLevel, args...) | ||
326 | } | ||
327 | |||
328 | func (entry *Entry) Warning(args ...interface{}) { | ||
329 | entry.Warn(args...) | ||
330 | } | ||
331 | |||
332 | func (entry *Entry) Error(args ...interface{}) { | ||
333 | entry.Log(ErrorLevel, args...) | ||
334 | } | ||
335 | |||
336 | func (entry *Entry) Fatal(args ...interface{}) { | ||
337 | entry.Log(FatalLevel, args...) | ||
338 | entry.Logger.Exit(1) | ||
339 | } | ||
340 | |||
341 | func (entry *Entry) Panic(args ...interface{}) { | ||
342 | entry.Log(PanicLevel, args...) | ||
343 | } | ||
344 | |||
345 | // Entry Printf family functions | ||
346 | |||
347 | func (entry *Entry) Logf(level Level, format string, args ...interface{}) { | ||
348 | if entry.Logger.IsLevelEnabled(level) { | ||
349 | entry.Log(level, fmt.Sprintf(format, args...)) | ||
350 | } | ||
351 | } | ||
352 | |||
353 | func (entry *Entry) Tracef(format string, args ...interface{}) { | ||
354 | entry.Logf(TraceLevel, format, args...) | ||
355 | } | ||
356 | |||
357 | func (entry *Entry) Debugf(format string, args ...interface{}) { | ||
358 | entry.Logf(DebugLevel, format, args...) | ||
359 | } | ||
360 | |||
361 | func (entry *Entry) Infof(format string, args ...interface{}) { | ||
362 | entry.Logf(InfoLevel, format, args...) | ||
363 | } | ||
364 | |||
365 | func (entry *Entry) Printf(format string, args ...interface{}) { | ||
366 | entry.Infof(format, args...) | ||
367 | } | ||
368 | |||
369 | func (entry *Entry) Warnf(format string, args ...interface{}) { | ||
370 | entry.Logf(WarnLevel, format, args...) | ||
371 | } | ||
372 | |||
373 | func (entry *Entry) Warningf(format string, args ...interface{}) { | ||
374 | entry.Warnf(format, args...) | ||
375 | } | ||
376 | |||
377 | func (entry *Entry) Errorf(format string, args ...interface{}) { | ||
378 | entry.Logf(ErrorLevel, format, args...) | ||
379 | } | ||
380 | |||
381 | func (entry *Entry) Fatalf(format string, args ...interface{}) { | ||
382 | entry.Logf(FatalLevel, format, args...) | ||
383 | entry.Logger.Exit(1) | ||
384 | } | ||
385 | |||
386 | func (entry *Entry) Panicf(format string, args ...interface{}) { | ||
387 | entry.Logf(PanicLevel, format, args...) | ||
388 | } | ||
389 | |||
390 | // Entry Println family functions | ||
391 | |||
392 | func (entry *Entry) Logln(level Level, args ...interface{}) { | ||
393 | if entry.Logger.IsLevelEnabled(level) { | ||
394 | entry.Log(level, entry.sprintlnn(args...)) | ||
395 | } | ||
396 | } | ||
397 | |||
398 | func (entry *Entry) Traceln(args ...interface{}) { | ||
399 | entry.Logln(TraceLevel, args...) | ||
400 | } | ||
401 | |||
402 | func (entry *Entry) Debugln(args ...interface{}) { | ||
403 | entry.Logln(DebugLevel, args...) | ||
404 | } | ||
405 | |||
406 | func (entry *Entry) Infoln(args ...interface{}) { | ||
407 | entry.Logln(InfoLevel, args...) | ||
408 | } | ||
409 | |||
410 | func (entry *Entry) Println(args ...interface{}) { | ||
411 | entry.Infoln(args...) | ||
412 | } | ||
413 | |||
414 | func (entry *Entry) Warnln(args ...interface{}) { | ||
415 | entry.Logln(WarnLevel, args...) | ||
416 | } | ||
417 | |||
418 | func (entry *Entry) Warningln(args ...interface{}) { | ||
419 | entry.Warnln(args...) | ||
420 | } | ||
421 | |||
422 | func (entry *Entry) Errorln(args ...interface{}) { | ||
423 | entry.Logln(ErrorLevel, args...) | ||
424 | } | ||
425 | |||
426 | func (entry *Entry) Fatalln(args ...interface{}) { | ||
427 | entry.Logln(FatalLevel, args...) | ||
428 | entry.Logger.Exit(1) | ||
429 | } | ||
430 | |||
431 | func (entry *Entry) Panicln(args ...interface{}) { | ||
432 | entry.Logln(PanicLevel, args...) | ||
433 | } | ||
434 | |||
435 | // Sprintlnn => Sprint no newline. This is to get the behavior of how | ||
436 | // fmt.Sprintln where spaces are always added between operands, regardless of | ||
437 | // their type. Instead of vendoring the Sprintln implementation to spare a | ||
438 | // string allocation, we do the simplest thing. | ||
439 | func (entry *Entry) sprintlnn(args ...interface{}) string { | ||
440 | msg := fmt.Sprintln(args...) | ||
441 | return msg[:len(msg)-1] | ||
442 | } | ||