logstash icon indicating copy to clipboard operation
logstash copied to clipboard

Doc: document the behavior of the if conditional when the field exists but is an empty string

Open danieledf opened this issue 3 years ago • 3 comments

Description:
The logstash documentation page about the if syntax states:

The expression if [foo] returns false when:

  • [foo] doesn’t exist in the event,
  • [foo] exists in the event, but is false, or
  • [foo] exists in the event, but is null

The last line should be changed into:

  • [foo] exists in the event, but is null (including empty strings like "foo": "")

URL: https://www.elastic.co/guide/en/logstash/current/event-dependent-configuration.html#conditionals

Validation The behavior can easily be validated with this logstash configuration file:

   input {
     heartbeat {
       message => '{"host": "test", "app": "test-me", "foo": "", "bar": " " }'
       interval => 5
     }
   }
   filter {
     json {
       source => "message"
     }
     if [foo] {
       mutate { add_tag => "foo is there" }
     } else {
       mutate { add_tag => "foo is NOT there" }
     }
     if [bar] {
       mutate { add_tag => "bar is there" }
     } else {
       mutate { add_tag => "bar is NOT there" }
     }
   }
   output {
     stdout { codec => rubydebug }
   }

which produces:

        [0] "foo is NOT there",
        [1] "bar is there"

danieledf avatar Jun 08 '22 09:06 danieledf

Source file: https://github.com/elastic/logstash/edit/main/docs/static/event-data.asciidoc (Lines 99+)

karenzone avatar Jun 08 '22 13:06 karenzone

@kares Quick validation, please? If all checks out, I'll make the fix or assist if @danieledf wants to make the fix. It's fun to see an issue turn into a github contribution, and I like helping people with that.

karenzone avatar Jun 08 '22 14:06 karenzone

LGTM but I think we can showcase all the cases - here's something that I had in mind:

The behavior can easily be validated with this logstash configuration file:

input {
  generator {
    message => '{ "numeric": 0, "empty": "", "space": " ", "falsy": false, "null": null }'
    count => 1
    codec => json
  }
}

filter {
  if [numeric] {
    mutate { add_tag => "numeric value is always truthy" }
  }

  if [space] {
    mutate { add_tag => "a non-empty string value is truthy" }
  }


  if [empty] {
    mutate { add_tag => "DOES NOT HAPPEN!" }
  } else {
    mutate { add_tag => "empty string value is NOT truthy" }
  }


  if ! [falsy] {
    mutate { add_tag => "false value is NOT truthy" }
  }

  if ! [null] {
    mutate { add_tag => "null value is NOT truthy" }
  }

  if [missing] {
    mutate { add_tag => "DOES NOT HAPPEN!" }    
  }
}

output {
  stdout {}
}

which produces an output similar to the following:

{
         "space" => " ",
      "sequence" => 0,
          "null" => nil,
         "falsy" => false,
       "numeric" => 0,
         "empty" => "",
          "tags" => [
        [0] "numeric value is always truthy",
        [1] "a non-empty string value is truthy",
        [2] "empty string value is NOT truthy",
        [3] "false value is NOT truthy",
        [4] "null value is NOT truthy"
    ]
}

kares avatar Jun 08 '22 14:06 kares