diff --git a/packages/@aws-cdk/aws-cloudwatch/README.md b/packages/@aws-cdk/aws-cloudwatch/README.md index 30b80f9646398..67828ee2b6864 100644 --- a/packages/@aws-cdk/aws-cloudwatch/README.md +++ b/packages/@aws-cdk/aws-cloudwatch/README.md @@ -697,3 +697,18 @@ new cloudwatch.Row(widgetA, widgetB); You can add a widget after object instantiation with the method `addWidget()`. + +### Interval duration for dashboard + +Interval duration for metrics in dashboard. You can specify `defaultInterval` with +the relative time(eg. 7 days) as `cdk.Duration.days(7)`. + +```ts +import * as cw from '@aws-cdk/aws-cloudwatch'; + +const dashboard = new cw.Dashboard(stack, 'Dash', { + defaultInterval: cdk.Duration.days(7), +}); +``` + +Here, the dashboard would show the metrics for the last 7 days. diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts index f138d1f419ab6..37cd92fd9e29b 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts @@ -1,4 +1,4 @@ -import { Lazy, Resource, Stack, Token, Annotations } from '@aws-cdk/core'; +import { Lazy, Resource, Stack, Token, Annotations, Duration } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDashboard } from './cloudwatch.generated'; import { Column, Row } from './layout'; @@ -31,6 +31,14 @@ export interface DashboardProps { */ readonly dashboardName?: string; + /** + * Interval duration for metrics. + * You can specify defaultInterval with the relative time(eg. cdk.Duration.days(7)). + * + * @default When the dashboard loads, the defaultInterval time will be the default time range. + */ + readonly defaultInterval?: Duration + /** * The start of the time range to use for each widget on the dashboard. * You can specify start without specifying end to specify a relative time range that ends with the current time. @@ -107,6 +115,10 @@ export class Dashboard extends Resource { } } + if (props.start !== undefined && props.defaultInterval !== undefined) { + throw ('both properties defaultInterval and start cannot be set at once'); + } + const dashboard = new CfnDashboard(this, 'Resource', { dashboardName: this.physicalName, dashboardBody: Lazy.string({ @@ -114,8 +126,8 @@ export class Dashboard extends Resource { const column = new Column(...this.rows); column.position(0, 0); return Stack.of(this).toJsonString({ - start: props.start, - end: props.end, + start: props.defaultInterval !== undefined ? `-${props.defaultInterval?.toIsoString()}` : props.start, + end: props.defaultInterval !== undefined ? undefined : props.end, periodOverride: props.periodOverride, widgets: column.toJson(), }); diff --git a/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts b/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts index cf4c123e0171c..87641c935d448 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts @@ -1,5 +1,5 @@ import { Template, Annotations, Match } from '@aws-cdk/assertions'; -import { App, Stack } from '@aws-cdk/core'; +import { App, Duration, Stack } from '@aws-cdk/core'; import { Dashboard, GraphWidget, PeriodOverride, TextWidget, MathExpression, TextWidgetBackground } from '../lib'; describe('Dashboard', () => { @@ -131,6 +131,31 @@ describe('Dashboard', () => { }); + test('defaultInterval test', () => { + // GIVEN + const stack = new Stack(); + // WHEN + const dashboard = new Dashboard(stack, 'Dash', { + defaultInterval: Duration.days(7), + }); + dashboard.addWidgets( + new GraphWidget({ width: 1, height: 1 }), // GraphWidget has internal reference to current region + ); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', { + DashboardBody: { + 'Fn::Join': ['', [ + '{"start":"-P7D",\ +"widgets":[{"type":"metric","width":1,"height":1,"x":0,"y":0,"properties":{"view":"timeSeries","region":"', + { Ref: 'AWS::Region' }, + '","yAxis":{}}}]}', + ]], + }, + }); + + }); + test('DashboardName is set when provided', () => { // GIVEN const app = new App(); diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestDefaultTestDeployAssert5BE38902.assets.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestDefaultTestDeployAssert5BE38902.assets.json index 54fff803ba3d9..cc6443bcd7bd8 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestDefaultTestDeployAssert5BE38902.assets.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestDefaultTestDeployAssert5BE38902.assets.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "31.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.assets.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.assets.json index 595d92ea76c09..c1216e09c0031 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.assets.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.assets.json @@ -1,7 +1,7 @@ { - "version": "30.0.0", + "version": "31.0.0", "files": { - "53eb5ec97b9df3953bc84bdc2aee87ace7b502c665b7e5b9f7b7d14dd46cea69": { + "1a70f8470c838c02020b9010528363b17eebd55d55c1a53fb3e0f6760a606c98": { "source": { "path": "DashboardIntegrationTestStack.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "53eb5ec97b9df3953bc84bdc2aee87ace7b502c665b7e5b9f7b7d14dd46cea69.json", + "objectKey": "1a70f8470c838c02020b9010528363b17eebd55d55c1a53fb3e0f6760a606c98.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.template.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.template.json index cce2e902ed631..bae3b7498819d 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.template.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/DashboardIntegrationTestStack.template.json @@ -3,7 +3,7 @@ "DashCCD7F836": { "Type": "AWS::CloudWatch::Dashboard", "Properties": { - "DashboardBody": "{\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"I don't have a background\",\"background\":\"transparent\"}}]}" + "DashboardBody": "{\"start\":\"-P7D\",\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"I don't have a background\",\"background\":\"transparent\"}}]}" } } }, diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/cdk.out index ae4b03c54e770..7925065efbcc4 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"30.0.0"} \ No newline at end of file +{"version":"31.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/integ.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/integ.json index 97d4b4c695087..0f1d270fe004c 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "31.0.0", "testCases": { "DashboardIntegrationTest/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/manifest.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/manifest.json index 7e16f2cbd9b40..e2232bc5e3d44 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "31.0.0", "artifacts": { "DashboardIntegrationTestStack.assets": { "type": "cdk:asset-manifest", @@ -17,7 +17,7 @@ "validateOnSynth": false, "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}/53eb5ec97b9df3953bc84bdc2aee87ace7b502c665b7e5b9f7b7d14dd46cea69.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1a70f8470c838c02020b9010528363b17eebd55d55c1a53fb3e0f6760a606c98.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/tree.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/tree.json index 20d55ea065cdf..208279e25ef53 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.js.snapshot/tree.json @@ -18,7 +18,7 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::CloudWatch::Dashboard", "aws:cdk:cloudformation:props": { - "dashboardBody": "{\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"I don't have a background\",\"background\":\"transparent\"}}]}" + "dashboardBody": "{\"start\":\"-P7D\",\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"I don't have a background\",\"background\":\"transparent\"}}]}" } }, "constructInfo": { @@ -75,7 +75,7 @@ "path": "DashboardIntegrationTest/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.252" + "version": "10.1.270" } }, "DeployAssert": { @@ -121,7 +121,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.252" + "version": "10.1.270" } } }, diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.ts index 445d19698d809..b35722bb60975 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.dashboard.ts @@ -7,7 +7,9 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'DashboardIntegrationTestStack'); -const dashboard = new cloudwatch.Dashboard(stack, 'Dash'); +const dashboard = new cloudwatch.Dashboard(stack, 'Dash', { + defaultInterval: cdk.Duration.days(7), +}); dashboard.addWidgets(new cloudwatch.TextWidget({ markdown: 'I don\'t have a background',