amazon-web-servicesaws-cloudformationamazon-cloudwatchlogsamazon-cloudwatch-metrics

How do I define an AWS MetricFilter FilterPattern to match a JSON-formatted log event in CloudWatch?


I am trying to define a metric filter, in an AWS CloudFormation template, to match JSON-formatted log events from CloudWatch. Here is an example of the log event:

{
    "httpMethod": "GET",
    "resourcePath": "/deployment",
    "status": "403",
    "protocol": "HTTP/1.1",
    "responseLength": "42"
}

Here is my current attempt to create a MetricFilter to match the status field using the examples given from the documentation here: FilterAndPatternSyntax

"DeploymentApiGatewayMetricFilter": {
  "Type": "AWS::Logs::MetricFilter",
  "Properties": {
    "LogGroupName": "/aws/apigateway/DeploymentApiGatewayLogGroup",
    "FilterPattern": "{ $.status = \"403\" }",
    "MetricTransformations": [
      {
        "MetricValue": "1",
        "MetricNamespace": "ApiGateway",
        "DefaultValue": 0,
        "MetricName": "DeploymentApiGatewayUnauthorized"
      }
    ]
  }
}

I get a "Invalid metric filter pattern" message in CloudFormation.

Other variations I've tried that didn't work:

"{ $.status = 403 }" <- no escaped characters
{ $.status = 403 } <- using a json object instead of string

I've been able to successfully filter for space-delimited log events using the bracket notation defined in a similar manner but the json-formatted log events don't follow the same convention.


Solution

  • Ran into the same problem and was able to figure it out by writing a few lines with the aws-cdk to generate the filter pattern template to see the difference between that and what I had.

    Seems like it needs each piece of criteria wrapped in parenthesis.

    - FilterPattern: '{ $.priority = "ERROR" && $.message != "*SomeMessagePattern*" }'
    + FilterPattern: '{ ($.priority = "ERROR") && ($.message != "*SomeMessagePattern*") }'
    

    It is unfortunate that the AWS docs for MetricFilter in CloudFormation have no examples of JSON patterns.