Logstash change time format - elasticsearch

My log statement looks like this.
2014-04-23 06:40:29 INFO [1605853264] [ModuleName] - [ModuleName] -
Blah blah
I am able to parse it fine and it gets logged to ES correctly with following ES field
"LogTimestamp": "2014-04-23T13:40:29.000Z"
But my requirement is to log this statement as following, note 'z' is dropped with +0000. I tried replace, gsub but none changes the output.
"LogTimestamp": "2014-04-23T13:40:29.000+0000"
Can somebody help?
Here is my pattern
TEMP_TIMESTAMP %{YEAR}-%{MONTHNUM}-%{MONTHDAY}\s%{HOUR}:%{MINUTE}:%{SECOND} TEMP_LOG %{TEMP_TIMESTAMP:logdate}\s*?%{LOGLEVEL:TempLogLevel}\s*?\[\s?*%{BASE10NUM:TempThreadId}\]%{GREEDYDATA}
This is the filter config:
grok{
patterns_dir => ["patterns"]
match=> ["message", "%{TEMP_LOG}"]
}
date{
match => [ "logdate", "yyyy-MM-dd HH:mm:ss" ]
target => "LogTimestamp"
timezone => "PST8PDT"
}
mutate {
gsub => ["logdate", ".000Z", ".000+0000"]
}
I haven't quite understood meaning of fields in logstash and how they map to elastic search, that confusion is making me go wrong in this case.

You can use ruby plugin to do what you want!
As your requirement, you want to change this
"LogTimestamp": "2014-04-23T13:40:29.000Z"
to
"LogTimestamp": "2014-04-23T13:40:29.000+0000"
Try to use this filter
filter {
ruby {
code => "
event['LogTimestamp'] = event['LogTimestamp'].localtime('+00:00')
"
}
}
Hope this can help you.

Related

"tags":["_dateparsefailure"]," with logstash

12-Apr-2021 17:12:45.289 FINE [https-jsse-nio2-8443-exec-5] org.apache.catalina.authenticator.FormAuthenticator.doAuthenticate Authentication of 'user1' was successful
I am parsing above log message with the below code in logstash and unfortunately getting a "tags":["_dateparsefailure"], .
%{MY_DATE_PATTERN:timestamp} is an custom pattern as follows MY_DATE_PATTERN %{MONTHDAY}-%{MONTH}-%{YEAR} %{HOUR}:?%{MINUTE}(?::?%{SECOND})
I also have checked with https://grokdebug.herokuapp.com/ that it parses perfectly fine.
I was wondering that you may be able to see where i am doing wrong.
filter {
grok{
patterns_dir => "/etc/logstash/patterns"
match => { "message" => "%{MY_DATE_PATTERN:timestamp}\s+%{WORD:severity}\s+\[%{DATA:thread}\]\s+%{NOTSPACE:type_log}\s+(?<action>\w(?:[\w\s]*\w)?)(?:\s+['\[](?<user>[^\]']+))?" }
}
# Converting timestamp
date {
locale => "nl"
match => ["timestamp", "dd-MM-YYYY HH:mm:ss"]
timezone => "Europe/Amsterdam"
target => "timestampconverted"
}
ruby {
code => "event.set('timestamp', (event.get('timestampconverted').to_f*1000).to_i)"
}
The output ( had to remove couple things so that i could post here)
user":"user1,"type_log":"org.apache.catalina.authenticator.FormAuthenticator.doAuthenticate","logSource":{"environment,"tags":["_dateparsefailure"],"thread":"https-jsse-nio2-8443-exec-6","action":"Authentication of
thanks in advance!
Update
I also tried below and still getting the error
date {
locale => "nl"
match => ["timestamp", "dd-MMM-YYYY HH:mm:ss.SSS"]
timezone => "Europe/Amsterdam"
target => "timestampconverted"
}
It should definitely be "dd-MMM-YYYY HH:mm:ss.SSS" -- you have to consume the entire field. Can you try removing the 'locale => "nl"' option (just for debugging purposes). We are currently in a month where the Dutch and English month abbreviations match. If it starts working then the month abbreviations are not what you think they are. Some locales expect to have a . at the end of the abbreviation. Looking at the CLDR charts it definitely appears that locale nl is one of them, so you will have to gsub it in. The CLDR data is here, scroll down to "Months - Abbreviated - Formatting". You could try
mutate { gsub => [ "timestamp", "(jan|feb|mrt|apr|jun|jul|aug|sep|okt|nov|dec)", "\1." ] }
My original suggestion of
mutate { gsub => [ "timestamp", "(jan|feb|apr|aug|sept|oct|okt|nov|dec)", "\1." ] }
was based on the abbreviations given here but that is not what Java uses.
The issue is definitely in the date filter, not the grok. If the grok filter were not parsing the timestamp field then the date filter would be a no-op and would not add the tag.
I figured out that custom pattern was causing issue, instead of using it from another location i added to my conf file as regex as following (?<logstamp>%{MONTHDAY}-%{MONTH}-%{YEAR} %{HOUR}:%{MINUTE}:%{SECOND})

Modify the content of a field using logstash

I am using logstash to get data from a sql database. There is a field called "code" in which the content has
this structure:
PO0000001209
ST0000000909
And what I would like to do is to remove the 6 zeros after the letters to get the following result:
PO1209
ST0909
I will put the result in another field called "code_short" and use it for my query in elasticsearch. I have configured the input
and the output in logstash but I am not sure how to do it using grok or maybe mutate filter
I have read some examples but I am quite new on this and I am a bit stuck.
Any help would be appreciated. Thanks.
You could use a mutate/gsub filter for this but that will replace the value of the code field:
filter {
mutate {
gsub => [
"code", "000000", "",
]
}
}
Another option is to use a grok filter like this:
filter {
grok {
match => { "code" => "(?<prefix>[a-zA-Z]+)000000%{INT:suffix}" }
add_field => { "code_short" => "%{prefix}%{suffix}"}
}
}

Sort logs based on timestamp in original logs using elasticsearch

I am using logstash+elasticsearch to index server logs. The logs if of this format:
17/03/15-06:29:30 31609 453749 545959 1 4 http://www.somesite.com/index.html - 0
Here is my logstash config file:
filter {
grok {
match => { "message" => "%{DATESTAMP:timestamp} %{NUMBER:some_id} %{NUMBER:some_id} %{NUMBER:some_id} %{NUMBER:some_id} %{NUMBER:some_id} %{DATA:url} %{GREEDYDATA:log_message}" }
}
date {
match => ["timestamp", "dd/MM/YY-HH:mm:ss"]
#remove_field => ["timestamp"]
}
mutate {
remove => [ "message" ]
}
}
I want to sort logs using the timestamp string of the logs. I have tried with and without using the 'date' filter. But unfortunately I am not able to query the timestamp field, sort or do a range query.
What should I do to make timestamp field sortable and queryable?
Is there a way to do this? Can anyone please help me with this situation? please comment if I am not clear with my question.
Thanks in advance.
See the below image of logs are loaded on the sorting base...

How to handle non-matching Logstash grok filters

I am wondering what the best approach to take with my Logstash Grok filters. I have some filters that are for specific log entries, and won't apply to all entries. The ones that don't apply always generate _grokparsefailure tags. For example, I have one grok filter that's for every log entry and it works fine. Then I have another filter that's for error messages with tracebacks. The traceback filter throws a grokparsefailure for every single log entry that doesn't have a traceback.
I'd prefer to have it just pass the rule if there isn't a match instead of adding the parsefailure tag. I use the parsefailure tag to find things that aren't parsing properly, not things that simply didn't match a particular filter. Maybe it's just the nomenclature "parse failure" that gets me. To me that means there's something wrong with the filter (e.g. badly formatted), not that it didn't match.
So the question is, how should I handle this?
Make the filter pattern optional using ?
(ab)use the tag_on_failure option by setting it to nothing []
make the filter conditional using something like "if traceback in message"
something else I'm not considering?
Thanks in advance.
EDIT
I took the path of adding a conditional around the filter:
if [message] =~ /took\s\d+/ {
grok {
patterns_dir => "/etc/logstash/patterns"
match => ["message", "took\s+(?<servicetime>[\d\.]+)"]
add_tag => [ "stats", "servicetime" ]
}
}
Still interested in feedback though. What is considered "best practice" here?
When possible, I'd go with a conditional wrapper just like the one you're using. Feel free to post that as an answer!
If your application produces only a few different line formats, you can use multiple match patterns with the grok filter. By default, the filter will process up to the first successful match:
grok {
patterns_dir => "./patterns"
match => {
"message" => [
"%{BASE_PATTERN} %{EXTRA_PATTERN}",
"%{BASE_PATTERN}",
"%{SOME_OTHER_PATTERN}"
]
}
}
If your logic is less straightforward (maybe you need to check the same condition more than once), the grep filter can be useful to add a tag. Something like this:
grep {
drop => false #grep normally drops non-matching events
match => ["message", "/took\s\d+/"]
add_tag => "has_traceback"
}
...
if "has_traceback" in [tags] {
...
}
You can also add tag_on_failure => [] to your grok stanza like so:
grok {
match => ["context", "\"tags\":\[%{DATA:apptags}\]"]
tag_on_failure => [ ]
}
grok will still fail, but will do so without adding to the tags array.
This is the most efficient way of doing this. Ignore the filter
filter {
grok {
match => [ "message", "something"]
}
if "_grokparsefailure" in [tags] {
drop { }
}
}
You can also do this
remove_tag => [ "_grokparsefailure" ]
whenever you have a match.

Tagging the Logs by Logstash - Grok - ElasticSearch

Summary:
I am using Logstash - Grok and elastic search and my main aim is to First accept the logs by logstash, parse them by grok and associate tags with the messages depending on the type of the log, and then finally feed it to the Elastic server to query with Kibana.
I have already written this code but am not able to get the tags in Elastic Search.
This is my logstash confif file.
input {
stdin {
type => "stdin-type"
}
}
filter {
grok {
tags => "mytags"
pattern => "I am a %{USERNAME}"
add_tag => "mytag"
named_captures_only => true
}
}
output {
stdout { debug => true debug_format => "json"}
elasticsearch {}
}
Where am I going wrong?
1) I would first start with editing your values to match the data type they represent. For example
add_tag => "mytag"
actually should have an array as it's value, not a simple string. Change that to
add_tag => ["mytag"]
as a good start. Double check all your values and verify they are of the correct type for logstash.
2) You are limiting your grok filters to messages that are already tagged with "mytags" based on the config line
tags => "mytags"
I don't see anywhere where you have added that tag ahead of time. Therefore, none of your messages will even go through your grok filter.
3) Please read the logstash docs carefully. I am rather new to the Logstash/Grok/ES/Kibana etc. world as well, but I have had very similar problems to what you have had, and all of them were solved by paying attention to what the documentation says.
You can run LogStash by hand (You may already be doing this) with /opt/logstash/bin/logstash -f $CONFIG_FILE and can check that your config file is valid with /opt/logstash/bin/logstash -f $CONFIG_FILE --configtest I bet you're already doing that though.
You may need to put your add_tag stanza into an array
grok {
...
add_tag => [ "mytag" ]
}
It could also be that what you're piping into STDIN isn't being matched in the grok pattern. If grok doesn't match is should result in _grokparsefailure being added to your tags. If you see those, it means your grok pattern isn't firing.
A better way to do this may be...
input {
stdin {
type => 'stdin'
}
}
filter {
if [type] = 'stdin' {
mutate {
add_tag => [ "mytag" ]
}
}
}
output {
stdout {
codec => 'rubydebug'
}
}
This will add a "mytag" tag to all things coming from standard in, wether they're groked or not.

Resources