Adding fields depending on event message in Logstash not working - elasticsearch

I have ELK installed and working in my machine, but now I want to do a more complex filtering and field adding depending on event messages.
Specifically, I want to set "id_error" and "descripcio" depending on the message pattern.
I have been trying a lot of code combinations in "logstash.conf" file, but I am not able to get the expected behavior.
Can someone tell me what I am doing wrong, what I have to do or if this is not possible? Thanks in advance.
This is my "logstash.conf" file, with the last test I have made, resulting in no events captured in Kibana:
input {
file {
path => "C:\xxx.log"
}
}
filter {
grok {
patterns_dir => "C:\elk\patterns"
match => [ "message", "%{ERROR2:error2}" ]
add_field => [ "id_error", "2" ]
add_field => [ "descripcio", "error2!!!" ]
}
grok {
patterns_dir => "C:\elk\patterns"
match => [ "message", "%{ERROR1:error1}" ]
add_field => [ "id_error", "1" ]
add_field => [ "descripcio", "error1!!!" ]
}
if ("_grokparsefailure" in [tags]) { drop {} }
}
output {
elasticsearch {
host => "localhost"
protocol => "http"
index => "xxx-%{+YYYY.MM.dd}"
}
}
I also have tried the following code, resulting in fields "id_error" and "descripcio" with both vaules "[1,2]" and "[error1!!!,error2!!!]" respectively, in each matched event.
As "break_on_match" is set "true" by default, I expect getting only the fields behind the matching clause, but this doesn't occur.
input {
file {
path => "C:\xxx.log"
}
}
filter {
grok {
patterns_dir => "C:\elk\patterns"
match => [ "message", "%{ERROR1:error1}" ]
add_field => [ "id_error", "1" ]
add_field => [ "descripcio", "error1!!!" ]
match => [ "message", "%{ERROR2:error2}" ]
add_field => [ "id_error", "2" ]
add_field => [ "descripcio", "error2!!!" ]
}
if ("_grokparsefailure" in [tags]) { drop {} }
}
output {
elasticsearch {
host => "localhost"
protocol => "http"
index => "xxx-%{+YYYY.MM.dd}"
}
}

I have solved the problem. I get the expected results with the following code in "logstash.conf":
input {
file {
path => "C:\xxx.log"
}
}
filter {
grok {
patterns_dir => "C:\elk\patterns"
match => [ "message", "%{ERROR1:error1}" ]
match => [ "message", "%{ERROR2:error2}" ]
}
if [message] =~ /error1_regex/ {
grok {
patterns_dir => "C:\elk\patterns"
match => [ "message", "%{ERROR1:error1}" ]
}
mutate {
add_field => [ "id_error", "1" ]
add_field => [ "descripcio", "Error1!" ]
remove_field => [ "message" ]
remove_field => [ "error1" ]
}
}
else if [message] =~ /error2_regex/ {
grok {
patterns_dir => "C:\elk\patterns"
match => [ "message", "%{ERROR2:error2}" ]
}
mutate {
add_field => [ "id_error", "2" ]
add_field => [ "descripcio", "Error2!" ]
remove_field => [ "message" ]
remove_field => [ "error2" ]
}
}
if ("_grokparsefailure" in [tags]) { drop {} }
}
output {
elasticsearch {
host => "localhost"
protocol => "http"
index => "xxx-%{+YYYY.MM.dd}"
}
}

Related

grokdebugger validates entries of a log that logstash eventually refuses

Using the grokdebugger I've adapted what I found over the Internet for my first attempt to handle logback spring-boot kind of logs.
Here is a log entry sent to grokdebugger:
2022-03-09 06:35:15,821 [http-nio-9090-exec-1] WARN org.springdoc.core.OpenAPIService - found more than one OpenAPIDefinition class. springdoc-openapi will be using the first one found.
with the grok pattern:
(?<timestamp>%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}) \[(?<thread>(.*?)+)\] %{LOGLEVEL:level}\s+%{GREEDYDATA:class} - (?<logmessage>.*)
and its dispatches its content as wished:
{
"timestamp": [
[
"2022-03-09 06:35:15,821"
]
],
"YEAR": [
[
"2022"
]
],
"MONTHNUM": [
[
"03"
]
],
"MONTHDAY": [
[
"09"
]
],
"TIME": [
[
"06:35:15,821"
]
],
"HOUR": [
[
"06"
]
],
"MINUTE": [
[
"35"
]
],
"SECOND": [
[
"15,821"
]
],
"thread": [
[
"http-nio-9090-exec-1"
]
],
"level": [
[
"WARN"
]
],
"class": [
[
"org.springdoc.core.OpenAPIService"
]
],
"logmessage": [
[
"found more than one OpenAPIDefinition class. springdoc-openapi will be using the first one found."
]
]
}
But when I ask for the same action inside logstash, I set in configuration for input declaration:
input {
file {
path => "/home/lebihan/dev/Java/comptes-france/metier-et-gestion/dev/ApplicationMetierEtGestion/sparkMetier.log"
codec => multiline {
pattern => "^%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}.*"
negate => "true"
what => "previous"
}
}
}
and for filter declaration:
filter {
#If log line contains tab character followed by 'at' then we will tag that entry as stacktrace
if [message] =~ "\tat" {
grok {
match => ["message", "^(\tat)"]
add_tag => ["stacktrace"]
}
}
grok {
match => [ "message",
"(?<timestamp>%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}) \[(?<thread>(.*?)+)\] %{LOGLEVEL:level}\s+%{GREEDYDATA:class} - (?<logmessage>.*)"
]
}
date {
match => [ "timestamp" , "yyyy-MM-dd HH:mm:ss.SSS" ]
}
}
But it fails in parsing it, and I don't know how to have extra content about the underlying error mentioned by _grokparsefailure.
The main responsible of my trouble is the:
grok {
match => [
instead of:
grok {
match => {
But after that, I had to change:
the timestamp definition to a %{TIMESTAMP_ISO8601:timestamp}
the date match
and in the date match add a target to it to avoid a
to avoid a _dateparsefailure.
#timestamp:
Mar 16, 2022 # 09:14:22.002
#version:
1
class:
f.e.service.AbstractSparkDataset
host:
debian
level:
INFO
logmessage:
Un dataset a été sauvegardé dans le fichier parquet /data/tmp/balanceComptesCommunes_2019_2019.
thread:
http-nio-9090-exec-10
timestamp:
2022-03-16T06:34:09.394Z
_id:
8R_KkX8BBIYNTaMw1Jfg
_index:
ecoemploimetier-2022.03.16
_score:
-
_type:
_doc
I eventually corrected my logstash config file like that:
input {
file {
path => "/home/[...]/myLog.log"
sincedb_path => "/dev/null"
start_position => "beginning"
codec => multiline {
pattern => "^%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}.*"
negate => "true"
what => "previous"
}
}
}
filter {
#If log line contains tab character followed by 'at' then we will tag that entry as stacktrace
if [message] =~ "\tat" {
grok {
match => ["message", "^(\tat)"]
add_tag => ["stacktrace"]
}
}
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[(?<thread>(.*?)+)\] %{LOGLEVEL:level} %{GREEDYDATA:class} - (?<logmessage>.*)" }
}
date {
# 2022-03-16 07:32:24,860
match => [ "timestamp" , "yyyy-MM-dd HH:mm:ss,SSS" ]
target => "timestamp"
}
# S'il n'y a pas d'erreur de parsing, supprimer le message d'origine, non parsé
if "_grokparsefailure" not in [tags] {
mutate {
remove_field => [ "message", "path" ]
}
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => ["localhost:9200"]
index => "ecoemploimetier-%{+YYYY.MM.dd}"
}
}

Logstash authentication

I'm setting up a logstash cluster and I configured some authentication regarding the output filter.
However I can't figure out why it isn't working...
I tried brackets, no brackets, IP, FQDN...
input {
tcp {
port => 5000
type => syslog
}
udp {
port => 5000
type => syslog
}
}
filter {
if [type] == "syslog" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
add_field => [ "received_at", "%{#timestamp}" ]
add_field => [ "received_from", "%{host}" ]
}
date {
match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
}
}
}
output {
elasticsearch { hosts => ["localhost.enedis.fr:9200"] }
user = sec-svc-log01
password => 3N3D1S!!
stdout { codec => rubydebug }
}
Am I missing something ?
Thanks for your help !
Try using below ouput section code,
output {
elasticsearch {
hosts => ["localhost.enedis.fr:9200"]
user => "sec-svc-log01"
password => "3N3D1S!!"
}
stdout { codec => rubydebug }
}

Logstash nginx filter doesn't apply to half of rows

Using filebeat to push nginx logs to logstash and then to elasticsearch.
Logstash filter:
filter {
if [fileset][module] == "nginx" {
if [fileset][name] == "access" {
grok {
match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\" \"%{DATA:[nginx][access][agent]}\""] }
remove_field => "message"
}
mutate {
add_field => { "read_timestamp" => "%{#timestamp}" }
}
date {
match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
remove_field => "[nginx][access][time]"
}
useragent {
source => "[nginx][access][agent]"
target => "[nginx][access][user_agent]"
remove_field => "[nginx][access][agent]"
}
geoip {
source => "[nginx][access][remote_ip]"
target => "[nginx][access][geoip]"
}
}
else if [fileset][name] == "error" {
grok {
match => { "message" => ["%{DATA:[nginx][error][time]} \[%{DATA:[nginx][error][level]}\] %{NUMBER:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: (\*%{NUMBER:[nginx][error][connection_id]} )?%{GREEDYDATA:[nginx][error][message]}"] }
remove_field => "message"
}
mutate {
rename => { "#timestamp" => "read_timestamp" }
}
date {
match => [ "[nginx][error][time]", "YYYY/MM/dd H:m:s" ]
remove_field => "[nginx][error][time]"
}
}
}
}
There is just one file /var/log/nginx/access.log.
In kibana, I see ± half of the rows with parsed message and other half - not.
All of the rows in kibana have a tag "beats_input_codec_plain_applied".
Examples from filebeat -e
Row that works fine:
"source": "/var/log/nginx/access.log",
"offset": 5405195,
"message": "...",
"fileset": {
"module": "nginx",
"name": "access"
}
Row that doesn't work fine (no "fileset"):
"offset": 5405397,
"message": "...",
"source": "/var/log/nginx/access.log"
Any idea what could be the cause?

Elasticsearch, Logstash and Kibana for pfsense logs with geo location

I want to create a tile map in Kibana to show source IP's from countries around the world.
When trying to set up a tile map, I get an error saying that "The "logstash-*" index pattern does not contain any of the following field types: geo_point"
I've googled the problem and found this link https://github.com/elastic/logstash/issues/3137 and at the end of that page, it states this is fixed in 2.x. But I am on 2.1.
Here are my configs:
1inputs.conf:
input {
udp {
type => "syslog"
port => 5140
}
}
5pfsense.conf:
filter {
# Replace with your IP
if [host] =~ /10\.1\.15\.200/ {
grok {
match => [ 'message', '.* %{WORD:program}:%{GREEDYDATA:rest}' ]
}
if [program] == "filterlog" {
# Grab fields up to IP version. The rest will vary depending on IP version.
grok {
match => [ 'rest', '%{INT:rule_number},%{INT:sub_rule_number},,%{INT:tracker_id},%{WORD:interface},%{WORD:reason},%{WORD:action},%{WORD:direction},%{WORD:ip_version},%{GREEDYDATA:rest2}' ]
}
}
mutate {
replace => [ 'message', '%{rest2}' ]
}
if [ip_version] == "4" {
# IPv4. Grab field up to dest_ip. Rest can vary.
grok {
match => [ 'message', '%{WORD:tos},,%{INT:ttl},%{INT:id},%{INT:offset},%{WORD:flags},%{INT:protocol_id},%{WORD:protocol},%{INT:length},%{IP:src_ip},%{IP:dest_ip},%{GREEDYDATA:rest3}' ]
}
}
if [protocol_id] != 2 {
# Non-IGMP has more fields.
grok {
match => [ 'rest3', '^%{INT:src_port:int},%{INT:dest_port:int}' ]
}
}
else {
# IPv6. Grab field up to dest_ip. Rest can vary.
grok {
match => [ 'message', '%{WORD:class},%{WORD:flow_label},%{INT:hop_limit},%{WORD:protocol},%{INT:protocol_id},%{INT:length},%{IPV6:src_ip},%{IPV6:dest_ip},%{GREEDYDATA:rest3}' ]
}
}
mutate {
replace => [ 'message', '%{rest3}' ]
lowercase => [ 'protocol' ]
}
if [message] {
# Non-ICMP has more fields
grok {
match => [ 'message', '^%{INT:src_port:int},%{INT:dest_port:int},%{INT:data_length}' ]
}
}
mutate {
remove_field => [ 'message' ]
remove_field => [ 'rest' ]
remove_field => [ 'rest2' ]
remove_field => [ 'rest3' ]
remove_tag => [ '_grokparsefailure' ]
add_tag => [ 'packetfilter' ]
}
geoip {
add_tag => [ "GeoIP" ]
source => "src_ip"
}
}
}
Lastly, the 50outputs.conf:
output {
elasticsearch { hosts => localhost index => "logstash-%{+YYYY.MM.dd}" template_overwrite => "true" }
stdout { codec => rubydebug }
}

OS X: logstash works for a while and then stops with "Logstash shutdown completed" msg((

After I upgraded to logstash 1.5.0 getting strange behavior of this program.
Whenever I run it with next command:
$ logstash agent -f /usr/local/etc/logstash/conf.d/logstash.conf
It works for a while and then stops saying "Logstash shutdown completed".
Example:
.....
......
"#version" => "1",
"#timestamp" => "2015-06-20T21:04:09.087Z",
"type" => "SuricataIDPS",
"host" => "drew-sh.server",
"path" => "/var/log/suricata/eve.json",
"geoip" => {
"ip" => "209.52.144.104",
"country_code2" => "CA",
"country_code3" => "CAN",
"country_name" => "Canada",
"continent_code" => "NA",
"region_name" => "BC",
"city_name" => "Vancouver",
"latitude" => 49.25,
"longitude" => -123.13329999999999,
"timezone" => "America/Vancouver",
"real_region_name" => "British Columbia",
"location" => [
[0] -123.13329999999999,
[1] 49.25
],
"coordinates" => [
[0] -123.13329999999999,
[1] 49.25
]
}
}
Logstash shutdown completed
even after complete reinstallation:
$ brew rm logstash
$ brew install logstash
I'm having same issue (((
Here is my /usr/local/etc/logstash/conf.d/logstash.conf:
input {
file {
path => ["/var/log/suricata/eve.json"]
sincedb_path => ["/var/lib/logstash/"]
codec => json
type => "SuricataIDPS"
start_position => "beginning"
}
}
filter {
if [type] == "SuricataIDPS" {
date {
match => [ "timestamp", "ISO8601" ]
}
ruby {
code => "if event['event_type'] == 'fileinfo'; event['fileinfo']['type']=event['fileinfo']['magic'].to_s.split(',')[0]; end;"
}
}
if [src_ip] {
geoip {
source => "src_ip"
target => "geoip"
#database => "/usr/local/opt/logstash/libexec/vendor/geoip/GeoLiteCity.dat"
add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ]
add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}" ]
}
mutate {
convert => [ "[geoip][coordinates]", "float" ]
}
if ![geoip.ip] {
if [dest_ip] {
geoip {
source => "dest_ip"
target => "geoip"
#database => "/usr/local/opt/logstash/libexec/vendor/geoip/GeoLiteCity.dat"
add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ]
add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}" ]
}
mutate {
convert => [ "[geoip][coordinates]", "float" ]
}
}
}
}
}
output {
elasticsearch {
host => localhost
protocol => http
}
stdout {
codec => rubydebug
}
}
Why? What am I doing wrong?
Never mind - I've updated logstash and now it works fine

Resources