66
|
1 package logrus
|
|
2
|
|
3 import "time"
|
|
4
|
|
5 // Default key names for the default fields
|
|
6 const (
|
|
7 defaultTimestampFormat = time.RFC3339
|
|
8 FieldKeyMsg = "msg"
|
|
9 FieldKeyLevel = "level"
|
|
10 FieldKeyTime = "time"
|
|
11 FieldKeyLogrusError = "logrus_error"
|
|
12 FieldKeyFunc = "func"
|
|
13 FieldKeyFile = "file"
|
|
14 )
|
|
15
|
|
16 // The Formatter interface is used to implement a custom Formatter. It takes an
|
|
17 // `Entry`. It exposes all the fields, including the default ones:
|
|
18 //
|
|
19 // * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
|
|
20 // * `entry.Data["time"]`. The timestamp.
|
|
21 // * `entry.Data["level"]. The level the entry was logged at.
|
|
22 //
|
|
23 // Any additional fields added with `WithField` or `WithFields` are also in
|
|
24 // `entry.Data`. Format is expected to return an array of bytes which are then
|
|
25 // logged to `logger.Out`.
|
|
26 type Formatter interface {
|
|
27 Format(*Entry) ([]byte, error)
|
|
28 }
|
|
29
|
|
30 // This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
|
|
31 // dumping it. If this code wasn't there doing:
|
|
32 //
|
|
33 // logrus.WithField("level", 1).Info("hello")
|
|
34 //
|
|
35 // Would just silently drop the user provided level. Instead with this code
|
|
36 // it'll logged as:
|
|
37 //
|
|
38 // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
|
39 //
|
|
40 // It's not exported because it's still using Data in an opinionated way. It's to
|
|
41 // avoid code duplication between the two default formatters.
|
|
42 func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
|
|
43 timeKey := fieldMap.resolve(FieldKeyTime)
|
|
44 if t, ok := data[timeKey]; ok {
|
|
45 data["fields."+timeKey] = t
|
|
46 delete(data, timeKey)
|
|
47 }
|
|
48
|
|
49 msgKey := fieldMap.resolve(FieldKeyMsg)
|
|
50 if m, ok := data[msgKey]; ok {
|
|
51 data["fields."+msgKey] = m
|
|
52 delete(data, msgKey)
|
|
53 }
|
|
54
|
|
55 levelKey := fieldMap.resolve(FieldKeyLevel)
|
|
56 if l, ok := data[levelKey]; ok {
|
|
57 data["fields."+levelKey] = l
|
|
58 delete(data, levelKey)
|
|
59 }
|
|
60
|
|
61 logrusErrKey := fieldMap.resolve(FieldKeyLogrusError)
|
|
62 if l, ok := data[logrusErrKey]; ok {
|
|
63 data["fields."+logrusErrKey] = l
|
|
64 delete(data, logrusErrKey)
|
|
65 }
|
|
66
|
|
67 // If reportCaller is not set, 'func' will not conflict.
|
|
68 if reportCaller {
|
|
69 funcKey := fieldMap.resolve(FieldKeyFunc)
|
|
70 if l, ok := data[funcKey]; ok {
|
|
71 data["fields."+funcKey] = l
|
|
72 }
|
|
73 fileKey := fieldMap.resolve(FieldKeyFile)
|
|
74 if l, ok := data[fileKey]; ok {
|
|
75 data["fields."+fileKey] = l
|
|
76 }
|
|
77 }
|
|
78 }
|