10

I was checking the nginx error logs at our server and found that they start with date formatted as:

2015/08/30 05:55:20

i.e. YYYY/MM/DD HH:mm:ss. I was trying to find an existing grok date pattern which might help me in parsing this quickly but sadly could not find any such date format. Eventually, I had to write the pattern as:

%{YEAR}/%{MONTHNUM}/%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}? 

I am still hoping if there is a shorter pattern for the same ?

baudsp
  • 4,076
  • 1
  • 17
  • 35
Mandeep Singh
  • 7,674
  • 19
  • 62
  • 104
  • Does the pattern _actually_ have to contain `[T ]` and `%{ISO8601_TIMEZONE}?`? Looking at your single example they're unnecessary. Also, why make the seconds optional? – Magnus Bäck Sep 06 '15 at 19:59
  • Agree with you. These are not necessary. But is there any pattern available that can parse this date format as it is? – Mandeep Singh Sep 07 '15 at 08:56

4 Answers4

10

No. You find the included patterns on github. The comment to datestamp seems to fit to your YYYY/MM/DD, but DATE_US and DATE_EU are different.

I suggest overload the DATE pattern using grok option patterns_dir and go with DATESTAMP.

DATE_YMD %{YEAR}/%{MONTHNUM}/%{MONTHDAY}
DATE %{DATE_US}|%{DATE_EU}|%{DATE_YMD}

or just add your pattern into a patterns-file and use grok's patterns_dir option.

dtrv
  • 693
  • 1
  • 6
  • 14
  • But how would that matched pattern be parsed into a proper date type? I think the other answer should be merged here. – Vanuan Jul 27 '16 at 13:14
6

Successful timestamp capture strategy comprised of 3 things

  1. Precision and timezone in the original log. Change your nginx timestamp log format.

Use $msec to capture milliseconds. Otherwise you wouldn't be able to sort it precisely.

log_format custom '[$msec] [$remote_addr] [$remote_user] '
                  '"$request" $status '
                  '"$http_referer" "$http_user_agent"';
  1. Raw timestamp. Use greedy matching to capture raw data into a field.

Use GREEDYDATA:

grok {
  match => { "message" => "\[%{GREEDYDATA:raw_timestamp}\] %{GREEDYDATA:message}" }
  overwrite => [ "message" ]
}
  1. Parsed timestamp. Use date filter to parse raw timestamp.

reference

date {
  match => [ "timestamp", "yyyy/MM/dd HH:mm:ss.S z" ]
  target => "@timestamp"
}
Vanuan
  • 31,770
  • 10
  • 98
  • 102
6

To match 2015/08/30 05:55:20, use:

%{DATESTAMP:mytimestamp}

Tested on Logstash 6.5

Source: https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/grok-patterns

Thiago Falcao
  • 4,463
  • 39
  • 34
1

You can also simply include the joda.time pattern which is simple and short.

date {
  match => [ "timestamp", "yyyy/MM/dd HH:mm:ss" ]
  target => "@timestamp"
}

Helpful link for reference: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

m0nhawk
  • 22,980
  • 9
  • 45
  • 73
Philip
  • 503
  • 7
  • 8