Format of ctx.results in an Action

I would like to send messages from the Alerting Plugin to another application that will read the results returned by the Alert.

The Action’s message reads as follows:

"{\"Name\": \"{{ctx.monitor.name}}\",
\"Message\": \"Sample Alert.\",
\"TriggerName\": \"{{ctx.trigger.name}}\",
\"Severity\": {{ctx.trigger.severity}},
\"PeriodStart\": \"{{ctx.periodStart}}\",
\"PeriodEnd\": \"{{ctx.periodEnd}}\",
\"TimeToLive\":180,

\"results\":
{{{ctx.results.0}}} }"

I can parse everything properly except for the results, which come back as “almost-JSON”:
{"Name": "Alert",
"Message": "Sample Alert.",
"TriggerName": "Testing",
"Severity": 1,
"PeriodStart": "2020-02-24T21:13:23.992Z",
"PeriodEnd": "2020-02-24T21:14:23.992Z",
"TimeToLive":180,

\"results\":
{_shards={total=30, failed=0, successful=30, skipped=0}, hits={hits=[], total=3, max_score=0.0}, took=16, timed_out=false, aggregations={aggregation={doc_count_error_upper_bound=0, sum_other_doc_count=0, buckets=[{doc_count=3, key=1.1.1.1}]}}} }"

Elasticsearch brings results back as JSON when I query it directly. I can also see results as JSON when I run the Monitor from Kibana.

Is there any way to have ctx.results come back as JSON? Or is there an easy way to turn it back into JSON if there isn’t? I have been searching around to see if there’s some Mustache thing I’m missing.

Thank you very much.

2 Likes

Did you find any solution to convert this in to json?

Thanks

Unfortunately, I have not found an easy way to transform this back into JSON.
What I ended up doing was having the service that gets sent the messages check for whether results are present. If so, it splits them out into another string, and then uses regular expressions to surround the key names with quotes, and then to surround the bucket key values with quotes as well. Fortunately, the only values that seem to be strings and not numbers are the names of the buckets, such as “1.1.1.1” in the example above, so the regular expressions can be a little simpler than if every value had to be in quotes.

The format of the results block we get from the alerts we create are nearly always the same, so we made some assumptions about the format, to make it easier to convert. These regular expressions are using some escape characters, since they were taken from strings used in .net core code.

I use one regular expression for the left hand side of the key value pairs:
[a-zA-Z0-9_]+(?==)
and replace it with
\"$&\"
to put it in quotes.
I then use another to handle the string values for the buckets’ keys:
(?<=\"key\"=).+?(?=(}, ?{\"doc_count|}]|, \"subaggregation))
It looks for key, then matches nearly anything after the equals sign, then ends the match when it finds either
"}", "}, {\"doc_count", or "\"subaggregation"
.
And then replace the value with the same match in quotes.
\"$&\"
At the end of it all, all the equals signs are replaced with colons. Ideally, it should only be done to equals signs that are outside of the quotation marks, and not inside the values for the keys.

So far, this has been working, but it would be much nicer if the JSON returned by Elasticsearch could be left as JSON instead of turning into this other format. Does anyone know if this format has a name?

Thank you very much.

Mustache as the only choice for the output of alerts cripples so much of the power of the feature.
Really need a more powerful template that can call functions, OR a script step to transform / supplement / output the results.
Having to output JSON via a template like this is very ordinary. Not having anyway at all to modify or format the values from results is very ordinary.

You should be able to do this to return it in json format

{{#toJson}}ctx.results.0{{/toJson}}

I will have to try this! Thank you for posting.
I will reply back when I get a chance to try- if it works, this will be a huge time saver and reduction in complexity! Thank you very much.

Wow, thank you! It looks like this might be working! Thank you very much again for pointing this out!