Conditionals: check field type

With the following logstash config:

filter
{
	if [client]
	{
		if [ip] in [client]
		{}
        }
}

Which is converted as:

if (((x = event["[client]"]; x.respond_to?(:include?) && x.include?(event["[ip]"])))) # if [ip] in [client]

When I enter the following input data to Logstash '{"client": ""}',it throws error (then stop the daemon which is not really cool in production...):

TypeError: can't convert nil into String

Hence my question, is it possible to check if the field is a string, or an object? (or a good way to validate/sanitize input data).

1 Like

I would like to do this too. I assume this may be a ruby filter, but I can't find any examples. I have a field that sometimes comes over as an array, sometimes it's a hash. I need to be able to test the field's type or logstash will crash trying to split a hash.

@ebuildy you can do something like:

filter {
  if [client] {
    if [client][ip] {
      # ...
    }
  }
}

@pixelrebel if your case you might need a rubyfilter, yes:

input {
  stdin { codec => json }
}
filter {
  ruby { code => 'case event.get("[client]")
                  when Hash
                    event.tag("hash")
                  when Array
                    event.tag("array")
                  else
                    event.tag("oh no")
                  end'
  }
}
output { stdout { codec => rubydebug } } 

output:

{"client": []}
{
    "@timestamp" => 2016-12-22T09:39:04.561Z,
      "@version" => "1",
          "host" => "Joaos-MBP-5.lan",
        "client" => [],
          "tags" => [
        [0] "array"
    ]
}
{"client": {}}
{
    "@timestamp" => 2016-12-22T09:39:13.829Z,
      "@version" => "1",
          "host" => "Joaos-MBP-5.lan",
        "client" => {},
          "tags" => [
        [0] "hash"
    ]
}
{"client": ""}
{
    "@timestamp" => 2016-12-22T09:39:20.005Z,
      "@version" => "1",
          "host" => "Joaos-MBP-5.lan",
        "client" => "",
          "tags" => [
        [0] "oh no"
    ]
}
2 Likes

@jsvd You are an example of everything that is right in this world! Thanks so much for this!!!

And, for those playing on 2.x like myself, this is how it's done the old-fashioned way:

filter {
  ruby { code => 'case event["client"]
                  when Hash
                    event.tag("hash")
                  when Array
                    event.tag("array")
                  else
                    event.tag("oh no")
                  end'
  }
}