Need help with watcher to send the correct fields of result in the email

Hello Team,

I am trying to setup a watcher for uptime using heartbeat to trigger a mail with proper message. I've got the watcher setup and is working but the issue is that one triggered mail has more than 10 alerts so the message that I get has 10 values of the same variables in the email body. I am pasting my code here if anyone wants to have a look at it.

{
	"metadata": {
		"color": "red"
	},
  "trigger": {
    "schedule": {
      "interval": "5s"
    }
  },
  "input": {
    "search": {
      "request": {
        "search_type": "query_then_fetch",
        "indices": ["heartbeat*"],
        "types": [],
        "body": {
          "query": {
            "bool": {
              "must": [
                {
                  "query_string": {
                    "query": "monitor.status:down"
                  }
                },
                {
                  "range": {
                    "@timestamp": {
                      "gte": "now-5m"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  },
  "condition": {
    "compare": {
      "ctx.payload.hits.total": {
        "gt": 0
      }
    }
  },
  "actions": {
    	"globo": {
    		"throttle_period": "15s",
    		"email": {
    			"to": "abc@gmail.com",
    			"subject": "Encountered {{ctx.payload.hits.total}} errors",
    			"body": "{{#ctx.payload.hits.hits}}{{_source.beat.hostname}}{{/ctx.payload.hits.hits}} is unable to connect to {{#ctx.payload.hits.hits}}{{_source.http.url}}{{/ctx.payload.hits.hits}}",
    			"attachments": {
    				"attached_data": {
    					"data": {
    						"format": "json"
    					}
    				}
    			},
    			"priority": "high"
    		}
    	}
  }
} 

The body of the mail that I am getting is given below.

host1 host1 host1 ..... host1 is unable to connect to url1 url1 url1 ..... url1

Could someone please help me in writing the watcher such that the body has just the urls that it cannot connect just once so that it looks meaningful.

Hey,

you need to change your query, and not check out single documents being returned from a search, but use a terms aggregation on the host and the url.

See https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-bucket-terms-aggregation.html

--Alex

1 Like

Thanks Alex,

I shall try the suggested method. Once again thanks alot for your response.

BR
Giridhar

Hello Alex,

I tried the solution you suggested and it worked . I am still stuck with extraction of the fields extraction. I am getting two things in the buckets. (i) The monitor name (ii) http which is not required. I am pasting my code here. could you please help me with some suggestions.

{
	"metadata": {
		"color": "red"
	},
  "trigger": {
    "schedule": {
      "interval": "60s"
    }
  },
  "input": {
    "search": {
      "request": {
        "search_type": "query_then_fetch",
        "indices": [
          "heartbeat-*"
        ],
        "rest_total_hits_as_int": true,
        "body": {
          "size": 0,
          "query": {
            "bool": {
              "must": [
                {
                  "term": {
                    "monitor.status": {
                      "value": "down"
                    }
                  }
                }
              ],
              "filter": [
                {
                  "range": {
                    "@timestamp": {
                      "from": "now-1m"
                    }
                  }
                }
              ]
            }
          },
          "aggregations": {
            "by_monitors": {
              "terms": {
                "field": "monitor.name",
                "size": 10,
                "min_doc_count": 1
              }
            }
          }
        }
      }
    }
  },
  "condition": {
    "compare": {
      "ctx.payload.hits.total": {
        "gt": 1
      }
    }
  },
  "actions": {
    	"globo": {
    		"throttle_period": "15s",
    		"email": {
    			"to": "abc@gmail.com",    			      ],
    			"subject": "Encountered {{ctx.payload.hits.total}} errors",
    			"body": "{{ctx.payload.aggregations.buckets.key}} is unable to connect other regions",
    			"priority": "high"
    		}
    	}
  }
}

ctx.payload.aggregations.buckets.key is expanding to nothing. I even tried with {{key}} but no luck. Could you please help me with some pointers to send a meaningful message in the email.

The response looks like below

"aggregations": {
          "by_monitors": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "doc_count": 18,
                "key": "http"
              },
              {
                "doc_count": 2,
                "key": "abc_monitor_name"
              }
            ]
          }
        }

The body of the email is given below

email": {
          "message": {
            "id": "globo__inlined__36213290-2bdd-4c13-86db-7104c3d70b3d-2020-05-20T12:46:45.386Z",
            "priority": "high",
            "sent_date": "2020-05-20T12:46:45.389Z",
            "to": "abc@gmail.com",
            "subject": "Encountered 20 errors",
            "body": {
              "text": " is unable to connect other regions"
            }
          }

Your help will be highly appreciated.

Thanks
Giridhar

Hello Team,

Could someone please help me with some pointers to loop over the buckets and send an email with the variable key to make it meaningful.

Thanks
Giridhar

you need to loop through the buckets, like this

{{#ctx.payload.aggregations.by_monitors.buckets}}
Key is {{key}} and doc_count {{doc_count}}
{{/ctx.payload.aggregations.by_monitors.buckets}}

hope this helps

1 Like

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