# Dynamically build the conditional statement from field value

**URL:** <https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305>\
**Category:** Logstash\
**Created:** [July 24, 2017, 10:19am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305 "2017-07-24T10:19:43Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![staodd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/staodd/32/24509_2.png) [@staodd](https://discuss.elastic.co/u/staodd)\
**Post date:** [July 24, 2017, 10:19am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/1 "2017-07-24T10:19:43Z")

</div>

Is it possible to use the value of one field in a json document as an argument to a conditional statement?

f.ex:

```javascript
{
value1: "test"
value2: "This is a string with the value test included"
}

if value2 =~ /value1/ then {
     string contained "test"
 }

```

Continuing on the same idea. Would it be possible to have a regex as the field value:

```javascript
{
value1:"test|example"
value2:"String with the word example included"
}

if value" =~ /value1/ then {
    string contained either "test" or "example"
}

```

Or is there any other way to dynamically build the conditional when you don't know the condition before the message has been received for parsing?

Haven't looked into the ruby code options.. Could that be used to solve it?  
Have played around a bit with it, and not been able to sort it out yet... so if anyone has any suggestions.

---

<div class="post-metadata">

**Author:** ![Prashant\_Agrawal](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/prashant_agrawal/32/74982_2.png) [@Prashant\_Agrawal](https://discuss.elastic.co/u/Prashant_Agrawal)\
**Post date:** [July 24, 2017, 10:26am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/2 "2017-07-24T10:26:38Z")

</div>

Yes you can use the field value to check for another string or value. So here when you are referring the value from field you need to access like

> [@staodd](#):
>
> if [value2] =~ [value1] {  
> // do what ever operation you want here.  
> }

instead of

> [@staodd](#):
>
> if value2 =~ /value1/ then {

---

<div class="post-metadata">

**Author:** ![staodd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/staodd/32/24509_2.png) [@staodd](https://discuss.elastic.co/u/staodd)\
**Post date:** [July 24, 2017, 11:08am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/3 "2017-07-24T11:08:29Z")

</div>

Still can't make it work.  
Did a simple config: (your forgot to enclose the regexp in //, wont run if not)

```javascript
input {
  stdin {
  }
}
filter {
  mutate {
    add_field => {"value2" => "lookfor"}
  }
}
filter {
  if [message] =~ /[value2]/ {
    mutate { add_field => { "hit" => true } }
  }
}
output {
  stdout {
    codec => rubydebug
  }
}

```

This should read from stdin, and set the field hit to true if it finds the lookfor string in the input.  
BUT, no matter what input i give, the resulting output will contain the hit:true field:

```json
teststring
{
           "hit" => "true",
    "@timestamp" => 2017-07-24T11:02:46.666Z,
        "value2" => "lookfor",
      "@version" => "1",
          "host" => "XXXXXX",
       "message" => "teststring"
}
lookfor
{
           "hit" => "true",
    "@timestamp" => 2017-07-24T11:02:59.976Z,
        "value2" => "lookfor",
      "@version" => "1",
          "host" => "XXXXXX",
       "message" => "lookfor"
}

```

Seems to me it checks if there exist a field with the name value2 instead, which ofc always are there.

---

<div class="post-metadata">

**Author:** ![Prashant\_Agrawal](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/prashant_agrawal/32/74982_2.png) [@Prashant\_Agrawal](https://discuss.elastic.co/u/Prashant_Agrawal)\
**Post date:** [July 25, 2017, 4:46am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/4 "2017-07-25T04:46:14Z")

</div>

> [@staodd](#):
>
> if [message] =~ /[value2]/ {

You dont need / here just make condition as :  
if [message] =~ [value2] {

Also instead of using 2 filter add everything in one filter as below :

```
filter {
  mutate {
    add_field => {"value2" => "lookfor"}
  }
 if [message] =~ [value2] {
    mutate { add_field => { "hit" => true } }
  }
}

```

---

<div class="post-metadata">

**Author:** ![staodd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/staodd/32/24509_2.png) [@staodd](https://discuss.elastic.co/u/staodd)\
**Post date:** [July 25, 2017, 6:40am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/5 "2017-07-25T06:40:41Z")

</div>

As i said, it won't run without the // :

```javascript
08:17:52.807 [LogStash::Runner] ERROR logstash.agent - Cannot create pipeline {:reason=>"Expected one of #, \", ', / at line 13, column 19 (byte 133) after filter {\n if [message] =~ "}

```

Reason for splitting is just that the first filter is to run on another machine in the pipeline, so i keep them separated for clarity while testing.

And if i just use the filter as you show it behaves in the same way, always adding hit =\> "true" to the final document printed to stdout:

```javascript
input {
  stdin {
  }
}
filter {
  mutate {
    add_field => {"value2" => "lookfor"}
  }
  if [message] =~ /[value2]/ {
    mutate { add_field => { "hit" => true } }
  }
}
output {
  stdout {
    codec => rubydebug
  }
}

```

Running this:

```auto
08:36:07.748 [Api Webserver] INFO logstash.agent - Successfully started Logstash API endpoint {:port=>9601}
This should not add the hit
{
           "hit" => "true",
    "@timestamp" => 2017-07-25T06:36:23.847Z,
        "value2" => "lookfor",
      "@version" => "1",
          "host" => "host",
       "message" => "This should not add the hit"
}
this should add hit as it contains lookfor
{
           "hit" => "true",
    "@timestamp" => 2017-07-25T06:36:38.114Z,
        "value2" => "lookfor",
      "@version" => "1",
          "host" => "host",
       "message" => "this should add hit as it contains lookfor"
}

```

Running Logstash 5.5.0-1.

---

<div class="post-metadata">

**Author:** ![magnusbaeck](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/magnusbaeck/32/44943_2.png) [@magnusbaeck](https://discuss.elastic.co/u/magnusbaeck)\
**Post date:** [July 25, 2017, 9:24pm UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/6 "2017-07-25T21:24:10Z")

</div>

> ```
> if [message] =~ /[value2]/ {
> 
> ```

This definitely won't work but try this instead:

```
if [message] =~ /%{value2}/ {

```

If that doesn't work either you may have to use a ruby filter.

---

<div class="post-metadata">

**Author:** ![staodd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/staodd/32/24509_2.png) [@staodd](https://discuss.elastic.co/u/staodd)\
**Post date:** [July 26, 2017, 7:54am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/7 "2017-07-26T07:54:06Z")

</div>

Didn't get lucky on that one either...  
But look on the bright side, this gives me an excuse to start learning ruby as well 😄  
Think it should be possible to patch something together using the code option in the filter.

Thanks for the suggestions.

---

<div class="post-metadata">

**Author:** ![staodd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/staodd/32/24509_2.png) [@staodd](https://discuss.elastic.co/u/staodd)\
**Post date:** [July 26, 2017, 10:00am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/8 "2017-07-26T10:00:23Z")

</div>

In case others are looking for something along the same lines:

```javascript
filter {
	mutate {add_field => {"value2" => "lookfor"}}
	ruby {
		code => "if (event.get('message') =~ /#{event.get('value2')}/i)
	          event.set('hit','true'); end" 
	}
}

```

This seems to do the trick. Only weird thing now is why can't it be a one-liner. If i try:

```javascript
code => "if (event.get('message') =~ /#{event.get('value2')}/i) event.set('hit','true'); end"

```

it crashes logstash.. But i might have to blame that on my lacking ruby skills 😠

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [August 23, 2017, 10:00am UTC](https://discuss.elastic.co/t/dynamically-build-the-conditional-statement-from-field-value/94305/9 "2017-08-23T10:00:41Z")

</div>

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