Compare condition for checking strings in watcher is not Working?

Hi Elastic Experts,

we have a compare condition as follows:

"condition": {
"compare": {
"ctx.payload.hits.hits.0._source.syslog_message": {
"gt": "lang.OutOfMemoryError:"
}
}
}

so here we want to check if syslog_message contains " lang.outOfMemoryError" , but we are getting alerts even when there is no "lang.OutOfMemoryError" ?

any Help on this would be great help!!

thanks,
Naveena K N

The compare condition works only for numerics.

You need to use painless, like this

return ctx.payload.hits.hits.get(0)._source.syslog_message.contains('lang.OutOfMemoryError')

--Alex

to clarify: strictly speaking, you can also use the condition for string comparison, but I think this is not what you are after, is it uses the java comparator logic

so we can use above statement for our usecase,
syslog_message.contains(' some text') will work right??

Thanks
Naveena K N

I suppose. you have not exactly mentioned what you are expecting to check with your condition, but the above examples checks if the first hit contains the specified string.

I am not sure if checking only the first hit is enough, and I am also not sure, why you dont write a query that checks for the syslog message including out of memory error, so there may be ways to improve this query, if you share it.

Hi @spinscale,

here is the watcher code to check Out of Memory Error in Server Logs running every 10seconds to check last 2 minute data:

{
  "trigger": {
    "schedule": {
      "interval": "10s"
    }
  },
  "input": {
    "search": {
      "request": {
        "search_type": "query_then_fetch",
        "indices": [
          "qa-mon-server-logs*"
        ],
        "types": [
          "doc"
        ],
        "body": {
          "query": {
            "range": {
              "logTimestamp": {
                "gte": "now-2m",
                "lt": "now"
              }
            }
          },
          "sort": [
            {
              "logTimestamp": {
                "order": "desc"
              }
            }
          ]
        }
      }
    }
  },
  "condition": {
    "script": {
      "source": "return ctx.payload.hits.hits.0._source.syslog_message.contains('OutOfMemoryError')",
      "lang": "painless"
    }
  },
  "actions": {
    "send_email": {
      "throttle_period_in_millis": 120000,
      "email": {
        "profile": "standard",
        "to": [
          "abc@gmail.com"
        ],
        "subject": "QA-mon-OutOfMemoryError",
        "body": {
          "text": "server path: {{ctx.payload.hits.hits.0._source.path}}              Error message: {{ctx.payload.hits.hits.0._source.syslog_message}} "
        }
      }
    }
  }
}

we would to like to hear any suggestions on improving this query!!

Thanks,
Naveena K N

Thanks for sharing the watch.

This can potentially miss hits. You are sorting by time, so the latest document is the first, and you are only checking the first document. If the second newest document contains that error, this will not be found.

You need to put the search for your OutOfMemoryError into the query (maybe using a match) query, and then it should be sufficient to check for the hit count in the condition.

Hi @spinscale,

can i Have something like below for checking all hits got in the context to check for "OutOfMemoryError"??

Thanks
Naveena

yes, you could, but again, you can solve this with a query, so why don't you go with that approach? It is easier and much faster.

--Alex

Hi @spinscale

i have query to fetch field containing 'OutOfMemoryError' in data arrived last 150 minute so the query is

"body": {
          "query": {
            "query_string" : {
            "default_field" : "syslog_message",
            "query" : "*OutOfMemoryError"
        },
        "range": {
              "logTimestamp": {
                "gte": "now-150m",
                "lt": "now"
              }
            }
          },
          "sort": [
            {
              "logTimestamp": {
                "order": "desc"
              }
            }
          ]
        }

but im getting parsing exception due to [query_string] malformed query, expected [END_OBJECT] but found [FIELD_NAME]

help me to modify this query to execute successfully!!

Thanks,
Naveena

you need to structure your queries differently. If you use a range and a query string query, you need to wrap it into a bool query, where the range query gets put into the filter clause and the query string query into the must clause.

Hope this helps!

--Alex

i framed it like this:

GET prod-sl1a-server-logs*/_search
{
  "query": { 
    "bool": { 
      "must": [
        { "match": { "syslog_message":   "java.lang.OutOfMemoryError" }}
      ],
      "filter": [
        { "range": { "logTimestamp": { "gte": "now-4d", "lt": "now"}}} 
      ]
    }
  }
}

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