logstash - split a message by newlines - ruby

logstash
trying to split a message by newlines ("\n") with no success so far. I need to retrieve the last line only.
Logstash code:
mutate{
split => ["traceback", "\n"]
add_field => {"traceback_last_line" => "%{[traceback][-1]}"}
}
Input:
[traceback] =
"File "<doctest...>", line 10, in <module>
lumberjack()
File "<doctest...>", line 4, in lumberjack
bright_side_of_death()
IndexError: tuple index out of range"

I Used gsub to replace '\n' and then, the usual sequence of mutate.split
mutate {
copy => { "traceback" => "traceback_tmp" }
}
mutate {
gsub => ["traceback_tmp", "\n", "::"]
}
mutate {
split => {"traceback_tmp" => "::"}
add_field => ["traceback_summary", "%{[traceback_tmp][-1]}"]
remove_field => ["traceback_tmp"]
}

Related

change dynamic field value in logstash

I'm using a filter in logstash. I wanna change value of a dynamic field in logstash.
I'm using below codes in my filter:
if [state_ls_keyvalue] == "False" {
mutate{
add_field => {"%{field_ls_keyvalue}" => "%{enrich_column}"}
}
} else {
mutate{
remove_field => ["%{field_ls_keyvalue}"]
}
mutate{
add_field => {"%{field_ls_keyvalue}" => "%{enrich_column}"}
}
}
but it does not work. how shall I handle it?
Both remove_field and add_field sprintf the field name.
output { stdout { codec => rubydebug { metadata => false } } }
input { generator { count => 1 lines => [ '{ "field_ls_keyvalue": "a", "a": "c", "enrich_column": "d" }' ] codec => json { } } }
filter {
mutate { remove_field => [ "%{field_ls_keyvalue}" ] }
mutate { add_field => { "%{field_ls_keyvalue}" => "%{enrich_column}" } }
}
will produce
"a" => "d",
If that is not happening for you then it suggests the conditional test of [validation] is evaluating to false.
The problem is related to type of field in elasticsearch. we can handle with mapping and change it.
using only add_field, the value of new field appends into old one.
using remove_field and then add_field, replace the value of new field to old one.

Removing grok matched field after using it

I use filebeat to fetch log files into my logstash and then filter unnecessary fields. Everything works fine and I output these into elasticsearch but there is a field which I use for elasticsearch index name, I define this variable in my grok match but I couldn't find a way to remove that variable once it serves its purpose. I'll share my logstash config below
input {
beats {
port => "5044"
}
}
filter {
grok {
match => { "[log][file][path]" => ".*(\\|\/)(?<myIndex>.*)(\\|\/).*.*(\\|\/).*(\\|\/).*(\\|\/).*(\\|\/)" }
}
json {
source => message
}
mutate {
remove_field => ["agent"]
remove_field => ["input"]
remove_field => ["#metadata"]
remove_field => ["log"]
remove_field => ["tags"]
remove_field => ["host"]
remove_field => ["#version"]
remove_field => ["message"]
remove_field => ["event"]
remove_field => ["ecs"]
}
date {
match => ["t","yyyy-MM-dd HH:mm:ss.SSS"]
remove_field => ["t"]
}
mutate {
rename => ["l","log_level"]
rename => ["mt","msg_template"]
rename => ["p","log_props"]
}
}
output {
elasticsearch {
hosts => [ "localhost:9222" ]
index => "%{myIndex}"
}
stdout { codec => rubydebug { metadata => true } }
}
I just want to remove the "myIndex" field from my index. With this config file, I see this field in elasticsearch if possible I want to remove it. I've tried to remove it with other fields altogether but it gave an error. I guess it's because I removed it before logstash could give it to elasticsearch.
Create the field under [#metadata]. Those fields are available to use in logstash but are ignored by outputs unless they use a rubydebug codec.
Adjust your grok filter
match => { "[log][file][path]" => ".*(\\|\/)(?<[#metadata][myIndex]>.*)(\\|\/).*.*(\\|\/).*(\\|\/).*(\\|\/).*(\\|\/)" }
Delete [#metadata] from the mutate+remove_field and change the output configuration to have
index => "%{[#metadata][myIndex]}"

How to retrieve n number of previous and after lines in log file using logstash configuration?

I am creating an application where I need to put previous and after n number of lines in elasticsearch with current log. This is my current logstash configuraion.
What changes I need to make so that I can retrieve last n number of lines(Let's say 5) in my output?
input{ file{ path => "D:\ELK_Info\TestLogs_Updated.log"
#start_position => beginning
ignore_older => 0
sincedb_path => "NUL"
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601}"
negate => true
what => "previous"
} } }
filter{
grok{
match => {
"message" => "%{TIMESTAMP_ISO8601:log_timestamp} %{DATA:line_number} %{DATA:log_level} %{DATA:log_type} %{NOTSPACE:space} %{GREEDYDATA:stackTrace}" } } mutate { remove_field => [ "tags", "space", "line_number"]} }
output { file{ path => "D:\ELK_Info\logstashOutput.log" }

elasticsearch - import csv using logstash date is not parsed as of datetime type

I am trying to import csv into elasticsearch using logstash
I have tried using two ways:
Using CSV
Using grok filter
1) For csv below is my logstash file:
input {
file {
path => "path_to_my_csv.csv"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
csv {
separator => ","
columns => ["col1","col2_datetime"]
}
mutate {convert => [ "col1", "float" ]}
date {
locale => "en"
match => ["col2_datetime", "ISO8601"] // tried this one also - match => ["col2_datetime", "yyyy-MM-dd HH:mm:ss"]
timezone => "Asia/Kolkata"
target => "#timestamp" // tried this one also - target => "col2_datetime"
}
}
output {
elasticsearch {
hosts => "http://localhost:9200"
index => "my_collection"
}
stdout {}
}
2) Using grok filter:
For grok filter below is my logstash file
input {
file {
path => "path_to_my_csv.csv"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
grok {
match => { "message" => "(?<col1>(?:%{BASE10NUM})),(%{TIMESTAMP_ISO8601:col2_datetime})"}
remove_field => [ "message" ]
}
date {
match => ["col2_datetime", "yyyy-MM-dd HH:mm:ss"]
}
}
output {
elasticsearch {
hosts => "http://localhost:9200"
index => "my_collection_grok"
}
stdout {}
}
PROBLEM:
So when I run both the files individually, I am able to import the data in elasticsearch. But my date field is not parsed as of datetime type rather it has been saved as string and because of that I am not able to run the date filters.
So can someone help me to figure out why it's happening.
My elasticsearch version is 5.4.1.
Thanks in advance
There are 2 changes I made to your config file.
1) remove the under_score in the column name col2_datetime
2) add target
Here is how my config file look like...
vi logstash.conf
input {
file {
path => "/config-dir/path_to_my_csv.csv"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
csv {
separator => ","
columns => ["col1","col2"]
}
mutate {convert => [ "col1", "float" ]}
date {
locale => "en"
match => ["col2", "yyyy-MM-dd HH:mm:ss"]
target => "col2"
}
}
output {
elasticsearch {
hosts => "http://172.17.0.1:9200"
index => "my_collection"
}
stdout {}
}
Here is the data file:
vi path_to_my_csv.csv
1234365,2016-12-02 19:00:52
1234368,2016-12-02 15:02:02
1234369,2016-12-02 15:02:07

Logstash Grok error

My logstash configuration is giving me this error:
whenever i run this command: /opt/logstash/bin/logstash -f /etc/logstash/conf.d/logstash.conf --auto-reload --debug
reason=>"Expected one of #, {, ,, ] at line 27, column 95 (byte 677) after filter {\n\n\tif [type] == \"s3\" {\n\t\tgrok {\n\t\n \t\t\tmatch => [\"message\", \"%{IP:client} %{USERNAME} %{USERNAME} \\[%{HTTPDATE:timestamp}\\] (?:\"", :level=>:error, :file=>"logstash/agent.rb", :line=>"430", :method=>"create_pipeline"}
This has to do with my pattern.But when i checked same in Grok online debugger its giving me required answer.Please help.
Here is my logstash configuration:
input {
s3 {
access_key_id => ""
bucket => ""
region => ""
secret_access_key => ""
prefix => "access"
type => "s3"
add_field => { source => gzfiles }
sincedb_path => "/dev/null"
#path => "/home/shubham/logstash.json"
#temporary_directory => "/home/shubham/S3_temp/"
backup_add_prefix => "logstash-backup"
backup_to_bucket => "logstash-nginx-overcart"
}
}
filter {
if [type] == "s3" {
grok {
match => ["message", "%{IP:client} %{USERNAME} %{USERNAME} \[%{HTTPDATE:timestamp}\] (?:"%{WORD:request}
%{URIPATHPARAM:path} HTTP/%{NUMBER:version}" %{NUMBER:reponse} %{NUMBER:bytes} "%{USERNAME}" %{GREEDYDATA:responseMessage})"]
}
}
}
output {
elasticsearch {
hosts => ''
index => "accesslogs"
}
}
You have a couple of unescaped " characters in your match assignment (around the username var for example), which trip up the parser. If you escape those with a \ it should work.

Resources