Creating a watcher to check for no data in all the indices

Hi Team,

I am trying to create a watcher in our elastic cloud 7.17.3 env to get an alert when there is no data in the indices. The problem here is i have more than 50 indices in the cluster and it will be difficult to create a individual alert for each index. So i thought of using a filters aggregation and created filters for all the 50 indices using application name in each index.

Now i will get if any application index is having 0 count. Now i need to use a condition to check the buckets which is having zero count and return them in the watcher body. Could you please let me know how can i achieve this. I have tried array comparison but the resulting output from filters aggregation is not an array it's a json object.

Thanks in advance.

Hello,

Yes, the approach is the one you just described. You can use aggregations and then the ouput will be a bucket (type object). To apply the conditions, you can use the paintless script that will browse your bucket. And to perhaps also use the transformations that can make it easier for you to format the email template as a mustache.

Example watcher

Hi @ahmed_charafouddine ,

I have tried to create the script to pick the filters buckets which has zero values but i am getting compile errors. Could you please help me with the script to fetch the buckets which has zero values.

My Query:

GET data-*/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "@timestamp": {
              "gt": "now-3h"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "applications": {
      "filters": {
        "filters": {
          "Application1": {
            "match": {
              "fields.applicationName": "Application1"
            }
          },
          "Application2": {
            "match": {
              "fields.applicationName": "Application2"
            }
          },
          "Application3": {
            "match": {
              "fields.applicationName": "Application3"
            }
          },
          "Application4": {
            "match": {
              "fields.applicationName": "Application4"
            }
          }
        }
      }
    }
  }
}

o/p:
  "aggregations" : {
    "applications" : {
      "buckets" : {
        "Application1" : {
          "doc_count" : 7991
        },
        "Application2" : {
          "doc_count" : 340743
        },
        "Application3" : {
          "doc_count" : 0
        },
        "Application4" : {
          "doc_count" : 0
        }
      }
    }
}

Thanks in Advance

Hi,

You can try a few things like this.

"condition": {
    "script": {
      "source": """
        def apps = ctx.payload.aggregations.applications.buckets;
        if (apps.size() == 0 ) return false;
        return apps.stream().anyMatch( app -> app.doc_count == 0 );
      """,
      "lang": "painless"
    }
  },

Do not hesitate to consult this link. You will find many examples to inspire you

https://github.com/elastic/examples/blob/master/Alerting/Sample%20Watches/port_scan/scripts/condition.json

Hi @ahmed_charafouddine ,

I have tried the script but getting an error at stream(). I think the o/p of my query was a object but not an array in the aggregations.

Error:

"exception": {
  "type": "script_exception",
  "reason": "runtime error",
  "script_stack": [
    "return ctx.payload.aggregations.applications.buckets.stream().anyMatch( ",
    "                                                    ^---- HERE"
  ],

Hi @ahmed_charafouddine ,

I have found the solution for JSON object in another topic and it worked.

"condition": {
      "script": {
        "source": """
ctx.payload.aggregations.applications.buckets.entrySet().stream().filter(e-> e.value.doc_count == 0).count() > 0
"""
      }
    },
    "transform" : {
      "script":
      """
        return [
          'only_ones': ctx.payload.aggregations.applications.buckets.entrySet().stream()
          .filter(e-> e.value.doc_count == 0).map(e-> [ 'key': e.key, 'value': e.value.doc_count ]).collect(Collectors.toList())
          ]
      """
    },

Thankyou..!!!

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