in auditbeat/module/auditd/audit_linux.go [546:692]
func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event {
auditEvent, err := aucoalesce.CoalesceMessages(msgs)
if err != nil {
// Add messages on error so that it's possible to debug the problem.
out := mb.Event{RootFields: mapstr.M{}, Error: err}
addEventOriginal(msgs, out.RootFields)
return out
}
if config.ResolveIDs {
aucoalesce.ResolveIDs(auditEvent)
}
eventOutcome := auditEvent.Result
if eventOutcome == "fail" {
eventOutcome = "failure"
}
out := mb.Event{
Timestamp: auditEvent.Timestamp,
RootFields: mapstr.M{
"event": mapstr.M{
"category": auditEvent.Category.String(),
"action": auditEvent.Summary.Action,
"outcome": eventOutcome,
},
},
ModuleFields: mapstr.M{
"message_type": strings.ToLower(auditEvent.Type.String()),
"sequence": auditEvent.Sequence,
"result": auditEvent.Result,
"data": createAuditdData(auditEvent.Data),
},
}
if auditEvent.Session != uidUnset {
_, _ = out.ModuleFields.Put("session", auditEvent.Session)
}
// Add root level fields.
addUser(auditEvent.User, out.RootFields)
addProcess(auditEvent.Process, out.RootFields)
addFile(auditEvent.File, out.RootFields)
addAddress(auditEvent.Source, "source", out.RootFields)
addAddress(auditEvent.Dest, "destination", out.RootFields)
addNetwork(auditEvent.Net, out.RootFields)
if len(auditEvent.Tags) > 0 {
_, _ = out.RootFields.Put("tags", auditEvent.Tags)
}
if config.Warnings && len(auditEvent.Warnings) > 0 {
warnings := make([]string, 0, len(auditEvent.Warnings))
for _, err := range auditEvent.Warnings {
warnings = append(warnings, err.Error())
}
_, _ = out.RootFields.Put("error.message", warnings)
addEventOriginal(msgs, out.RootFields)
}
if config.RawMessage {
addEventOriginal(msgs, out.RootFields)
}
// Add module fields.
m := out.ModuleFields
if auditEvent.Summary.Actor.Primary != "" {
_, _ = m.Put("summary.actor.primary", auditEvent.Summary.Actor.Primary)
}
if auditEvent.Summary.Actor.Secondary != "" {
_, _ = m.Put("summary.actor.secondary", auditEvent.Summary.Actor.Secondary)
}
if auditEvent.Summary.Object.Primary != "" {
_, _ = m.Put("summary.object.primary", auditEvent.Summary.Object.Primary)
}
if auditEvent.Summary.Object.Secondary != "" {
_, _ = m.Put("summary.object.secondary", auditEvent.Summary.Object.Secondary)
}
if auditEvent.Summary.Object.Type != "" {
_, _ = m.Put("summary.object.type", auditEvent.Summary.Object.Type)
}
if auditEvent.Summary.How != "" {
_, _ = m.Put("summary.how", auditEvent.Summary.How)
}
if len(auditEvent.Paths) > 0 {
_, _ = m.Put("paths", auditEvent.Paths)
}
normalizeEventFields(auditEvent, out.RootFields)
// User set for related.user
var userSet common.StringSet
if config.ResolveIDs {
userSet = make(common.StringSet)
}
// Copy user.*/group.* fields from event
setECSEntity := func(key string, ent aucoalesce.ECSEntityData, root mapstr.M, set common.StringSet) {
if ent.ID == "" && ent.Name == "" {
return
}
if ent.ID == uidUnset {
ent.ID = ""
}
nameField := key + ".name"
idField := key + ".id"
if ent.ID != "" {
_, _ = root.Put(idField, ent.ID)
} else {
_ = root.Delete(idField)
}
if ent.Name != "" {
_, _ = root.Put(nameField, ent.Name)
if set != nil {
set.Add(ent.Name)
}
} else {
_ = root.Delete(nameField)
}
}
setECSEntity("user", auditEvent.ECS.User.ECSEntityData, out.RootFields, userSet)
setECSEntity("user.effective", auditEvent.ECS.User.Effective, out.RootFields, userSet)
setECSEntity("user.target", auditEvent.ECS.User.Target, out.RootFields, userSet)
setECSEntity("user.changes", auditEvent.ECS.User.Changes, out.RootFields, userSet)
setECSEntity("group", auditEvent.ECS.Group, out.RootFields, nil)
if userSet != nil {
if userSet.Count() != 0 {
_, _ = out.RootFields.Put("related.user", userSet.ToSlice())
}
}
getStringField := func(key string, m mapstr.M) (str string) {
if asIf, _ := m.GetValue(key); asIf != nil {
str, _ = asIf.(string)
}
return str
}
// Remove redundant user.effective.* when it's the same as user.*
removeRedundantEntity := func(target, original string, m mapstr.M) bool {
for _, suffix := range []string{".id", ".name"} {
if value := getStringField(original+suffix, m); value != "" && getStringField(target+suffix, m) == value {
_ = m.Delete(target)
return true
}
}
return false
}
removeRedundantEntity("user.effective", "user", out.RootFields)
return out
}