GROK custom pattern filter in logstash - logstash

How to create a grok custom pattern filter in logstash?
I want to create a pattern for http response status code
here is my pattern code
STATUS_CODE __ %{NONNEGINT} __
what I reaaly want to do is to have all of my web server hits with user IP and request http headers and payload and also web servers's response.
and here is my logstash.conf
input {
file {
type => "kpi-success"
path => "/var/log/kpi_success.log"
start_position => beginning
}
}
filter {
if [type] == "kpi-success" {
grok {
patterns_dir => ["./patterns"]
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{GREEDYDATA:message} "}
}
multiline {
pattern => "^\["
what => "previous"
negate => true
}
mutate{
add_field => {
"statusCode" => "[STATUS_CODE]"
}
}
}
}
output {
if [type] == "kpi-success" {
elasticsearch {
hosts => "elasticsearch:9200"
index => "kpi-success-%{+YYYY.MM.dd}"
}
}
}

You don't have to use a custom pattern file, you can define a new one directly in the filter.
grok {
match => { "message" => "(?<STATUS_CODE>__ %{NONNEGINT} __)"}
}

Related

Grok pattern for log with pipeline seperator

I'm trying to figure out the log pattern for the log pattern below.
01/02AVDC190001|00001|4483850000152971|DATAPREP|PREPERATION/ENRICHEMENT |020190201|20:51:52|SCHED
What I've tried so far is :
input {
file {
path => "C:/Elasitcity/Logbase/July10_Logs_SDC/*.*"
start_position => "beginning"
sincedb_path => "NUL"
}
}
filter {
mutate {
gsub => ["message","\|"," "]
}
grok {
match => ["message","%{NUMBER:LOGID} %{NUMBER:LOGPHASE} %{NUMBER:LOGID} %{WORD:LOGEVENT} %{WORD:LOGACTIVITY} %{DATE_US: DATE} %{TIME:LOGTIME}"]
}
}
}
output {
elasticsearch {
hosts => "localhost"
index => "grokcsv"
document_type => "gxs"
}
stdout {}
}
I'm also wondering if its possible to combine the data and time since its seperated by a pipeline character. But that's not the primary question,.

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
}
}

grok multiple messages and process them with different tags

I want to make a filter in Logstash(version 2.4) with different matches in the same grok.
I would like to add different tags depending on the match.
Basically, I receive three different message pattern:
"##MAGIC##%message"
"##REAL##%message"
"%message"
I am trying to do is:
grok {
match => {"message" => "##MAGIC##%{GREEDYDATA:magic_message}"}
match => {"message" => "##REAL##%{GREEDYDATA:real_message}"}
match => {"message" => "%{GREEDYDATA:basic_message}"}
if [magic_message]{
overwrite => [ "message"]
add_tag => ["Magic"]
} else if [real_message]{
overwrite => [ "message"]
add_tag => ["Real"]
}else{
overwrite => [ "message"]
add_tag => ["Basic"]
}
But, I got this compile fails:
The given configuration is invalid. Reason: Expected one of #, => at line 34, column 9 (byte 900) after filter {
grok {
match => {"message" => "##MAGIC##%{GREEDYDATA:magic_message}"}
match => {"message" => "##REAL##%{GREEDYDATA:real_message}"}
match => {"message" => "%{GREEDYDATA:basic_message}"}
if {:level=>:fatal}
The logstash configuration syntax does not work like this.
This should work better (under the assumption that you want to replace message by magic_message/real_message):
grok {
match => {"message" => [ "##MAGIC##%{GREEDYDATA:magic_message}",
"##REAL##%{GREEDYDATA:real_message}",
"%{GREEDYDATA:basic_message}"]}
}
if [magic_message] {
mutate {
replace => { "message" => "%{magic_message}" }
add_tag => ["Magic"]
}
} else if [real_message] {
mutate {
replace => { "message" => "%{real_message}" }
add_tag => ["Real"]
}
} else {
mutate {
add_tag => ["Basic"]
}
}

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