Logstash can not handle multiple heterogeneous inputs - regex

Let's say you have 2 very different types of logs such as FORTINET and NetASQ logs and you want:
grok FORTINET using a regex, ang grok NETASQ using an other regex.
I know that with "type"in the input file and "condition" in the filter we can resolve this problem.
So I used this confing file to do it :
input {
file {
type => "FORTINET"
path => "/fortinet/*.log"
sincedb_path=>"/logstash-autre_version/var/.sincedb"
start_position => 'beginning'
}
file {
type => "NETASQ"
path => "/home/netasq/*.log"
}
}
filter {
if [type] == "FORTINET" {
grok {
patterns_dir => "/logstash-autre_version/patterns"
match => [
"message" , "%{FORTINET}"
]
tag_on_failure => [ "failure_grok_exemple" ]
break_on_match => false
}
}
if [type] == "NETASQ" {
# .......
}
}
output {
elasticsearch {
cluster => "logstash"
}
}
And i'm getting this error :
Got error to send bulk of actions: no method 'type' for arguments(org.jruby.RubyArray) on Java::OrgElasticsearchActionIndex::IndexRequest {:level=>:error}
But if don't use "type" and i grok only FORTINET logs it wroks.
What should i do ?

I'm not sure about this but maybe it helps:
I have the same error and I think that it is caused by the use of these if statements:
if [type] == "FORTINET"
your type field is compared to "FORTINET" but this is maybe not possible because "FORTINET" is a string and type isn't. Some times by setting a type to an input, if there is already a type, the type isn't replaced, but the new type is added to a list with the old type. You should have a look to your data in kibana (or wherever) and try to find something like this:
\"type\":[\"FORTINET\",\"some-other-type\"]
maybe also without all those \" .
If you find something like this try not to set the type of your input explicitly and compare the type in your if-statement to the some-other-type you have found.
Hope this works (I'm working with more complex inputs/forwarders and for me it doesn't, but it is worth a try)

Related

Proper way to create index template that is applied to all in ElasticSearch

I'm still new to the ElasticSearch technology and right now struggle with creating index template that will be applied to all new indices but can't create proper one.
Currently running ElasticSearch 7.9.2 and it's documentation index templates informs that index_patterns field is required and should be array of wildcards (* matches any string).
Naturally I have tried using ["*"] as pattern via Kibana's console for request:
PUT _index_template/template_1
{
"index_patterns": ["*"],
"priority": 0
}
I've got:
{
"error" : {
"root_cause" : [
{
"type" : "null_pointer_exception",
"reason" : null
}
],
"type" : "null_pointer_exception",
"reason" : null
},
"status" : 500
}
while for request that added empty settings:
PUT _index_template/template_1
{
"index_patterns": ["*"],
"template": {
"settings": {
}
},
"priority": 0
}
I've received:
#! Deprecation: index template [template_1] has index patterns [*] matching patterns from existing older templates [.monitoring-es,.triggered_watches,.management-beats,.transform-internal-005,.logstash-management,.monitoring-kibana,.kibana-event-log-7.9.2-template,.ml-config,.watch-history-11,.ml-meta,ilm-history,.monitoring-logstash,.ml-state,.slm-history,.ml-inference-000002,.monitoring-beats,.monitoring-alerts-7,.ml-anomalies-,.watches,.ml-notifications-000001,.transform-notifications-000002,.ml-stats] with patterns (.monitoring-es => [.monitoring-es-7-*],.triggered_watches => [.triggered_watches*],.management-beats => [.management-beats],.transform-internal-005 => [.transform-internal-005],.logstash-management => [.logstash],.monitoring-kibana => [.monitoring-kibana-7-*],.kibana-event-log-7.9.2-template => [.kibana-event-log-7.9.2-*],.ml-config => [.ml-config],.watch-history-11 => [.watcher-history-11*],.ml-meta => [.ml-meta],ilm-history => [ilm-history-2*],.monitoring-logstash => [.monitoring-logstash-7-*],.ml-state => [.ml-state*],.slm-history => [.slm-history-2*],.ml-inference-000002 => [.ml-inference-000002],.monitoring-beats => [.monitoring-beats-7-*],.monitoring-alerts-7 => [.monitoring-alerts-7],.ml-anomalies- => [.ml-anomalies-*],.watches => [.watches*],.ml-notifications-000001 => [.ml-notifications-000001],.transform-notifications-000002 => [.transform-notifications-*],.ml-stats => [.ml-stats-*]); this template [template_1] will take precedence during new index creation
{
"acknowledged" : true
}
Response depends only on existence of empty template.settings it seems like it might be slightly bugged.
Nevertheless latter approach seems to work however deprecation warning sounds dangerous and discouraging (I've tried setting priority to 0 but to no avail). However Documentation of 6.8 version sports example of "*". So such functionality existed not long ago.
What is the proper way, if there is one, to construct "match all" index template?
Currently to match all indices you really need to use the * as the index pattern and the warning is there because it will match anything, including the internal systems indices.
Depending on what is in your template this can lead to things not working right or break your system.
There is an open issue on github about it, mostly regarding to the .security index, which is also affected when you use an match all index pattern, and there is another open issue that also deals with this problem.

Parsing out PowerShell CommandLine Data from EventLog

Sending Windows Event Logs with WinLogBeat to Logstash - primarily focused on PowerShell events within the logs.
Example:
<'Data'>NewCommandState=Stopped SequenceNumber=1463 HostName=ConsoleHost HostVersion=5.1.14409.1005 HostId=b99970c6-0f5f-4c76-9fb0-d5f7a8427a2a HostApplication=C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe EngineVersion=5.1.14409.1005 RunspaceId=bd4224a9-ce42-43e3-b8bb-53a302c342c9 PipelineId=167 CommandName=Import-Module CommandType=Cmdlet ScriptName= CommandPath= CommandLine=Import-Module -Verbose.\nishang.psm1<'/Data'>
How can I extract the CommandLine= field using grok to get the following?
Import-Module -Verbose.\nishang.psm1
Grok is a wrapper around regular expressions. If you can parse data with a regex, you can implement it with grok.
Even though your scope is specific to the CommandLine field, parsing each of the fields in most key=value logs is pretty straightforward, and a single regex can be used for every field with some grok filters. If you intend to store, query, and visualize logs - the more data, the better.
Regular Expression:
First we start with the following:
(.*?(?=\s\w+=|\<|$))
.*? - Matches any character except for line terminators
(?=\s\w+=|\<|$)) - Positive lookahead that asserts the pattern must match the following
\s\w+= - Any word characters with a space prior to it, followed by a =
|\<|$ - Alternatively may match < or the end of the line so as not to include them in the matching group.
This means that each field can be parsed similar to the following:
CommandLine=(.*?(?=\s\w+=|\<|$))
Grok:
Now this means we can begin creating grok filters. The power of it is that reusable components may have semantic language applied to them.
/etc/logstash/patterns/powershell.grok:
# Patterns
PS_KEYVALUE (.*?(?=\s\w+=|\<|$))
# Fields
PS_NEWCOMMANDSTATE NewCommandState=%{PS_KEYVALUE:NewCommandState}
PS_SEQUENCENUMBER SequenceNumber=%{PS_KEYVALUE:SequenceNumber}
PS_HOSTNAME HostName=%{PS_KEYVALUE:HostName}
PS_HOSTVERSION HostVersion=%{PS_KEYVALUE:HostVersion}
PS_HOSTID HostId=%{PS_KEYVALUE:HostId}
PS_HOSTAPPLICATION HostApplication=%{PS_KEYVALUE:HostApplication}
PS_ENGINEVERSION EngineVersion=%{PS_KEYVALUE:EngineVersion}
PS_RUNSPACEID RunspaceId=%{PS_KEYVALUE:RunspaceId}
PS_PIPELINEID PipelineId=%{PS_KEYVALUE:PipelineId}
PS_COMMANDNAME CommandName=%{PS_KEYVALUE:CommandName}
PS_COMMANDTYPE CommandType=%{PS_KEYVALUE:CommandType}
PS_SCRIPTNAME ScriptName=%{PS_KEYVALUE:ScriptName}
PS_COMMANDPATH CommandPath=%{PS_KEYVALUE:CommandPath}
PS_COMMANDLINE CommandLine=%{PS_KEYVALUE:CommandLine}
Where %{PATTERN:label} will utilize the PS_KEYVALUE regular expression, and the matching group will be labeled with that value in JSON. This is where you can get flexible in naming fields you know.
/etc/logstash/conf.d/powershell.conf:
input {
...
}
filter {
grok {
patterns_dir => "/etc/logstash/patterns"
break_on_match => false
match => [
"message", "%{PS_NEWCOMMANDSTATE}",
"message", "%{PS_SEQUENCENUMBER}",
"message", "%{PS_HOSTNAME}",
"message", "%{PS_HOSTVERSION}",
"message", "%{PS_HOSTID}",
"message", "%{PS_HOSTAPPLICATION}",
"message", "%{PS_ENGINEVERSION}",
"message", "%{PS_RUNSPACEID}",
"message", "%{PS_PIPELINEID}",
"message", "%{PS_COMMANDNAME}",
"message", "%{PS_COMMANDTYPE}",
"message", "%{PS_SCRIPTNAME}",
"message", "%{PS_COMMANDPATH}",
"message", "%{PS_COMMANDLINE}"
]
}
}
output {
stdout { codec => "rubydebug" }
}
Result:
{
"HostApplication" => "C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe",
"EngineVersion" => "5.1.14409.1005",
"RunspaceId" => "bd4224a9-ce42-43e3-b8bb-53a302c342c9",
"message" => "<'Data'>NewCommandState=Stopped SequenceNumber=1463 HostName=ConsoleHost HostVersion=5.1.14409.1005 HostId=b99970c6-0f5f-4c76-9fb0-d5f7a8427a2a HostApplication=C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe EngineVersion=5.1.14409.1005 RunspaceId=bd4224a9-ce42-43e3-b8bb-53a302c342c9 PipelineId=167 CommandName=Import-Module CommandType=Cmdlet ScriptName= CommandPath= CommandLine=Import-Module -Verbose.\\nishang.psm1<'/Data'>",
"HostId" => "b99970c6-0f5f-4c76-9fb0-d5f7a8427a2a",
"HostVersion" => "5.1.14409.1005",
"CommandLine" => "Import-Module -Verbose.\\nishang.psm1",
"#timestamp" => 2017-05-12T23:49:24.130Z,
"port" => 65134,
"CommandType" => "Cmdlet",
"#version" => "1",
"host" => "10.0.2.2",
"SequenceNumber" => "1463",
"NewCommandState" => "Stopped",
"PipelineId" => "167",
"CommandName" => "Import-Module",
"HostName" => "ConsoleHost"
}

Logstash config-file don't catch my logs, but debugger did

So, I'm a little bit new at the elk-stack, and I’m having an issue with further experiment with the tools. I'm using a linux machine.
First of all, here's my config-file :
input {
file {
type => "openerp"
path => "/home/jvc/Documents/log/openerp-cron.log.2014-11-20.txt"
start_position => "beginning"
codec => multiline{
pattern => "^%{TIMESTAMP_ISO8601} "
negate => true
what => previous
}
}
}
filter{
if [type]=="openerp"{
date{
match => ["timestamp","yyyy-MM-dd HH:mm:ss,SSS"]
}
grok{
patterns_dir => "./patterns"
match => { "message" => "%{ODOOLOG}" }
}
}
}
output{
file{
path => "/home/jvc/Bureau/testretour.txt"
}
}
I have some patterns too :
REQUESTTIMESTAMP %{MONTHDAY}/%{MONTH}/%{YEAR} %{TIME}
REQUEST %{IPORHOST:client} %{USER:ident} %{USER:auth} [%{REQUESTTIMESTAMP:request_timestamp}] "%{WORD:request_type} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} -
ODOOMISC %{GREEDYDATA}
ODOOLOG %{TIMESTAMP_ISO8601:timestamp} %{POSINT:pid} %{LOGLEVEL:level} (?:%{USERNAME:user}|\?) %{PROG:module}: (?:%{REQUEST}|%{ODOOMISC:misc})
Some examples of the logs :
2014-11-21 08:00:16,715 17798 DEBUG noe openerp.addons.base.ir.ir_cron: cron.object.execute('noe', 1, '*', u'crossovered.budget.lines', u'computeblank')
2014-11-21 08:00:17,172 17798 WARNING noe openerp.osv.orm.browse_record.noe_utils.synchro_date: Field 'conform' does not exist in object 'browse_record(noe_utils.synchro_date, 13)'
2014-11-21 08:00:17,172 17798 ERROR noe openerp.sql_db: Programming error: can't adapt type 'browse_record', in query SELECT id
FROM crossovered_budget_lines
WHERE is_blank='t'
AND general_budget_id in %s
AND date_from <= %s AND date_to >= %s
2014-11-21 08:00:17,173 17798 ERROR noe openerp.addons.base.ir.ir_cron: Call of self.pool.get('crossovered.budget.lines').computeblank(cr, uid, *()) failed in Job 10
I'm having trouble with this config. For some reason that I can't find, this produces nothing.
What I have tried - done :
-First of all, I tested my grok, and multiline pattern in some grok debugger I have find on the web. All of them matches my logs.
-Before using the codec for multiline, i used the multiline filter. This one worked, but seems to be deprecated. So it's not a solution.
-I know that logstash keep in mind what he had read or not with the "sincedb" files : I delete these before every test, but you know what happens.
-I tried to run logstash with the -verbose, but nothing wrong is displayed.
-I don't really know if I must write the ".txt" at the end of my paths. But anyway, none of them works.
Have I missed something ? Thank you in advance for helping hands.
So, with more test i succeeded. I copied the content of one of my logs file and pasted it in another file : It works.
But, there is now another question : if deleting the "sincedb" file doesn't work, how can i "empty" the cache of logstash ?

Logstash grok multiline message

My logs are formatted like this:
2014-06-19 02:26:05,556 INFO ok
2014-06-19 02:27:05,556 ERROR
message:space exception
at line 85
solution:increase space
remove files
There are 2 types of events:
-log on one line like the first
-log on multiple line like the second
I am able to process the one line event, but I am not able to process the second type, where I would like to stock the message in one variable and the solution in another.
This is my config:
input {
file {
path => ["logs/*"]
start_position => "beginning"
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601} "
negate => true
what => previous
}
}
}
filter {
#parsing of one line event
grok {
patterns_dir => "./patterns"
match=>["message","%{TIMESTAMP_ISO8601:timestamp} %{WORD:level} ok"]
}
#the parsing fail, so we assumed we are in multiline events, now I process them and I am stuck when I am getting to the new line.
if "_grokparsefailure" in [tags] {
grok {
patterns_dir => "./patterns"
match=>["message","%{TIMESTAMP_ISO8601:timestamp} %{WORD:level}\r\n"]
}
}
}
So this is what I have done, and I would like to have in my console output the following:
{
"#timestamp" => "2014-06-19 00:00:00,000"
"path" => "logs/test.log"
"level"=>"INFO"
},
{
"#timestamp" => "2014-06-19 00:00:00,000"
"path" => "logs/test.log"
"level"=>"ERROR"
"message" => "space exception at line 85"
"solution"=>"increase space remove files"
}
Concretely, I would like to get all the expression between two words ("message" and "solution" for the message variable, "solution" and the end of event for the solution variable), and that no matter if the expression is on one or multiple lines.
Thanks in advance
As for multiline grok, it's best to use special flag for pattern string:
grok {
match => ["message", "(?m)%{SYSLOG5424LINE}"]
}
It looks like you have two issues:
You need to correctly combine your multilines:
filter
{
multiline
{
pattern => "^ "
what => "previous"
}
}
This will combine any line that begins with a space into the previous line. You may end up having to use a "next" instead of a "previous".
Replace Newlines
I don't believe that grok matches across newlines.
I got around this by doing the following in your filter section. This should go before the grok section:
mutate
{
gsub => ["message", "\n", "LINE_BREAK"]
}
This allowed me to grok multilines as one big line rather than matching only till the "\n".

How to remove an event from logstash?

I have a line in my log files that literally just have a semi colon in them. I am assuming it is attached to the previous line. Logstash is constantly printing them, and I want to drop these when ever there is a line that begins with a ;.
This is what logstash prints:
"message" => ";/r"
"#version" => "1"
"#timestamp" => 2014-06-24T15:39:00.655Z,"
"type" => "BCM_Core",
"host => XXXXXXXXXXX",
"Path => XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"tags" => [
[0] "_grokparsefailureZ"
],
"BCM_UTC_TIME" =>"2014-06-24%{time}Z"
I've attempted to use multiline to append to previous line so logstash would stop printing:
multiline{
type => "BCM_Core"
pattern => "\;"
negate => true
what => "previous"
}
but logstash is still printing them out. How can I make logstash drop it?
Just use a drop filter to drop any line that starts with ;:
filter {
if ([message] =~ "^;") {
drop {}
}
}
Although based on your output, it really ;/r not ;\r, so you might need to adjust if your output is not just an example.
You can also just drop anything that fails to grok:
if "_grokparsefailure" in [tags] { drop {} }