...
1 package logrus
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 )
8
9 type fieldKey string
10
11
12 type FieldMap map[fieldKey]string
13
14 func (f FieldMap) resolve(key fieldKey) string {
15 if k, ok := f[key]; ok {
16 return k
17 }
18
19 return string(key)
20 }
21
22
23 type JSONFormatter struct {
24
25 TimestampFormat string
26
27
28 DisableTimestamp bool
29
30
31 DataKey string
32
33
34
35
36
37
38
39
40
41
42
43 FieldMap FieldMap
44
45
46 PrettyPrint bool
47 }
48
49
50 func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
51 data := make(Fields, len(entry.Data)+4)
52 for k, v := range entry.Data {
53 switch v := v.(type) {
54 case error:
55
56
57 data[k] = v.Error()
58 default:
59 data[k] = v
60 }
61 }
62
63 if f.DataKey != "" {
64 newData := make(Fields, 4)
65 newData[f.DataKey] = data
66 data = newData
67 }
68
69 prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
70
71 timestampFormat := f.TimestampFormat
72 if timestampFormat == "" {
73 timestampFormat = defaultTimestampFormat
74 }
75
76 if entry.err != "" {
77 data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
78 }
79 if !f.DisableTimestamp {
80 data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
81 }
82 data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
83 data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
84 if entry.HasCaller() {
85 data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
86 data[f.FieldMap.resolve(FieldKeyFile)] = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
87 }
88
89 var b *bytes.Buffer
90 if entry.Buffer != nil {
91 b = entry.Buffer
92 } else {
93 b = &bytes.Buffer{}
94 }
95
96 encoder := json.NewEncoder(b)
97 if f.PrettyPrint {
98 encoder.SetIndent("", " ")
99 }
100 if err := encoder.Encode(data); err != nil {
101 return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
102 }
103
104 return b.Bytes(), nil
105 }
106
View as plain text