packer-cn/vendor/github.com/sirupsen/logrus/json_formatter.go

122 lines
3.0 KiB
Go
Raw Normal View History

2018-02-05 19:52:44 -05:00
package logrus
import (
2019-04-10 09:41:22 -04:00
"bytes"
2018-02-05 19:52:44 -05:00
"encoding/json"
"fmt"
2019-09-23 14:09:10 -04:00
"runtime"
2018-02-05 19:52:44 -05:00
)
type fieldKey string
// FieldMap allows customization of the key names for default fields.
2018-02-05 19:52:44 -05:00
type FieldMap map[fieldKey]string
func (f FieldMap) resolve(key fieldKey) string {
if k, ok := f[key]; ok {
return k
}
return string(key)
}
// JSONFormatter formats logs into parsable json
2018-02-05 19:52:44 -05:00
type JSONFormatter struct {
// TimestampFormat sets the format used for marshaling timestamps.
TimestampFormat string
// DisableTimestamp allows disabling automatic timestamps in output
DisableTimestamp bool
2019-04-10 09:41:22 -04:00
// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
DataKey string
// FieldMap allows users to customize the names of keys for default fields.
2018-02-05 19:52:44 -05:00
// As an example:
// formatter := &JSONFormatter{
// FieldMap: FieldMap{
2019-04-10 09:41:22 -04:00
// FieldKeyTime: "@timestamp",
2018-02-05 19:52:44 -05:00
// FieldKeyLevel: "@level",
2019-04-10 09:41:22 -04:00
// FieldKeyMsg: "@message",
// FieldKeyFunc: "@caller",
2018-02-05 19:52:44 -05:00
// },
// }
FieldMap FieldMap
2019-04-10 09:41:22 -04:00
2019-09-23 14:09:10 -04:00
// CallerPrettyfier can be set by the user to modify the content
// of the function and file keys in the json data when ReportCaller is
// activated. If any of the returned value is the empty string the
// corresponding key will be removed from json fields.
CallerPrettyfier func(*runtime.Frame) (function string, file string)
2019-04-10 09:41:22 -04:00
// PrettyPrint will indent all json logs
PrettyPrint bool
2018-02-05 19:52:44 -05:00
}
// Format renders a single log entry
2018-02-05 19:52:44 -05:00
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
2019-04-10 09:41:22 -04:00
data := make(Fields, len(entry.Data)+4)
2018-02-05 19:52:44 -05:00
for k, v := range entry.Data {
switch v := v.(type) {
case error:
// Otherwise errors are ignored by `encoding/json`
// https://github.com/sirupsen/logrus/issues/137
2018-02-05 19:52:44 -05:00
data[k] = v.Error()
default:
data[k] = v
}
}
2019-04-10 09:41:22 -04:00
if f.DataKey != "" {
newData := make(Fields, 4)
newData[f.DataKey] = data
data = newData
}
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
2018-02-05 19:52:44 -05:00
timestampFormat := f.TimestampFormat
if timestampFormat == "" {
timestampFormat = defaultTimestampFormat
2018-02-05 19:52:44 -05:00
}
2019-04-10 09:41:22 -04:00
if entry.err != "" {
data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
}
2018-02-05 19:52:44 -05:00
if !f.DisableTimestamp {
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
}
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
2019-04-10 09:41:22 -04:00
if entry.HasCaller() {
2019-09-23 14:09:10 -04:00
funcVal := entry.Caller.Function
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
if f.CallerPrettyfier != nil {
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
}
if funcVal != "" {
data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
}
if fileVal != "" {
data[f.FieldMap.resolve(FieldKeyFile)] = fileVal
}
2019-04-10 09:41:22 -04:00
}
var b *bytes.Buffer
if entry.Buffer != nil {
b = entry.Buffer
} else {
b = &bytes.Buffer{}
}
2018-02-05 19:52:44 -05:00
2019-04-10 09:41:22 -04:00
encoder := json.NewEncoder(b)
if f.PrettyPrint {
encoder.SetIndent("", " ")
}
if err := encoder.Encode(data); err != nil {
2019-09-23 14:09:10 -04:00
return nil, fmt.Errorf("failed to marshal fields to JSON, %v", err)
2018-02-05 19:52:44 -05:00
}
2019-04-10 09:41:22 -04:00
return b.Bytes(), nil
2018-02-05 19:52:44 -05:00
}