From a363b56f3f0e0aaee75ce957703f64b0cd53fae4 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Wed, 3 Jul 2024 10:12:01 +0200 Subject: [PATCH 01/12] Support regex patterns --- packages/aws-cdk-lib/aws-logs/lib/pattern.ts | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/aws-cdk-lib/aws-logs/lib/pattern.ts b/packages/aws-cdk-lib/aws-logs/lib/pattern.ts index 279ec55f9f372..bffad0ef04d75 100644 --- a/packages/aws-cdk-lib/aws-logs/lib/pattern.ts +++ b/packages/aws-cdk-lib/aws-logs/lib/pattern.ts @@ -117,6 +117,27 @@ export class FilterPattern { return new JSONNumberPattern(jsonField, comparison, value); } + /** + * A JSON log pattern that compares against a Regex values. + * + * This pattern only matches if the event is a JSON event, and the indicated field inside + * compares with the regex value. + * + * Use '$' to indicate the root of the JSON structure. The comparison operator can only + * compare equality or inequality. + * + * For more information, see: + * + * https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html + * + * @param jsonField Field inside JSON. Example: "$.myField" + * @param comparison Comparison to carry out. Either = or !=. + * @param value The regex value to compare to. + */ + public static regexValue(jsonField: string, comparison: string, value: string): JsonPattern { + return new JSONRegexPattern(jsonField, comparison, value); + } + /** * A JSON log pattern that matches if the field exists and has the special value 'null'. * @@ -226,6 +247,16 @@ class JSONStringPattern extends JsonPattern { } } +/** + * A regex comparison for JSON patterns + */ +class JSONRegexPattern extends JsonPattern { + public constructor(jsonField: string, comparison: string, value: string) { + // No validation, we assume these are generated by trusted factory functions + super(`${jsonField} ${comparison} %${value}%`); + } +} + /** * A number comparison for JSON values */ From c3bf88233024725f22b407a91653795098deb2a1 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Wed, 3 Jul 2024 10:53:18 +0200 Subject: [PATCH 02/12] add unit test for regex pattern --- packages/aws-cdk-lib/aws-logs/test/pattern.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts b/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts index b49c9cd220588..4c277e344671c 100644 --- a/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts +++ b/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts @@ -51,6 +51,12 @@ describe('pattern', () => { expect('{ $.field = "value" }').toEqual(pattern.logPatternString); }); + test('regex pattern', () => { + const pattern = FilterPattern.regexValue('$.field', '==', 'value'); + + expect('{ $.field = %value% }').toEqual(pattern.logPatternString); + }); + test('number patterns', () => { const pattern = FilterPattern.numberValue('$.field', '<=', 300); From 16113ed3054b6722eab3dd0c429c77912eb88ee7 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Wed, 3 Jul 2024 11:15:20 +0200 Subject: [PATCH 03/12] add documentation --- packages/aws-cdk-lib/aws-logs/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/aws-cdk-lib/aws-logs/README.md b/packages/aws-cdk-lib/aws-logs/README.md index 2276fddfb2f7f..88f9f1fcd35a7 100644 --- a/packages/aws-cdk-lib/aws-logs/README.md +++ b/packages/aws-cdk-lib/aws-logs/README.md @@ -262,6 +262,8 @@ and then descending into it, such as `$.field` or `$.list[0].field`. * `FilterPattern.stringValue(field, comparison, string)`: matches if the given field compares as indicated with the given string value. +* `FilterPattern.regexValue(field, comparison, string)`: matches if the given + field compares as indicated with the given regex pattern. * `FilterPattern.numberValue(field, comparison, number)`: matches if the given field compares as indicated with the given numerical value. * `FilterPattern.isNull(field)`: matches if the given field exists and has the @@ -291,6 +293,7 @@ const pattern = logs.FilterPattern.all( logs.FilterPattern.booleanValue('$.error', true), logs.FilterPattern.numberValue('$.latency', '>', 1000), ), + logs.FilterPattern.regexValue('$.message', '=', 'bind address already in use'), ); ``` From 93ddc8eb733b0025591a833cc62f7984f1421799 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Wed, 3 Jul 2024 11:28:14 +0200 Subject: [PATCH 04/12] add pattern to integration test --- packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts b/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts index dd61bf8ddedc9..9b5e8be5841c4 100644 --- a/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts +++ b/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts @@ -14,7 +14,10 @@ class MetricFilterIntegStack extends Stack { logGroup, metricNamespace: 'MyApp', metricName: 'Latency', - filterPattern: FilterPattern.exists('$.latency'), + filterPattern: FilterPattern.all( + FilterPattern.exists('$.latency'), + FilterPattern.regexValue('$.message', '==', 'bind: address already in use'), + ), metricValue: '$.latency', }); /// !hide From 675f8a6ff377b4e6d677bc5f8ba5765e834edffa Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Tue, 11 Feb 2025 17:44:35 +0100 Subject: [PATCH 05/12] add integration tests --- .../aws-cdk-metricfilter-integ.template.json | 4 ++-- .../test/aws-logs/test/integ.metricfilter.lit.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json index 32f6577f1b0f2..eacdf4b3ca62d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json @@ -11,7 +11,7 @@ "MetricFilter1B93B6E5": { "Type": "AWS::Logs::MetricFilter", "Properties": { - "FilterPattern": "{ $.latency = \"*\" }", + "FilterPattern": "{ ($.latency = \"*\") && ($.message == %bind: address already in use%) }", "LogGroupName": { "Ref": "LogGroupF5B46931" }, @@ -60,4 +60,4 @@ ] } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts index b06259887204d..11cfc6b6a46cc 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts @@ -15,7 +15,10 @@ class MetricFilterIntegStack extends Stack { metricNamespace: 'MyApp', metricName: 'Latency', filterName: 'MyFilterName', - filterPattern: FilterPattern.exists('$.latency'), + filterPattern: FilterPattern.all( + FilterPattern.exists('$.latency'), + FilterPattern.regexValue('$.message', '==', 'bind: address already in use'), + ), metricValue: '$.latency', }); /// !hide From 707c58a55ad174f4b4115e0eb02ff9d8f206bd1e Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Tue, 11 Feb 2025 17:46:17 +0100 Subject: [PATCH 06/12] undo line feed change --- .../aws-cdk-metricfilter-integ.template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json index eacdf4b3ca62d..251869d42473a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json @@ -60,4 +60,4 @@ ] } } -} +} \ No newline at end of file From dccd39138cb56ffd33263bccfbe1bea67ff91b95 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Tue, 11 Feb 2025 17:55:53 +0100 Subject: [PATCH 07/12] enforce comparison tighter --- packages/aws-cdk-lib/aws-logs/lib/pattern.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/aws-cdk-lib/aws-logs/lib/pattern.ts b/packages/aws-cdk-lib/aws-logs/lib/pattern.ts index 5f032ec832e73..a5198693fa6bf 100644 --- a/packages/aws-cdk-lib/aws-logs/lib/pattern.ts +++ b/packages/aws-cdk-lib/aws-logs/lib/pattern.ts @@ -133,7 +133,7 @@ export class FilterPattern { * @param comparison Comparison to carry out. Either = or !=. * @param value The regex value to compare to. */ - public static regexValue(jsonField: string, comparison: string, value: string): JsonPattern { + public static regexValue(jsonField: string, comparison: '=' | '!=', value: string): JsonPattern { return new JSONRegexPattern(jsonField, comparison, value); } @@ -250,7 +250,7 @@ class JSONStringPattern extends JsonPattern { * A regex comparison for JSON patterns */ class JSONRegexPattern extends JsonPattern { - public constructor(jsonField: string, comparison: string, value: string) { + public constructor(jsonField: string, comparison: '=' | '!=', value: string) { // No validation, we assume these are generated by trusted factory functions super(`${jsonField} ${comparison} %${value}%`); } @@ -291,7 +291,7 @@ class JSONAggregatePattern extends JsonPattern { } } -export type RestrictionMap = {[column: string]: ColumnRestriction[]}; +export type RestrictionMap = { [column: string]: ColumnRestriction[] }; const COL_ELLIPSIS = '...'; From 78f35a750ea4a670c25b6686bf29287e45cefbdb Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Tue, 11 Feb 2025 18:02:30 +0100 Subject: [PATCH 08/12] fix tempalte json --- .../aws-cdk-metricfilter-integ.template.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json index 251869d42473a..5a0774c1b1db5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json @@ -11,7 +11,7 @@ "MetricFilter1B93B6E5": { "Type": "AWS::Logs::MetricFilter", "Properties": { - "FilterPattern": "{ ($.latency = \"*\") && ($.message == %bind: address already in use%) }", + "FilterPattern": "{ ($.latency = \"*\") && ($.message = %bind: address already in use%) }", "LogGroupName": { "Ref": "LogGroupF5B46931" }, @@ -60,4 +60,4 @@ ] } } -} \ No newline at end of file +} From 9a83ebe93a7d599bac27bcc3f6a795f1740b69f8 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Tue, 11 Feb 2025 18:03:09 +0100 Subject: [PATCH 09/12] fix tests --- .../test/aws-logs/test/integ.metricfilter.lit.ts | 2 +- packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts index 11cfc6b6a46cc..92140291d2ce8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.ts @@ -17,7 +17,7 @@ class MetricFilterIntegStack extends Stack { filterName: 'MyFilterName', filterPattern: FilterPattern.all( FilterPattern.exists('$.latency'), - FilterPattern.regexValue('$.message', '==', 'bind: address already in use'), + FilterPattern.regexValue('$.message', '=', 'bind: address already in use'), ), metricValue: '$.latency', }); diff --git a/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts b/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts index 9b5e8be5841c4..ae7ef932c0c0f 100644 --- a/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts +++ b/packages/aws-cdk-lib/aws-logs/test/integ.metricfilter.lit.ts @@ -16,7 +16,7 @@ class MetricFilterIntegStack extends Stack { metricName: 'Latency', filterPattern: FilterPattern.all( FilterPattern.exists('$.latency'), - FilterPattern.regexValue('$.message', '==', 'bind: address already in use'), + FilterPattern.regexValue('$.message', '=', 'bind: address already in use'), ), metricValue: '$.latency', }); From 6b8a6eccdc688b3ac76030546527617ce98c5d70 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Tue, 11 Feb 2025 18:03:42 +0100 Subject: [PATCH 10/12] undo line feed change --- .../aws-cdk-metricfilter-integ.template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json index 5a0774c1b1db5..e50aca80cb811 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.metricfilter.lit.js.snapshot/aws-cdk-metricfilter-integ.template.json @@ -60,4 +60,4 @@ ] } } -} +} \ No newline at end of file From 9dfefd1b9b15b14d95d1eb6fb4ff47b0e33150ae Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Tue, 11 Feb 2025 18:04:35 +0100 Subject: [PATCH 11/12] fix comparison in test --- packages/aws-cdk-lib/aws-logs/test/pattern.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts b/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts index 4c277e344671c..7ee8104c8e116 100644 --- a/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts +++ b/packages/aws-cdk-lib/aws-logs/test/pattern.test.ts @@ -52,7 +52,7 @@ describe('pattern', () => { }); test('regex pattern', () => { - const pattern = FilterPattern.regexValue('$.field', '==', 'value'); + const pattern = FilterPattern.regexValue('$.field', '=', 'value'); expect('{ $.field = %value% }').toEqual(pattern.logPatternString); }); From f8c4a5b33d8d46cef6ccee2d91a129d7dfe20674 Mon Sep 17 00:00:00 2001 From: Jan Steinke Date: Thu, 13 Feb 2025 17:59:41 +0100 Subject: [PATCH 12/12] remove comparison union --- packages/aws-cdk-lib/aws-logs/lib/pattern.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-logs/lib/pattern.ts b/packages/aws-cdk-lib/aws-logs/lib/pattern.ts index a5198693fa6bf..44caabb6fec35 100644 --- a/packages/aws-cdk-lib/aws-logs/lib/pattern.ts +++ b/packages/aws-cdk-lib/aws-logs/lib/pattern.ts @@ -133,7 +133,7 @@ export class FilterPattern { * @param comparison Comparison to carry out. Either = or !=. * @param value The regex value to compare to. */ - public static regexValue(jsonField: string, comparison: '=' | '!=', value: string): JsonPattern { + public static regexValue(jsonField: string, comparison: string, value: string): JsonPattern { return new JSONRegexPattern(jsonField, comparison, value); } @@ -250,7 +250,7 @@ class JSONStringPattern extends JsonPattern { * A regex comparison for JSON patterns */ class JSONRegexPattern extends JsonPattern { - public constructor(jsonField: string, comparison: '=' | '!=', value: string) { + public constructor(jsonField: string, comparison: string, value: string) { // No validation, we assume these are generated by trusted factory functions super(`${jsonField} ${comparison} %${value}%`); }