Reputation: 1063
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.
Upvotes: 4
Views: 8634
Reputation: 74
I kept running into this error too, because I had the metric filter formatted with double quotes on the outside like this.
FilterPattern: "{ ($.errorCode = '*UnauthorizedOperation') || ($.errorCode = 'AccessDenied*') }"
Strings that consist entirely of alphanumeric characters do not need to be quoted. Strings that have unicode and other characters such as ‘@,‘ ‘$,' ‘,' etc. must be enclosed in double quotes to be valid.
It didn't explicitly list the splat/wildcard * character, so I thought it would be OK inside single quotes, but it kept saying the metric filter pattern was bad because of the * in single quotes
I could have used single quotes around the outside of the pattern and double quotes around the strings inside, but I opted for escaping the double quotes like this instead.
FilterPattern: "{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }"
Upvotes: 0
Reputation: 140
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.
Upvotes: 8