diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/LogGroupMetricsDefaultTestDeployAssertF61C3BCA.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/LogGroupMetricsDefaultTestDeployAssertF61C3BCA.assets.json new file mode 100644 index 0000000000000..7e6afd7d1b6b3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/LogGroupMetricsDefaultTestDeployAssertF61C3BCA.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "LogGroupMetricsDefaultTestDeployAssertF61C3BCA.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/LogGroupMetricsDefaultTestDeployAssertF61C3BCA.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/LogGroupMetricsDefaultTestDeployAssertF61C3BCA.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/LogGroupMetricsDefaultTestDeployAssertF61C3BCA.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/aws-cdk-log-group-metrics.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/aws-cdk-log-group-metrics.assets.json new file mode 100644 index 0000000000000..008e4c48fcd0f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/aws-cdk-log-group-metrics.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "71b53c3965d74bf965044819161cded75e176bd07805af4fceff5dcda7eab49e": { + "source": { + "path": "aws-cdk-log-group-metrics.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "71b53c3965d74bf965044819161cded75e176bd07805af4fceff5dcda7eab49e.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/aws-cdk-log-group-metrics.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/aws-cdk-log-group-metrics.template.json new file mode 100644 index 0000000000000..1a2cf93f3a73d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/aws-cdk-log-group-metrics.template.json @@ -0,0 +1,71 @@ +{ + "Resources": { + "MyLogGroup5C0DAD85": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "my-log-group", + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "IncomingBytesPerInstanceAlarmFA8EEFDB": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "MetricName": "IncomingBytes", + "Namespace": "AWS/Logs", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "IncomingEventsPerInstanceAlarmA9670D55": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "MetricName": "IncomingLogs", + "Namespace": "AWS/Logs", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/integ.json new file mode 100644 index 0000000000000..af6adfec747c4 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "38.0.1", + "testCases": { + "LogGroupMetrics/DefaultTest": { + "stacks": [ + "aws-cdk-log-group-metrics" + ], + "assertionStack": "LogGroupMetrics/DefaultTest/DeployAssert", + "assertionStackName": "LogGroupMetricsDefaultTestDeployAssertF61C3BCA" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/manifest.json new file mode 100644 index 0000000000000..ebdb79361913c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/manifest.json @@ -0,0 +1,127 @@ +{ + "version": "38.0.1", + "artifacts": { + "aws-cdk-log-group-metrics.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-log-group-metrics.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-log-group-metrics": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-log-group-metrics.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/71b53c3965d74bf965044819161cded75e176bd07805af4fceff5dcda7eab49e.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-log-group-metrics.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-log-group-metrics.assets" + ], + "metadata": { + "/aws-cdk-log-group-metrics/MyLogGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLogGroup5C0DAD85" + } + ], + "/aws-cdk-log-group-metrics/IncomingBytesPerInstanceAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "IncomingBytesPerInstanceAlarmFA8EEFDB" + } + ], + "/aws-cdk-log-group-metrics/IncomingEventsPerInstanceAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "IncomingEventsPerInstanceAlarmA9670D55" + } + ], + "/aws-cdk-log-group-metrics/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-log-group-metrics/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-log-group-metrics" + }, + "LogGroupMetricsDefaultTestDeployAssertF61C3BCA.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "LogGroupMetricsDefaultTestDeployAssertF61C3BCA.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "LogGroupMetricsDefaultTestDeployAssertF61C3BCA": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "LogGroupMetricsDefaultTestDeployAssertF61C3BCA.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "LogGroupMetricsDefaultTestDeployAssertF61C3BCA.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "LogGroupMetricsDefaultTestDeployAssertF61C3BCA.assets" + ], + "metadata": { + "/LogGroupMetrics/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/LogGroupMetrics/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "LogGroupMetrics/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/tree.json new file mode 100644 index 0000000000000..c68d2c1c9b17a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.js.snapshot/tree.json @@ -0,0 +1,186 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-log-group-metrics": { + "id": "aws-cdk-log-group-metrics", + "path": "aws-cdk-log-group-metrics", + "children": { + "MyLogGroup": { + "id": "MyLogGroup", + "path": "aws-cdk-log-group-metrics/MyLogGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-log-group-metrics/MyLogGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Logs::LogGroup", + "aws:cdk:cloudformation:props": { + "logGroupName": "my-log-group", + "retentionInDays": 731 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.CfnLogGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.LogGroup", + "version": "0.0.0" + } + }, + "IncomingBytesPerInstanceAlarm": { + "id": "IncomingBytesPerInstanceAlarm", + "path": "aws-cdk-log-group-metrics/IncomingBytesPerInstanceAlarm", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-log-group-metrics/IncomingBytesPerInstanceAlarm/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", + "aws:cdk:cloudformation:props": { + "comparisonOperator": "GreaterThanOrEqualToThreshold", + "evaluationPeriods": 1, + "metricName": "IncomingBytes", + "namespace": "AWS/Logs", + "period": 300, + "statistic": "Sum", + "threshold": 1 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudwatch.CfnAlarm", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudwatch.Alarm", + "version": "0.0.0" + } + }, + "IncomingEventsPerInstanceAlarm": { + "id": "IncomingEventsPerInstanceAlarm", + "path": "aws-cdk-log-group-metrics/IncomingEventsPerInstanceAlarm", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-log-group-metrics/IncomingEventsPerInstanceAlarm/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", + "aws:cdk:cloudformation:props": { + "comparisonOperator": "GreaterThanOrEqualToThreshold", + "evaluationPeriods": 1, + "metricName": "IncomingLogs", + "namespace": "AWS/Logs", + "period": 300, + "statistic": "Sum", + "threshold": 1 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudwatch.CfnAlarm", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudwatch.Alarm", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-log-group-metrics/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-log-group-metrics/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "LogGroupMetrics": { + "id": "LogGroupMetrics", + "path": "LogGroupMetrics", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "LogGroupMetrics/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "LogGroupMetrics/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "LogGroupMetrics/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "LogGroupMetrics/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "LogGroupMetrics/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.ts new file mode 100644 index 0000000000000..ea74dec2462f5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.log-group-metrics.ts @@ -0,0 +1,25 @@ +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { App, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { LogGroup } from 'aws-cdk-lib/aws-logs'; + +const app = new App(); +const stack = new Stack(app, 'aws-cdk-log-group-metrics'); + +const logGroup = new LogGroup(stack, 'MyLogGroup', { + logGroupName: 'my-log-group', + removalPolicy: RemovalPolicy.DESTROY, +}); + +logGroup.metricIncomingBytes().createAlarm(stack, 'IncomingBytesPerInstanceAlarm', { + threshold: 1, + evaluationPeriods: 1, +}); + +logGroup.metricIncomingLogEvents().createAlarm(stack, 'IncomingEventsPerInstanceAlarm', { + threshold: 1, + evaluationPeriods: 1, +}); + +new IntegTest(app, 'LogGroupMetrics', { + testCases: [stack], +}); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-events-targets/test/logs/log-group.test.ts b/packages/aws-cdk-lib/aws-events-targets/test/logs/log-group.test.ts index f2670af087148..0f831b032168f 100644 --- a/packages/aws-cdk-lib/aws-events-targets/test/logs/log-group.test.ts +++ b/packages/aws-cdk-lib/aws-events-targets/test/logs/log-group.test.ts @@ -398,3 +398,83 @@ testDeprecated('specifying retry policy with 0 retryAttempts', () => { ], }); }); + +test('metricIncomingLogEvents', () => { + // GIVEN + const stack = new cdk.Stack(); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup', { + logGroupName: '/aws/events/MyLogGroup', + }); + + expect(stack.resolve(logGroup.metricIncomingLogEvents())).toEqual({ + period: { + amount: 5, + unit: { label: 'minutes', inMillis: 60000, isoLabel: 'M' }, + }, + namespace: 'AWS/Logs', + metricName: 'IncomingLogs', + statistic: 'Sum', + }); +}); + +test('metricIncomingLogEvents with MetricOptions props', () => { + // GIVEN + const stack = new cdk.Stack(); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup', { + logGroupName: '/aws/events/MyLogGroup', + }); + + expect(stack.resolve(logGroup.metricIncomingLogEvents({ + period: cdk.Duration.hours(10), + label: 'MyMetric', + }))).toEqual({ + period: { + amount: 10, + unit: { label: 'hours', inMillis: 3600000, isoLabel: 'H' }, + }, + namespace: 'AWS/Logs', + metricName: 'IncomingLogs', + statistic: 'Sum', + label: 'MyMetric', + }); +}); + +test('metricIncomingBytes', () => { + // GIVEN + const stack = new cdk.Stack(); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup', { + logGroupName: '/aws/events/MyLogGroup', + }); + + expect(stack.resolve(logGroup.metricIncomingBytes())).toEqual({ + period: { + amount: 5, + unit: { label: 'minutes', inMillis: 60000, isoLabel: 'M' }, + }, + namespace: 'AWS/Logs', + metricName: 'IncomingBytes', + statistic: 'Sum', + }); +}); + +test('metricIncomingBytes with MetricOptions props', () => { + // GIVEN + const stack = new cdk.Stack(); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup', { + logGroupName: '/aws/events/MyLogGroup', + }); + + expect(stack.resolve(logGroup.metricIncomingBytes({ + period: cdk.Duration.minutes(15), + statistic: 'Sum', + }))).toEqual({ + period: { + amount: 15, + unit: { label: 'minutes', inMillis: 60000, isoLabel: 'M' }, + }, + namespace: 'AWS/Logs', + metricName: 'IncomingBytes', + statistic: 'Sum', + }); +}); + diff --git a/packages/aws-cdk-lib/aws-logs/README.md b/packages/aws-cdk-lib/aws-logs/README.md index 4ee04e1de7ed3..52dd9aaf84b1f 100644 --- a/packages/aws-cdk-lib/aws-logs/README.md +++ b/packages/aws-cdk-lib/aws-logs/README.md @@ -208,6 +208,29 @@ new cloudwatch.Alarm(this, 'alarm from metric filter', { }); ``` +### Metrics for IncomingLogs and IncomingBytes +Metric methods have been defined for IncomingLogs and IncomingBytes within LogGroups. These metrics allow for the creation of alarms on log ingestion, ensuring that the log ingestion process is functioning correctly. + +To define an alarm based on these metrics, you can use the following template: +```ts +const logGroup = new logs.LogGroup(this, 'MyLogGroup'); +const incomingEventsMetric = logGroup.metricIncomingLogEvents(); +new cloudwatch.Alarm(this, 'HighLogVolumeAlarm', { + metric: incomingEventsMetric, + threshold: 1000, + evaluationPeriods: 1, +}); +``` +```ts +const logGroup = new logs.LogGroup(this, 'MyLogGroup'); +const incomingBytesMetric = logGroup.metricIncomingBytes(); +new cloudwatch.Alarm(this, 'HighDataVolumeAlarm', { + metric: incomingBytesMetric, + threshold: 5000000, // 5 MB + evaluationPeriods: 1, +}); +``` + ## Patterns Patterns describe which log events match a subscription or metric filter. There diff --git a/packages/aws-cdk-lib/aws-logs/lib/log-group.ts b/packages/aws-cdk-lib/aws-logs/lib/log-group.ts index d1a014ef7cefa..d9ba52ef30ae5 100644 --- a/packages/aws-cdk-lib/aws-logs/lib/log-group.ts +++ b/packages/aws-cdk-lib/aws-logs/lib/log-group.ts @@ -84,6 +84,32 @@ export interface ILogGroup extends iam.IResourceWithPolicy { * Public method to get the physical name of this log group */ logGroupPhysicalName(): string; + + /** + * Return the given named metric for this Log Group + * + * @param metricName The name of the metric + * @param props Properties for the metric + */ + metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric; + + /** + * The number of log events uploaded to CloudWatch Logs. + * When used with the LogGroupName dimension, this is the number of + * log events uploaded to the log group. + * + * @param props Properties for the Cloudwatch metric + */ + metricIncomingLogEvents(props?: cloudwatch.MetricOptions): cloudwatch.Metric; + + /** + * The volume of log events in uncompressed bytes uploaded to CloudWatch Logs. + * When used with the LogGroupName dimension, this is the volume of log events + * in uncompressed bytes uploaded to the log group. + * + * @param props Properties for the Cloudwatch metric + */ + metricIncomingBytes(props?: cloudwatch.MetricOptions): cloudwatch.Metric; } /** @@ -245,6 +271,78 @@ abstract class LogGroupBase extends Resource implements ILogGroup { return principal; } + + /** + * Creates a CloudWatch metric for the number of incoming log events to this log group. + * + * @param props - Optional. Configuration options for the metric. + * @returns A CloudWatch Metric object representing the IncomingLogEvents metric. + * + * This method allows you to monitor the rate at which log events are being ingested + * into the log group. It's useful for understanding the volume of logging activity + * and can help in capacity planning or detecting unusual spikes in logging. + * + * Example usage: + * ``` + * const logGroup = new logs.LogGroup(this, 'MyLogGroup'); + * logGroup.metricIncomingLogEvents().createAlarm(stack, 'IncomingEventsPerInstanceAlarm', { + * threshold: 1, + * evaluationPeriods: 1, + * }); + * ``` + */ + public metricIncomingLogEvents(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return this.metric('IncomingLogs', props); + } + + /** + * Creates a CloudWatch metric for the volume of incoming log data in bytes to this log group. + * + * @param props - Optional. Configuration options for the metric. + * @returns A CloudWatch Metric object representing the IncomingBytes metric. + * + * This method allows you to monitor the volume of data being ingested into the log group. + * It's useful for understanding the size of your logs, which can impact storage costs + * and help in identifying unexpectedly large log entries. + * + * Example usage: + * ``` + * const logGroup = new logs.LogGroup(this, 'MyLogGroup'); + * logGroup.metricIncomingBytes().createAlarm(stack, 'IncomingBytesPerInstanceAlarm', { + * threshold: 1, + * evaluationPeriods: 1, + * }); + * ``` + */ + public metricIncomingBytes(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return this.metric('IncomingBytes', props); + } + + /** + * Creates a CloudWatch metric for this log group. + * + * @param _metricName - The name of the metric to create. + * @param _props - Optional. Additional properties to configure the metric. + * @returns A CloudWatch Metric object representing the specified metric for this log group. + * + * This method creates a CloudWatch Metric object with predefined settings for the log group. + * It sets the namespace to 'AWS/Logs' and the statistic to 'Sum' by default. + * + * The created metric is automatically associated with this log group using the `attachTo` method. + * + * Common metric names for log groups include: + * - 'IncomingBytes': The volume of log data in bytes ingested into the log group. + * - 'IncomingLogEvents': The number of log events ingested into the log group. + * ``` + */ + public metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return new cloudwatch.Metric({ + namespace: 'AWS/Logs', + metricName, + statistic: 'Sum', + ...props, + }).attachTo(this); + } } /**