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 | }
|
---|