Grok filter - check field existence - logstash-grok

I have a log message with this structure:
"message" => "{
"#timestamp":"201856T12:54:33.347+02:00",
"thread":"main",
"logger_name":"org.elasticsearch.bootstrap",
"level":"WARN",
"message":"JNA not found. native methods will be disabled.",
"stack_trace": "java.lang.ClassNotFoundException: ...
}
As you can see, inside the message there is a stack_trace field, but the control
if [message][stack_trace] {
mutate { add_tag => ["EXCEPTION"] }
}
doesn't work
How can I check if "message" contains the "stack_trace" field?
Other infos:
the message is generated via logstash-logback-encoder, as follow:
<appender name="STASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>localhost:5000</destination>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>Europe/Berlin</timeZone>
</timestamp>
<callerData>
<classFieldName>classname</classFieldName>
<methodFieldName>method</methodFieldName>
<fileFieldName>file</fileFieldName>
<lineFieldName>line</lineFieldName>
</callerData>
<threadName>
<fieldName>thread</fieldName>
</threadName>
<loggerName />
<logLevel />
<message />
<stackTrace />
</providers>
</encoder>
</appender>
This is the content of logstash input pipeline:
input {
tcp {
port => 5000
}
}
filter {
grok {
match => { "message" => "LAT: %{NUMBER:LAT:float}, LON: %{NUMBER:LON:float}"}
match => { "message" => "file %{WORD:TIPOFILE} elaborato" }
match => { "message" => "Pubblicazione file %{WORD:PUB_FILENAME} sulla coda %{WORD:DEST_QUEUE} terminata" }
}
mutate {
rename => { "TIPOFILE" => "[filename]" }
rename => { "LAT" => "[location][latitude]" }
rename => { "LON" => "[location][longitude]" }
rename => { "DEST_QUEUE" => "[destQueue]" }
rename => { "PUB_FILENAME" => "[nomeFilePubbl]" }
}
}
output {
stdout {
codec => rubydebug
}
elasticsearch {
hosts => "elasticsearch:9200"
}
}

Related

Grok json parser with \n in it

I have a json log message as below :
{\n \"jobId\": \"12030845\",\n \"publicationId\": \"hpg01\",\n \"startDateTime\": \"2022-08-03T14:38:49.833\",\n \"endDateTime\": \"2022-08-03T14:48:55.420\",\n \"jobName\": \"import\",\n \"numberInputDocs\": \"12925\",\n \"numberOutputDocs\": \"12925\",\n \"numberUCMDocs\": \"1159\",\n \"state\": \"success\",\n \"numberDocErrors\": \"0\"\n}
And I need to parse/convert this into a key/value pair. I am using logstash and grok to parse it.
My logstash.conf is as follows :
input {
file {
codec => multiline {
pattern => '^\n'
negate => true
what => previous
}
path => "C:/logs/gaimport.log"
}
}
filter {
mutate
{
replace => [ "message", "%{message}}" ]
gsub => [ 'message','\n','']
}
if [message] =~ /^{.*}$/
{
json { source => message }
}
}
output {
stdout { codec => rubydebug }
}

Can't create a field with a variable from a grok match regex

I am currently using logstash, elasticsearch and kibana 6.3.0
My log are generated at a unique id path : /tmp/USER_DATA/FactoryContainer/images/(my unique id)/oar/oar_image_job(my unique id).stdout
What I want to do is to match this unique id and to create a field with this id.
I m a bit novice to logstash filter but I don't know why it doesn't want to use my uid and always return me %{uid} in my field or this Failed to execute action error.
my filter :
input {
file {
path => "/tmp/USER_DATA/FactoryContainer/images/*/oar/oar_image_job*.stdout"
start_position => "beginning"
add_field => { "data_source" => "oar-image-job" }
}
}
filter {
grok {
match => ["path","%{UNIXPATH}%{NUMBER:uid}%{UNIXPATH}"]
}
mutate {
add_field => [ "unique_id" => "%{uid}" ]
}
}
output {
if [data_source] == "oar-image-job" {
elasticsearch {
index => "oar-image-job-%{+YYYY.MM.dd}"
hosts => ["localhost:9200"]
}
}
}
the data_source field is to avoid this issue: When you put multiple config files in a directory for Logstash to use, they will all be concatenated
in the grok debugger %{UNIXPATH}%{NUMBER:uid}%{UNIXPATH} my path return me the good value
link to the solution : https://discuss.elastic.co/t/cant-create-a-field-with-a-variable-from-a-grok-match-regex/142613/7?u=thesmartmonkey
the correct filter :
input {
file {
path => "/tmp/USER_DATA/FactoryContainer/images/*/oar/oar_image_job*.stdout"
start_position => "beginning"
add_field => { "data_source" => "oar-image-job" }
}
}
filter {
grok {
match => { "path" => [ "/tmp/USER_DATA/FactoryContainer/images/%{DATA:unique_id}/oar/oar_image_job%{DATA}.stdout" ] }
}
}
output {
if [data_source] == "oar-image-job" {
elasticsearch {
index => "oar-image-job-%{+YYYY.MM.dd}"
hosts => ["localhost:9200"]
}
}
}

Logstash Multiline Logfile XML Parsing Filter

I am absolutely new to Logstash and I am trying to parse my multiline logentries, that are in the following format
<log level="INFO" time="Wed May 03 08:25:03 CEST 2017" timel="1493792703368" host="host">
<msg><![CDATA[Method=GET URL=http://localhost (Vers=[Version], Param1=[param1], Param2=[param1]) Result(Content-Length=[22222], Content-Type=[text/xml; charset=utf-8]) Status=200 Times=TISP:1098/CSI:-/Me:1/Total:1099]]>
</msg>
</log>
Do you know how to implement the filter in logstash config to be able to index the following fields in elasticsearch
time, host, Vers, Param1, Param2, TISP
Thank you very much
OK, I found out how to do it. This is my pipeline.conf file and it works
input {
beats {
port => 5044
}
}
filter {
xml {
store_xml => false
source => "message"
xpath => [
"/log/#level", "level",
"/log/#time", "time",
"/log/#timel", "unixtime",
"/log/#host", "host_org",
"/log/#msg", "msg",
"/log/msg/text()","msg_txt"
]
}
grok {
break_on_match => false
match => ["msg_txt", "Param1=\[(?<param1>-?\w+)\]"]
match => ["msg_txt", "Param2=\[(?<param2>-?\w+)\]"]
match => ["msg_txt", "Vers=\[(?<vers>-?\d+\.\d+)\]"]
match => ["msg_txt", "TISP:(?<tisp>-?\d+)"]
match => [unixtime, "(?<customTime>-?\d+)"]
}
if "_grokparsefailure" in [tags] {
drop { }
}
mutate {
convert => { "tisp" => "integer" }
}
date {
match => [ "customTime", "UNIX_MS"]
target => "#timestamp"
}
if "_dateparsefailure" in [tags] {
drop { }
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
user => user
password => passwd
}
}

Logstash filter correct in debugger but doesn't work when searching in kibana

My logstash filter correct in debugger but doesn't show the fields when searching the exact message I tested with in kibana. Here is my filter:
filter {
if [type] == "syslog" {
grok {
match => { 'message' => '%{SYSLOG5424LINE}' }
}
syslog_pri {
syslog_pri_field_name => 'syslog5424_pri'
}
date {
match => [ 'syslog5424_ts', 'ISO8601' ]
}
}
and here is an example of my log message:
<134>1 2017-01-23T10:54:44.587136-08:00 mcmp mapp - - close ('xxx', 32415)
It seems like the filter isn't applying, I restarted my logstash service and tested in the grok debugger. Any idea whats wrong?
It looks like it works correctly to me.
I created test.conf with:
input {
stdin {}
}
filter {
grok {
match => { 'message' => '%{SYSLOG5424LINE}' }
}
syslog_pri {
syslog_pri_field_name => 'syslog5424_pri'
}
date {
match => [ 'syslog5424_ts', 'ISO8601' ]
}
}
output {
stdout { codec => "rubydebug" }
}
and then tested like this:
echo "<134>1 2017-01-23T10:54:44.587136-08:00 mcmp mapp - - close ('xxx', 32415)" | bin/logstash -f test.conf
And the event it gives as output:
{
"syslog_severity_code" => 6,
"syslog_facility" => "local0",
"syslog_facility_code" => 16,
"syslog5424_ver" => "1",
"message" => "<134>1 2017-01-23T10:54:44.587136-08:00 mcmp mapp - - close ('xxx', 32415)",
"syslog5424_app" => "mapp",
"syslog5424_msg" => "close ('xxx', 32415)",
"syslog_severity" => "informational",
"tags" => [],
"#timestamp" => 2017-01-23T18:54:44.587Z,
"syslog5424_ts" => "2017-01-23T10:54:44.587136-08:00",
"syslog5424_pri" => "134",
"#version" => "1",
"host" => "xxxx",
"syslog5424_host" => "mcmp"
}
which has all of the fields that the SYSLOG5424LINE pattern contains.

Logstash input filename as output elasticsearch index

Is there a way of having the filename of the file being read by logstash as the index name for the output into ElasticSearch?
I am using the following config for logstash.
input{
file{
path => "/logstashInput/*"
}
}
output{
elasticsearch{
index => "FromfileX"
}
}
I would like to be able to put a file e.g. log-from-20.10.2016.log and have it indexed into the index log-from-20.10.2016. Does the logstash input plugin "file" produce any variables for use in the filter or output?
Yes, you can use the path field for that and grok it to extract the filename into the index field
input {
file {
path => "/logstashInput/*"
}
}
filter {
grok {
match => ["path", "(?<index>log-from-\d{2}\.\d{2}\.\d{4})\.log$" ]
}
}
output{
elasticsearch {
index => "%{index}"
}
}
input {
file {
path => "/home/ubuntu/data/gunicorn.log"
start_position => "beginning"
}
}
filter {
grok {
match => {
"message" => "%{USERNAME:u1} %{USERNAME:u2} \[%{HTTPDATE:http_date}\] \"%{DATA:http_verb} %{URIPATHPARAM:api} %{DATA:http_version}\" %{NUMBER:status_code} %{NUMBER:byte} \"%{DATA:external_api}\" \"%{GREEDYDATA:android_client}\""
remove_field => ["message"]
}
}
date {
match => ["http_date", "dd/MMM/yyyy:HH:mm:ss +ssss"]
}
ruby {
code => "event.set('index_name',event.get('path').split('/')[-1].gsub('.log',''))"
}
}
output {
elasticsearch {
hosts => ["0.0.0.0:9200"]
index => "%{index_name}-%{+yyyy-MM-dd}"
user => "*********************"
password => "*****************"
}
stdout { codec => rubydebug }
}

Resources