Skip to content

Commit c89afe3

Browse files
authored
feat(logs): support regex patterns for JSON Metrics filters (#30741)
### Issue # (if applicable) Closes #30451 ### Reason for this change Support Regex in filter functions for JSON ### Description of changes Adding a new JSONPattern factory that uses `%` instead of `"` to support the regex pattern. ### Description of how you validated changes I tried it in our own CDK code. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 39151d0 commit c89afe3

File tree

6 files changed

+50
-4
lines changed

6 files changed

+50
-4
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"MetricFilter1B93B6E5": {
1212
"Type": "AWS::Logs::MetricFilter",
1313
"Properties": {
14-
"FilterPattern": "{ $.latency = \"*\" }",
14+
"FilterPattern": "{ ($.latency = \"*\") && ($.message = %bind: address already in use%) }",
1515
"LogGroupName": {
1616
"Ref": "LogGroupF5B46931"
1717
},

packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ class MetricFilterIntegStack extends Stack {
1515
metricNamespace: 'MyApp',
1616
metricName: 'Latency',
1717
filterName: 'MyFilterName',
18-
filterPattern: FilterPattern.exists('$.latency'),
18+
filterPattern: FilterPattern.all(
19+
FilterPattern.exists('$.latency'),
20+
FilterPattern.regexValue('$.message', '=', 'bind: address already in use'),
21+
),
1922
metricValue: '$.latency',
2023
});
2124
/// !hide

packages/aws-cdk-lib/aws-logs/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ and then descending into it, such as `$.field` or `$.list[0].field`.
295295

296296
* `FilterPattern.stringValue(field, comparison, string)`: matches if the given
297297
field compares as indicated with the given string value.
298+
* `FilterPattern.regexValue(field, comparison, string)`: matches if the given
299+
field compares as indicated with the given regex pattern.
298300
* `FilterPattern.numberValue(field, comparison, number)`: matches if the given
299301
field compares as indicated with the given numerical value.
300302
* `FilterPattern.isNull(field)`: matches if the given field exists and has the
@@ -324,6 +326,7 @@ const pattern = logs.FilterPattern.all(
324326
logs.FilterPattern.booleanValue('$.error', true),
325327
logs.FilterPattern.numberValue('$.latency', '>', 1000),
326328
),
329+
logs.FilterPattern.regexValue('$.message', '=', 'bind address already in use'),
327330
);
328331
```
329332

packages/aws-cdk-lib/aws-logs/lib/pattern.ts

+32-1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,27 @@ export class FilterPattern {
116116
return new JSONNumberPattern(jsonField, comparison, value);
117117
}
118118

119+
/**
120+
* A JSON log pattern that compares against a Regex values.
121+
*
122+
* This pattern only matches if the event is a JSON event, and the indicated field inside
123+
* compares with the regex value.
124+
*
125+
* Use '$' to indicate the root of the JSON structure. The comparison operator can only
126+
* compare equality or inequality.
127+
*
128+
* For more information, see:
129+
*
130+
* https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html
131+
*
132+
* @param jsonField Field inside JSON. Example: "$.myField"
133+
* @param comparison Comparison to carry out. Either = or !=.
134+
* @param value The regex value to compare to.
135+
*/
136+
public static regexValue(jsonField: string, comparison: string, value: string): JsonPattern {
137+
return new JSONRegexPattern(jsonField, comparison, value);
138+
}
139+
119140
/**
120141
* A JSON log pattern that matches if the field exists and has the special value 'null'.
121142
*
@@ -225,6 +246,16 @@ class JSONStringPattern extends JsonPattern {
225246
}
226247
}
227248

249+
/**
250+
* A regex comparison for JSON patterns
251+
*/
252+
class JSONRegexPattern extends JsonPattern {
253+
public constructor(jsonField: string, comparison: string, value: string) {
254+
// No validation, we assume these are generated by trusted factory functions
255+
super(`${jsonField} ${comparison} %${value}%`);
256+
}
257+
}
258+
228259
/**
229260
* A number comparison for JSON values
230261
*/
@@ -260,7 +291,7 @@ class JSONAggregatePattern extends JsonPattern {
260291
}
261292
}
262293

263-
export type RestrictionMap = {[column: string]: ColumnRestriction[]};
294+
export type RestrictionMap = { [column: string]: ColumnRestriction[] };
264295

265296
const COL_ELLIPSIS = '...';
266297

packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ class MetricFilterIntegStack extends Stack {
1414
logGroup,
1515
metricNamespace: 'MyApp',
1616
metricName: 'Latency',
17-
filterPattern: FilterPattern.exists('$.latency'),
17+
filterPattern: FilterPattern.all(
18+
FilterPattern.exists('$.latency'),
19+
FilterPattern.regexValue('$.message', '=', 'bind: address already in use'),
20+
),
1821
metricValue: '$.latency',
1922
});
2023
/// !hide

packages/aws-cdk-lib/aws-logs/test/pattern.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ describe('pattern', () => {
5151
expect('{ $.field = "value" }').toEqual(pattern.logPatternString);
5252
});
5353

54+
test('regex pattern', () => {
55+
const pattern = FilterPattern.regexValue('$.field', '=', 'value');
56+
57+
expect('{ $.field = %value% }').toEqual(pattern.logPatternString);
58+
});
59+
5460
test('number patterns', () => {
5561
const pattern = FilterPattern.numberValue('$.field', '<=', 300);
5662

0 commit comments

Comments
 (0)