# Find the hosts whose hits are 5% more/less than the mean of hits of all hosts

**URL:** <https://discuss.elastic.co/t/find-the-hosts-whose-hits-are-5-more-less-than-the-mean-of-hits-of-all-hosts/137531>\
**Category:** Elasticsearch\
**Tags:** elastic-stack-alerting\
**Created:** [June 27, 2018, 3:05am UTC](https://discuss.elastic.co/t/find-the-hosts-whose-hits-are-5-more-less-than-the-mean-of-hits-of-all-hosts/137531 "2018-06-27T03:05:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![naveensrikanth](https://avatars.discourse-cdn.com/v4/letter/n/ee7513/32.png) [@naveensrikanth](https://discuss.elastic.co/u/naveensrikanth)\
**Post date:** [June 27, 2018, 3:05am UTC](https://discuss.elastic.co/t/find-the-hosts-whose-hits-are-5-more-less-than-the-mean-of-hits-of-all-hosts/137531/1 "2018-06-27T03:05:13Z")

</div>

Hi,

I am new to ElasticSearch watcher scripts. Can you help me with the below problem:

We get hits/transactions to 50 hosts/nodes. We would like to send an email notification with the host names whose hits are 5% more or less than the average hits across all hosts.

Thanks  
NS

---

<div class="post-metadata">

**Author:** ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)\
**Post date:** [June 27, 2018, 7:14am UTC](https://discuss.elastic.co/t/find-the-hosts-whose-hits-are-5-more-less-than-the-mean-of-hits-of-all-hosts/137531/2 "2018-06-27T07:14:08Z")

</div>

Hey,

before writing any watch the main question is, can you write the correct queries. This is actually not a watcher issue at all, but more a question of data exploration.

A query could be a [avg aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/6.3/search-aggregations-metrics-avg-aggregation.html) in the transaction field

A second aggregation in that query could be the transactions grouped by host using a `terms` aggregation.

Then you could use the condition with a painless script to check if there are hosts that differ by about %5.

In general, I would be careful with averages due to it's outlier specific nature. Maybe percentiles and using a percentile agg makes sense in your case, but this is hard to tell from the outside.

---

<div class="post-metadata">

**Author:** ![naveensrikanth](https://avatars.discourse-cdn.com/v4/letter/n/ee7513/32.png) [@naveensrikanth](https://discuss.elastic.co/u/naveensrikanth)\
**Post date:** [June 27, 2018, 5:56pm UTC](https://discuss.elastic.co/t/find-the-hosts-whose-hits-are-5-more-less-than-the-mean-of-hits-of-all-hosts/137531/3 "2018-06-27T17:56:34Z")

</div>

I would like to monitor the hits every 1 min so I need a watcher.

Is this approach correct ?

1. I will create 2 inputs (chained).
2. First returns total no.of hits in 1 min --- ctx.payload.hits.total gives that.
3. Second I create buckets (keys are hostnames). then i get the document count in each bucket (values are document count)
4. create a painless script to check if there are any hosts that differ by 5%

And I got stuck at the buckets. How do I loop through the buckets and get the count of each bucket.

Here is my script:

```
{
    "trigger": {
      "schedule": {
        "interval": "1m"
      }
    },
    "input": {
    "chain": {
    "inputs": [
      {
      "all":{
          "search": {
            "request": {
              "search_type": "query_then_fetch",
              "indices": [
                "90183*"
              ],
              "types": [],
              "body": {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "range": {
                          "@timestamp": {
                            "from": "now-1m",
                            "to": null,
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                          }
                        }
                      }
                    ],
                    "should": [
                      {
                        "range": {
                          "total_flow_time": {
                            "from": 1,
                            "to": null,
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 2
                          }
                        }
                      }
                    ],
                    "disable_coord": false,
                    "adjust_pure_negative": true,
                    "minimum_should_match": "1",
                    "boost": 1
                  }
                },
                "ext": {}
              }
            }
          }
        }
      },
      {
      "per_host":{
          "search": {
            "request": {
              "search_type": "query_then_fetch",
              "indices": [
                "90183*"
              ],
              "types": [],
              "body": {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "range": {
                          "@timestamp": {
                            "from": "now-1m",
                            "to": null,
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                          }
                        }
                      }
                    ],
                    "should": [
                      {
                        "range": {
                          "total_flow_time": {
                            "from": 1,
                            "to": null,
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 2
                          }
                        }
                        }
                    ],
					"aggs": {
					"origin": {
					"terms": {
					"field": "host.keyword"
						}
					  }
					},
					"extract": [
					"aggregations.origin.buckets.key",
				        "aggregations.origin.buckets.sum_bucket"
					],
                    "disable_coord": false,
                    "adjust_pure_negative": true,
                    "minimum_should_match": "1",
                    "boost": 1
                  }
                },
                "ext": {}
              }
            }
          }
        }
    }
    ]  
    }
    },
    "condition": {
      "script": "return true"
     },
    "actions": {
      "send_email": {
        "email": {
          "profile": "standard",
          "attachments": {
            "attached_data.txt": {
              "data": {
                "format": "json"
              }
            }
          },
          "priority": "high",
          "to": [
            "xyz@gmail.com"
          ],
          "subject": " {{ctx.payload.all.hits.total}} ",
          "body": {
            "html": "{{ctx.payload.aggregations}} "
          }
        }
      }
  }
}
```

---

<div class="post-metadata">

**Author:** ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)\
**Post date:** [June 29, 2018, 8:47am UTC](https://discuss.elastic.co/t/find-the-hosts-whose-hits-are-5-more-less-than-the-mean-of-hits-of-all-hosts/137531/4 "2018-06-29T08:47:23Z")

</div>

I do not see a script in that watch, just an always true condition.

Please take some time and check the [examples repository](https://github.com/elastic/examples/tree/master/Alerting) for some more examples using painless in conditions.

In general, you can use painless to check lists using java lambdas

```auto
ctx.payload.aggregations.my_bucket.buckets.stream().anyMatch(b -> b.path_to_value_to_check < threshold*1.05 && b.path_to_value_to_check > threshold*0.95)

```

The threshold needs to be extracted from the payload as well.

Hope this helps as a getting started point!

--Alex

---

<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:** [July 27, 2018, 8:47am UTC](https://discuss.elastic.co/t/find-the-hosts-whose-hits-are-5-more-less-than-the-mean-of-hits-of-all-hosts/137531/5 "2018-07-27T08:47:30Z")

</div>

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