in formatter.go [64:140]
func (f *Formatter) Format(e *logrus.Entry) ([]byte, error) {
datahint := len(e.Data)
if f.DataKey != "" {
datahint = 2
}
data := make(logrus.Fields, datahint)
if len(e.Data) > 0 {
extraData := data
if f.DataKey != "" {
extraData = make(logrus.Fields, len(e.Data))
}
for k, v := range e.Data {
switch k {
case logrus.ErrorKey:
err, ok := v.(error)
if ok {
data["error"] = errorObject{
Message: err.Error(),
}
break
}
fallthrough // error has unexpected type
default:
extraData[k] = v
}
}
if f.DataKey != "" && len(extraData) > 0 {
data[f.DataKey] = extraData
}
}
if e.HasCaller() {
// Logrus has a single configurable field (logrus.FieldKeyFile)
// for storing a combined filename and line number, but we want
// to split them apart into two fields. Remove the event's Caller
// field, and encode the ECS fields explicitly.
var funcVal, fileVal string
var lineVal int
if f.CallerPrettyfier != nil {
var fileLineVal string
funcVal, fileLineVal = f.CallerPrettyfier(e.Caller)
if sep := strings.IndexRune(fileLineVal, ':'); sep != -1 {
fileVal = fileLineVal[:sep]
lineVal, _ = strconv.Atoi(fileLineVal[sep+1:])
} else {
fileVal = fileLineVal
lineVal = 0
}
} else {
funcVal = e.Caller.Function
fileVal = e.Caller.File
lineVal = e.Caller.Line
}
e.Caller = nil
if funcVal != "" {
data["log.origin.function"] = funcVal
}
if fileVal != "" {
data["log.origin.file.name"] = fileVal
}
if lineVal > 0 {
data["log.origin.file.line"] = lineVal
}
}
data["ecs.version"] = ecsVersion
ecopy := *e
ecopy.Data = data
e = &ecopy
jf := logrus.JSONFormatter{
TimestampFormat: "2006-01-02T15:04:05.000Z0700",
DisableHTMLEscape: f.DisableHTMLEscape,
FieldMap: ecsFieldMap,
CallerPrettyfier: f.CallerPrettyfier,
PrettyPrint: f.PrettyPrint,
}
return jf.Format(e)
}