LogStash Conf | Drop Empty Lines

The contents of LogStash's conf file looks like this:

input {
    beats {
        port => 5044
    }
	
	file {
		path => "/usr/share/logstash/iway_logs/*"		
		start_position => "beginning"
		sincedb_path => "/dev/null"
		#ignore_older => 0
		codec => multiline {
         pattern => "^\[%{NOTSPACE:timestamp}\]"
         negate => true
         what => "previous"
		 max_lines => 2500
        }
  }
}

filter {	
	
	grok {
		match => { 	"message" => 
			['(?m)\[%{NOTSPACE:timestamp}\]%{SPACE}%{WORD:level}%{SPACE}\(%{NOTSPACE:entity}\)%{SPACE}%{GREEDYDATA:rawlog}'			
			]
		}
	}
					
	date {
	  match => [ "timestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS"]
	  target => "@timestamp"
	}
		
	grok {
		match => { "entity" => 			['(?:W.%{GREEDYDATA:channel}:%{GREEDYDATA:inlet}:%{GREEDYDATA:listener}\.%{GREEDYDATA:workerid}|W.%{GREEDYDATA:channel}\.%{GREEDYDATA:workerid}|%{GREEDYDATA:channel}:%{GREEDYDATA:inlet}:%{GREEDYDATA:listener}\.%{GREEDYDATA:workerid}|%{GREEDYDATA:channel}:%{GREEDYDATA:inlet}:%{GREEDYDATA:listener}|%{GREEDYDATA:channel})']
		}
	}
	
	dissect {
        mapping => {
            "[log][file][path]" => "/usr/share/logstash/iway_logs/%{serverName}#%{configName}#%{?ignore}.log"
        }
    }
	
}

output {
    elasticsearch {
        hosts => "${ELASTICSEARCH_HOST_PORT}"
		index => "iway_"
        user => "${ELASTIC_USERNAME}"
        password => "${ELASTIC_PASSWORD}"
        ssl => true
        ssl_certificate_verification => false
        cacert => "/certs/ca.crt"
    }
}

As one can make out, the idea is to parse a custom log employing multiline extraction. The extraction does its job. The log occasionally contains an empty first line. So:


[2022-11-29T12:23:15.073] DEBUG (manager) Generic XPath iFL functions use full XPath 1.0 syntax
[2022-11-29T12:23:15.074] DEBUG (manager) XPath 1.0 iFL functions use iWay's full syntax implementation

which naturally is causing Kibana to report an empty line:

enter image description here

In an attempt to supress this line from being sent to ES, I added the following as a last filter item:

if ![message] {
  drop { }
}
	
if [message] =~ /^\s*$/ {
  drop { }
}

The resulting JSON payload to ES:

{
	"@timestamp": [
		"2022-12-09T14:09:35.616Z"
	],
	"@version": [
		"1"
	],
	"@version.keyword": [
		"1"
	],
	"event.original": [
		"\r"
	],
	"event.original.keyword": [
		"\r"
	],
	"host.name": [
		"xxx"
	],
	"host.name.keyword": [
		"xxx"
	],
	"log.file.path": [
		"/usr/share/logstash/iway_logs/localhost#iCLP#iway_2022-11-29T12_23_33.log"
	],
	"log.file.path.keyword": [
		"/usr/share/logstash/iway_logs/localhost#iCLP#iway_2022-11-29T12_23_33.log"
	],
	"message": [
		"\r"
	],
	"message.keyword": [
		"\r"
	],
	"tags": [
		"_grokparsefailure"
	],
	"tags.keyword": [
		"_grokparsefailure"
	],
	"_id": "oRc494QBirnaojU7W0Uf",
	"_index": "iway_",
	"_score": null
}

While this does drop the empty first line, it also unfortunately interferes with the multiline operation on other lines. In other words, the multiline operation does not work anymore. What am I doing incorrectly?

I use this to drop empty messages

  # drop logs without message
  if [message] == "" { drop{} }

@RudyStolds Thanks but the filter to drop empty lines (I tried a similar filter) works already at the cost of messed up multiline parsing...

Your multiline expression will append blank lines to the previous line with a timestamp. /^\s*$/ matches a blank line within a multiline message. If you just want to drop messages that only contain whitespace then try /\A\s*\Z/.

2 Likes

Can you share an example of this? This should not happen, the multiline codec happens in the input block of your pipeline, the drop filter happens in the filter block, after your multiline event was already created.

@Badger Thank you! That was it. The empty line is dropped.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.