32

I have JSON strings upload to AWS Cloudwatch logs and am now trying to write a filter that generates metrics from those logs.

Suppose I have JSON like the following:

{"test_results": [{"result": "success", "name": "foo", "nr_failed": 0}, {"result": "failure", "name": "bar", "nr_failed": 3}]}

The AWS Cloudwatch log metrics filter allows me to specify a pattern like the following:

{ $.test_results[0].result = "failure" }

The above means, "match the entire line if the zeroth entry in the value of 'test_results' has a value of 'failure' for its 'result' field". In this particular case, the zeroth entry had a result of 'success', so it wouldn't match. But this next line would match:

{ $.test_results[1].result = "failure" }

Now suppose I want to match the whole line if any of the entries had a value of 'failure'. Basically, I want to do this:

{ $.test_results[*].result = "failure" }

But the pattern syntax doesn't seem to allow wildcards in the array index. How can I match lines where any of the result values are "failure" ?

Alternatively, how could I pick out the numeric values for all the "nr_failed" fields in the "test_results" array and create metrics from those?

Paolo
  • 21,270
  • 6
  • 38
  • 69
Steve Leibman
  • 621
  • 7
  • 7

2 Answers2

0

Indeed, according to the official AWS docs there's no syntax to address your issue explicitly:

The elements in arrays follow a zero-based numbering system, meaning that the first element in the array is element 0, the second element is element 1, and so on. Enclose elements in brackets ("[]").

However there's a little hack that might be helpful for somebody who also looks for the solution. You might build query with OR (||) operator to check every item in the list:

{$.test_results[0].result = failure || $.test_results[1].result = failure}

Moreover, it does work even if actual list length is less than number of conditional arguments. So, we have to set the upper limit for the length of test_results and generate query for that.

Let's say the length of test_results would be less than 10 elements then let's generate the query with Bash:

#!/bin/bash
echo -n "{"; for i in {0..10}; do echo -n "$.test_results[$i].result = failure"; test "$i" -ne "10" && echo -n " || "; done; echo "}"

But let you know: the length of query should be less or equal to 1024 chars to work.

mdraevich
  • 116
  • 6
-2

I found just using "failure" as a metric filter worked, it isn't particularly elegant but it might work for you.

enter image description here

Baza86
  • 1,458
  • 1
  • 7
  • 10