diff --git a/plugins/parsers/grok/parser.go b/plugins/parsers/grok/parser.go index bc65588eb..c1ebf9003 100644 --- a/plugins/parsers/grok/parser.go +++ b/plugins/parsers/grok/parser.go @@ -344,6 +344,9 @@ func (p *Parser) ParseLine(line string) (telegraf.Metric, error) { v = strings.Replace(v, ",", ".", -1) ts, err := time.ParseInLocation(t, v, p.loc) if err == nil { + if ts.Year() == 0 { + ts = ts.AddDate(timestamp.Year(), 0, 0) + } timestamp = ts } else { log.Printf("E! Error parsing %s to time layout [%s]: %s", v, t, err) @@ -485,6 +488,9 @@ type tsModder struct { // most significant time unit of ts. // ie, if the input is at ms precision, it will increment it 1µs. func (t *tsModder) tsMod(ts time.Time) time.Time { + if ts.IsZero() { + return ts + } defer func() { t.last = ts }() // don't mod the time if we don't need to if t.last.IsZero() || ts.IsZero() { @@ -498,7 +504,6 @@ func (t *tsModder) tsMod(ts time.Time) time.Time { t.rollover = 0 return ts } - if ts.Equal(t.last) { t.dupe = ts } diff --git a/plugins/parsers/grok/parser_test.go b/plugins/parsers/grok/parser_test.go index 8133d3021..60348fc63 100644 --- a/plugins/parsers/grok/parser_test.go +++ b/plugins/parsers/grok/parser_test.go @@ -1009,3 +1009,19 @@ func TestMeasurementModifierNoName(t *testing.T) { require.NoError(t, err) require.Equal(t, m.Name(), "hello") } + +func TestEmptyYearInTimestamp(t *testing.T) { + p := &Parser{ + Patterns: []string{`%{APPLE_SYSLOG_TIME_SHORT:timestamp:ts-"Jan 2 15:04:05"} %{HOSTNAME} %{APP_NAME:app_name}\[%{NUMBER:pid:int}\]%{GREEDYDATA:message}`}, + CustomPatterns: ` + APPLE_SYSLOG_TIME_SHORT %{MONTH} +%{MONTHDAY} %{TIME} + APP_NAME [a-zA-Z0-9\.]+ + `, + } + require.NoError(t, p.Compile()) + p.ParseLine("Nov 6 13:57:03 generic iTunes[6504]: info> Scale factor of main display = 2.0") + m, err := p.ParseLine("Nov 6 13:57:03 generic iTunes[6504]: objc[6504]: Object descriptor was null.") + require.NoError(t, err) + require.NotNil(t, m) + require.Equal(t, 2018, m.Time().Year()) +}