Search code examples
amazon-web-servicesamazon-cloudwatch

Cloudwatch metric filter to do an AND query


I want to create a cloudwatch metric filter on a log group, I want the query to match two things in the JSON data. The data is json data coming from an application on EKS. I'm trying to basically match a string in the "log" part of the json and then do match kubernetes.namespace_name. How do I do this in a metric filter?

The idea is to have a metric filter and then an alert that uses that metric filter if the query in the metric filter catches an occurence.

I've read the docs, tried a bunch of stuff in the Cloudwatch log explorer, but just can't seem to get it. Logically this would work: (But it doesn't seem to work)

{ $.kubernetes.namespace_name = "production" && $.log = "*] Failed: *" }

Since this isn't working I just created a metric filter for:

] Failed:

But now I catch occurences of it in my staging Kubernetes namespace and on production.

Thanks for your help.

Update: Here is an example log entry:

{
  "time": "2024-03-11T00:00:10.411851489Z",
  "stream": "stdout",
  "_p": "F",
  "log": "[2024-03-11 00:00:10][XXXXXXXX] Failed: App\Jobs\RandomJob",
  "kubernetes": {
    "pod_name": "queue-worker-XXXXXXXX",
    "namespace_name": "production",
    "pod_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "host": "XXXXXXXX",
    "container_name": "supervisor-queue-worker",
    "docker_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "container_hash": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "container_image": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:v0.0.29"
  }
}

Solution

  • I've got a match using this filter pattern against the log sample you've provided, you can modify it further based on the need.

    {($.kubernetes.namespace_name = "production" && $.log = *Failed*)}
    

    Also, while testing filter pattern using custom log data, make sure to use unformatted JSON otherwise you won't get the results. So instead of a formatted JSON use the below unformatted data.

    { "time": "2024-03-11T00:00:10.411851489Z", "stream": "stdout", "p": "F", "log": "[2024-03-11 00:00:10][XXXXXXXX] Failed: App\Jobs\RandomJob", "kubernetes": { "pod_name": "queue-worker-XXXXXXXX", "namespace_name": "production", "pod_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "host": "XXXXXXXX", "container_name": "supervisor-queue-worker", "docker_id":"x", "container_hash":"x", "container_image":"x" } }