How can you parse 2 properties out of 1 value with grok in logstash? - logstash

Some context:
I want to parse the following log statement using grok in logstash
07:51:45,729 TRACE [com.company.Class] (ajp-/1.2.3.4:8080-251) USERID called path: /url and took: 1000 ms
I am now using the following syntax to parse the complete message:
%{DATA:time}\s%{DATA:level}\s%{DATA:class}\s%{DATA:thread}\s%{DATA:userid}\s.*path:\s%{DATA:url}\s.*:\s%{NUMBER:duration:int}\sms
Which gives me all the properties that i have defined.
My question:
I want to parse this part (ajp-/1.2.3.4:8080-251) into a 'thread' property and an ip property.
The result needs to be:
thread: (ajp-/1.2.3.4:8080-251)
ip: 1.2.3.4
How can i do this?
Thanks

Just add a second grok filter after your working one. Do not put this in your existing grok filter because it will finish after the first match.
Example:
grok {
match => [ 'thread', '%{IP:ip}' ]
}
This obtains your previous field thread => "(ajp-/1.2.3.4:8080-251)" and adds a new field ip => "1.2.3.4"
Apart from that, I would recommend you to be more specific with your pattern. You used DATA everytime which is kind of imprecise. Start with something like this:
%{TIME:timestamp} %{WORD:method} \[%{JAVACLASS:class}\] \(%{DATA:thread}\) %{NUMBER:userid} %{DATA}%{URIPATH:uri}%{DATA}

Related

Regex group from within custom grok pattern

I'm trying to create custom grok patterns to extract various data using logstash and am wracking my brain getting the syntax correct to pull the regex group 1 equivalent from my log rows. I've looked at a ton of threads on this over the past 2 days, but nothing's out there that fits my example, and none of the canned grok patterns seem like they will pull the value I need.
3 example log file rows look similar to this (with abbreviated data for the examples):
2022-04-07 12:52:06,184:INFO :Thread-70_SCHEDULE.0001: MsgID=63759111848731967
2022-04-07 07:23:39,876:INFO :Thread-53_OrderInterfaceIntServer: MsgID=21316889724753182|
07:23:40,482 INFO [stdout] (http-/0.0.0.0:8080-20) 2022-04-07 07:23:40,482:ERROR
I want to create a custom grok pattern called SERVICE that extracts a pattern match using a regex match string:
Thread-[0-9]{2}_(.*?)\:
that for the 3 rows would return:
SCHEDULE.0001
OrderInterfaceIntServer
""
In the log:
SERVICE will always be prefixed by "Thread-xx_" where xx = 2-digit number followed by underscore. Some logs may not have this pattern at all (like row 3). In that case, no match.
SERVICE is always followed by a colon
In grok, I can define this in 2 ways:
SERVICE Thread-[0-9]{2}_(.*?)\:
or as a field using (?<service>Thread-[0-9]{2}_(.*?)\:)
however, for row 1, I get the response value of:
{
"service": [
[
"Thread-70_SCHEDULE.0001:"
]
]
}
What I want is:
{
"service": [
[
"SCHEDULE.0001"
]
]
}
Which is the equivalent of the regex group 1 response. I can't figure out how to manage the grok patterns to get the result I need.
You do not have to include all of the pattern in the capture group. You can use
grok { match => { "message" => "Thread-[0-9]{2}_(?<service>.*?):" } }
That will result in
"service" => "SCHEDULE.0001",
"service" => "OrderInterfaceIntServer",
and a "_grokparsefailure" tag on the third event.

Getting parsing error while writting custom grok filter

I am new to regex and using logstack grok filter. I have to write my own regex to filter this message
NAID-iOS-3093448A-BC34-4FE1-A057-29AD2CEF8FD3-1471410782.565937 IP-202.174.93.103 2016-08-17 00:13:09,963
my grok filter is
grok{
match => {"message" => "%{DATA:deviceid}%{IP:Serverip}%{%{YEAR}[-]%{MONTHNUM}[-]%{MONTHDAY}:Date}%{GREEDYDATA:data}"}
}
the default DATE_EU entry in grok has %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
but i needed a reverse of it so I wrote
%{%{YEAR}[./-]%{MONTHNUM}[./-]%{MONTHDAY}:Date} instead of %{DATE_EU:Date} but getting [0]_grok parsefailure message in my syntax.
I even followed https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html#_custom_patterns and created a patterns directory inside logstash folder I am using windows and added DATE_LOG %{YEAR}[./-]%{MONTHNUM}[./-]%{MONTHDAY} entry inside file named "extra" but again got parsing_error.
You're using bad syntax. While parsing a log line you name each part with your own variables, for example:
%{MONTHNUM:month}-%{MONTHDAY:day}
and then you complete your own format this way:
replace => ['timestamp', '%{month}-%{day}']

How to pull specific data out of a message in LogStash

I am trying to take log data from a custom application that has a well defined format. I am trying to pick out certain pieces of the data using the grok filter, but I am not having any luck. Here is a sample log:
- System.Data.SqlClient.SqlException (0x80131904): Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
What I would like to do is extract out the SqlException out of the string. Here is the grok that I am using:
grok{
match =>
{
"message" =>
[
"(?m)%{DATE:TIMESTAMP_DATE}%{SPACE}%{TIME:TIMESTAMP_TIME}%{SPACE}%{WORD:LOG_LEVEL}%{SPACE}(?<THREAD>[^\s]+)%{SPACE}(?<HOST>[^\s]+)%{SPACE}%{GREEDYDATA:MESSAGE}",
"(?<EXCEPTION>[.*]+)"
]
}
}
I have tried several different ways, but I guess I am not completely understanding the documentation. What I would expect to happen is all of the fields that I have extracts in the first set would include the result of the second set. In other words:
TIMESTAMP_DATE,TIMESTAMP_TIME,LOG_LEVEL,THREAD,HOST,MESSAGE,EXCEPTION
I am getting the other fields perfectly, it is just additional matching that I am missing. Any help would be appreciated. Thanks
If you specify multiple patterns grok by default only looks checks the patterns until the first match is encountered. If you want to match against both patterns regardless of whether the first one matched or not you can change the behaviour like that:
grok{
break_on_match => false
match =>
{
"message" =>
[
"(?m)%{DATE:TIMESTAMP_DATE}%{SPACE}%{TIME:TIMESTAMP_TIME}%{SPACE}%{WORD:LOG_LEVEL}%{SPACE}(?<THREAD>[^\s]+)%{SPACE}(?<HOST>[^\s]+)%{SPACE}%{GREEDYDATA:MESSAGE}",
"(?<EXCEPTION>[.*]+)"
]
}
}
Check out the docs under: https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html#plugins-filters-grok-break_on_match

How to define grok pattern for pipe delimited log message?

setting up ELK is very easy until you hit the logstash filter. I have a log delimited 10 fields. I may have some field blank but I am sure there will be 10 fields:
7/5/2015 10:10:18 AM|KDCVISH01|
|ClassNameUnavailable:MethodNameUnavailable|CustomerView|xwz261|ef315792-5c41-4bdf-aa66-73317e82e4d6|52|6182d1a1-7916-4874-995b-bc9a23437dab|<Exception>
afkh akla 487234 &*<Exception>
Q:
1- I am confused how grok or regex pattern will pick only the field that I am looking and not the similar match from another field. For example, what is the guarantee that DATESTAMP pattern picks only the first value and not the timestamp present in the last field (buried in stack trace)?
2- Is there a way to define positional mapping? For example, 1st fiels is dateTime, 2nd is machine name, 3rd is class name and so on. This will make sure I have fields displayed in Kibana no matter the field value is present or not.
I know i am little late, But here is a simple solution which i am using,
replace your | with space
option 1:
filter {
mutate {
gsub => ["message","\|"," "]
}
grok {
match => ["message","%{DATESTAMP:time} %{WORD:MESSAGE1} %{WORD:EXCEPTION} %{WORD:MESSAGE2}"]
}
}
option 2: excepting |
filter {
grok {
match => ["message","%{DATESTAMP:time}\|%{WORD:MESSAGE1}\|%{WORD:EXCEPTION}\|%{WORD:MESSAGE2}"]
}
}
it is working fine : http://grokdebug.herokuapp.com/. check here.

Different structure in a few lines in my log file

My log file contains different structures in a few lines, and I can not grok it, I don't know if we can test by lines or attribute, I'm still a beginner.
if you don't understand me I can give you some examples :
input :
id=firewall action=bloc type=web
id=firewall fw="ER" type=filter
id=firewall fw="Az" tz="loo" action=bloc
Pattern:
id=%{WORD:id} ...
I thought to add some patterns between ()?,
but i don't know exactly how to do it.
you can use this site to test it http://grokdebug.herokuapp.com/
Any help please? What should i do :(
Logstash supports key-value Values, take a look at http://logstash.net/docs/1.4.2/filters/kv.
Or you could use multiple match values:
grok {
patterns_dir => "./patterns"
match => [
"message", "%{BASE_PATTERN} %{EXTRA_PATTERN}",
"message", "%{BASE_PATTERN}",
"message", "%{SOME_OTHER_PATTERN}"
]
}
Not sure if I understood well your question but I will try to answer. I think the first thing you have to do is to parse the different fields from your input. Example of pattern to parse your first line input :
PATTERN %{NOTSPACE} %{NOTSPACE} %{NOTSPACE} (in $LOGSTASH_HOME/pattern/extra)
Then in your logstash configuration file :
filter {
grok {
patterns_dir => "$LOGSTASH_HOME/pattern"
match => [ "message" => "%{PATTERN}" ]
}
}
This will match your first line as 3 fields ("id=firewall" "action=bloc" "type=web") (you have to adapt it if you have more than 3 fields).
And the last thing you seem be looking for is splitting field (in key-value scheme) like id=firewall would become id => "firewall". This can be done with the kv plugin. I never used it but I recommend you the logstash docs here
If I did not understand you question, please be more clear.

Resources