Fix Event timestamps (#8216)

Closes #8204
This commit is contained in:
simnv 2020-10-19 21:24:46 +05:00 committed by GitHub
parent 87fcea5e9b
commit e3aa6eb577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 3 deletions

View File

@ -72,6 +72,10 @@ Telegraf minimum version: Telegraf 1.16.0
## Get only first line of Message field. For most events first line is usually more than enough
only_first_line_of_message = true
## Parse timestamp from TimeCreated.SystemTime event field.
## Will default to current time of telegraf processing on parsing error or if set to false
timestamp_from_event = true
## Fields to include as tags. Globbing supported ("Level*" for both "Level" and "LevelText")
event_tags = ["Source", "EventID", "Level", "LevelText", "Task", "TaskText", "Opcode", "OpcodeText", "Keywords", "Channel", "Computer"]
@ -79,7 +83,7 @@ Telegraf minimum version: Telegraf 1.16.0
event_fields = ["*"]
## Fields to exclude. Also applied to data fields. Globbing supported
exclude_fields = ["Binary", "Data_Address*"]
exclude_fields = ["TimeCreated", "Binary", "Data_Address*"]
## Skip those tags or fields if their value is empty or equals to zero. Globbing supported
exclude_empty = ["*ActivityID", "UserID"]
@ -154,6 +158,8 @@ Fields `Level`, `Opcode` and `Task` are converted to text and saved as computed
`Message` field is rendered from the event data, and can be several kilobytes of text with line breaks. For most events the first line of this text is more then enough, and additional info is more useful to be parsed as XML fields. So, for brevity, plugin takes only the first line. You can set `only_first_line_of_message` parameter to `false` to take full message text.
`TimeCreated` field is a string in RFC3339Nano format. By default Telegraf parses it as an event timestamp. If there is a field parse error or `timestamp_from_event` configration parameter is set to `false`, then event timestamp will be set to the exact time when Telegraf has parsed this event, so it will be rounded to the nearest minute.
### Additional Fields
The content of **Event Data** and **User Data** XML Nodes can be added as additional fields, and is added by default. You can disable that by setting `process_userdata` or `process_eventdata` parameters to `false`.

View File

@ -13,6 +13,7 @@ import (
"reflect"
"strings"
"syscall"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/inputs"
@ -80,6 +81,10 @@ var sampleConfig = `
## Get only first line of Message field. For most events first line is usually more than enough
only_first_line_of_message = true
## Parse timestamp from TimeCreated.SystemTime event field.
## Will default to current time of telegraf processing on parsing error or if set to false
timestamp_from_event = true
## Fields to include as tags. Globbing supported ("Level*" for both "Level" and "LevelText")
event_tags = ["Source", "EventID", "Level", "LevelText", "Task", "TaskText", "Opcode", "OpcodeText", "Keywords", "Channel", "Computer"]
@ -87,7 +92,7 @@ var sampleConfig = `
event_fields = ["*"]
## Fields to exclude. Also applied to data fields. Globbing supported
exclude_fields = ["Binary", "Data_Address*"]
exclude_fields = ["TimeCreated", "Binary", "Data_Address*"]
## Skip those tags or fields if their value is empty or equals to zero. Globbing supported
exclude_empty = ["*ActivityID", "UserID"]
@ -102,6 +107,7 @@ type WinEventLog struct {
ProcessEventData bool `toml:"process_eventdata"`
Separator string `toml:"separator"`
OnlyFirstLineOfMessage bool `toml:"only_first_line_of_message"`
TimeStampFromEvent bool `toml:"timestamp_from_event"`
EventTags []string `toml:"event_tags"`
EventFields []string `toml:"event_fields"`
ExcludeFields []string `toml:"exclude_fields"`
@ -157,6 +163,7 @@ loop:
tags := map[string]string{}
fields := map[string]interface{}{}
evt := reflect.ValueOf(&event).Elem()
timeStamp := time.Now()
// Walk through all fields of Event struct to process System tags or fields
for i := 0; i < evt.NumField(); i++ {
fieldName := evt.Type().Field(i).Name
@ -181,6 +188,12 @@ loop:
case "TimeCreated":
fieldValue = event.TimeCreated.SystemTime
fieldType = reflect.TypeOf(fieldValue).String()
if w.TimeStampFromEvent {
timeStamp, err = time.Parse(time.RFC3339Nano, fmt.Sprintf("%v", fieldValue))
if err != nil {
w.Log.Warnf("Error parsing timestamp %q: %v", fieldValue, err)
}
}
case "Correlation":
if should, _ := w.shouldProcessField("ActivityID"); should {
activityID := event.Correlation.ActivityID
@ -258,7 +271,7 @@ loop:
}
// Pass collected metrics
acc.AddFields("win_eventlog", fields, tags)
acc.AddFields("win_eventlog", fields, tags, timeStamp)
}
}
@ -510,6 +523,7 @@ func init() {
ProcessEventData: true,
Separator: "_",
OnlyFirstLineOfMessage: true,
TimeStampFromEvent: true,
EventTags: []string{"Source", "EventID", "Level", "LevelText", "Keywords", "Channel", "Computer"},
EventFields: []string{"*"},
ExcludeEmpty: []string{"Task", "Opcode", "*ActivityID", "UserID"},