diff --git a/API.md b/API.md index df8ad68c..fbbde8e0 100644 --- a/API.md +++ b/API.md @@ -49930,6 +49930,7 @@ create a two sets of dashboards: standard set (interactive) and a copy (bitmap). | STACKED_AREA | *No description.* | | PIE | *No description.* | | BAR | *No description.* | +| SINGLE_VALUE | *No description.* | --- @@ -49953,6 +49954,11 @@ create a two sets of dashboards: standard set (interactive) and a copy (bitmap). --- +##### `SINGLE_VALUE` + +--- + + ### HeaderLevel #### Members diff --git a/lib/common/widget/types.ts b/lib/common/widget/types.ts index 772b5c2c..f21e4f2f 100644 --- a/lib/common/widget/types.ts +++ b/lib/common/widget/types.ts @@ -2,6 +2,8 @@ import { GraphWidget, GraphWidgetProps, GraphWidgetView, + IWidget, + SingleValueWidget, } from "aws-cdk-lib/aws-cloudwatch"; export enum GraphWidgetType { @@ -9,36 +11,47 @@ export enum GraphWidgetType { STACKED_AREA = "StackedArea", PIE = "Pie", BAR = "Bar", + SINGLE_VALUE = "SingleValue", } /** * Creates a graph widget of the desired type. + * * @param type graph type (e.g. Pie or Bar) * @param props graph widget properties */ export function createGraphWidget( type: GraphWidgetType, props: GraphWidgetProps -) { +): IWidget { switch (type) { - case "Line": + case GraphWidgetType.LINE: return new GraphWidget(props); - case "Bar": + + case GraphWidgetType.BAR: return new GraphWidget({ ...props, view: GraphWidgetView.BAR, }); - case "Pie": + + case GraphWidgetType.PIE: return new GraphWidget({ ...props, view: GraphWidgetView.PIE, }); - case "StackedArea": + + case GraphWidgetType.STACKED_AREA: return new GraphWidget({ ...props, stacked: true, }); + + case GraphWidgetType.SINGLE_VALUE: + return new SingleValueWidget({ + metrics: [...(props.left ?? []), ...(props.right ?? [])], + }); + default: - throw new Error("Unsupported graph type: " + type); + throw new Error(`Unsupported graph type: ${type}`); } } diff --git a/lib/monitoring/custom/CustomMonitoring.ts b/lib/monitoring/custom/CustomMonitoring.ts index 60a2d222..638634a1 100644 --- a/lib/monitoring/custom/CustomMonitoring.ts +++ b/lib/monitoring/custom/CustomMonitoring.ts @@ -328,7 +328,7 @@ export class CustomMonitoring extends Monitoring { annotatedGroups: CustomMetricGroupWithAnnotations[], summary: boolean ) { - const widgets: GraphWidget[] = []; + const widgets: IWidget[] = []; const metricGroupWidgetWidth = recommendedWidgetWidth( annotatedGroups.length ); diff --git a/test/monitoring/custom/CustomMonitoring.test.ts b/test/monitoring/custom/CustomMonitoring.test.ts index bcc10770..4402cb54 100644 --- a/test/monitoring/custom/CustomMonitoring.test.ts +++ b/test/monitoring/custom/CustomMonitoring.test.ts @@ -10,9 +10,11 @@ import { import { AxisPosition, CustomMonitoring, + GraphWidgetType, MetricFactory, MetricStatistic, } from "../../../lib"; +import { addMonitoringDashboardsToStack } from "../../utils/SnapshotUtil"; import { TestMonitoringScope } from "../TestMonitoringScope"; const namespace = "DummyCustomNamespace"; @@ -24,7 +26,7 @@ test("snapshot test", () => { let numAlarmsCreated = 0; - new CustomMonitoring(scope, { + const monitoring = new CustomMonitoring(scope, { alarmFriendlyName: "DummyAlarmName", humanReadableName: "DummyName", description: @@ -68,6 +70,7 @@ test("snapshot test", () => { }, { title: "DummyGroup2", + graphWidgetType: GraphWidgetType.BAR, metrics: [ // regular metric new Metric({ metricName: "DummyMetric10", namespace, dimensionsMap }), @@ -99,6 +102,7 @@ test("snapshot test", () => { }, { title: "DummyGroup3", + graphWidgetType: GraphWidgetType.PIE, metrics: [ // regular metric new Metric({ metricName: "DummyMetric20", namespace, dimensionsMap }), @@ -145,6 +149,14 @@ test("snapshot test", () => { { label: "DummyAnnotation3", value: 20, fill: Shading.BELOW }, ], }, + { + title: "DummyGroup4", + graphWidgetType: GraphWidgetType.SINGLE_VALUE, + metrics: [ + new Metric({ metricName: "DummyMetric40", namespace, dimensionsMap }), + new Metric({ metricName: "DummyMetric41", namespace, dimensionsMap }), + ], + }, ], useCreatedAlarms: { consume(alarms) { @@ -154,6 +166,8 @@ test("snapshot test", () => { }); expect(numAlarmsCreated).toStrictEqual(6); + + addMonitoringDashboardsToStack(stack, monitoring); expect(Template.fromStack(stack)).toMatchSnapshot(); }); diff --git a/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap b/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap index fbb7c4d0..3890934a 100644 --- a/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap +++ b/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap @@ -401,6 +401,114 @@ Object { }, }, "Resources": Object { + "Alarm7103F465": Object { + "Properties": Object { + "DashboardBody": Object { + "Fn::Join": Array [ + "", + Array [ + "{\\"widgets\\":[{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"annotations\\":{\\"alarms\\":[\\"", + Object { + "Fn::GetAtt": Array [ + "ScopeTestDummyAlarmNameAlarmForDummyMetric3WarningA3421ECE", + "Arn", + ], + }, + "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":6,\\"y\\":0,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"annotations\\":{\\"alarms\\":[\\"", + Object { + "Fn::GetAtt": Array [ + "ScopeTestDummyAlarmNameAlarmForDummyMetric3Critical2B202C0B", + "Arn", + ], + }, + "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":12,\\"y\\":0,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"annotations\\":{\\"alarms\\":[\\"", + Object { + "Fn::GetAtt": Array [ + "ScopeTestDummyAlarmNameAlarmForDummyMetric12WarningA3D33CD3", + "Arn", + ], + }, + "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":18,\\"y\\":0,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"annotations\\":{\\"alarms\\":[\\"", + Object { + "Fn::GetAtt": Array [ + "ScopeTestDummyAlarmNameAlarmForDummyMetric12Critical71A1C38A", + "Arn", + ], + }, + "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":0,\\"y\\":4,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"annotations\\":{\\"alarms\\":[\\"", + Object { + "Fn::GetAtt": Array [ + "ScopeTestDummyAlarmNameAlarmForDummyMetric22Warning4F0C643F", + "Arn", + ], + }, + "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":6,\\"y\\":4,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"annotations\\":{\\"alarms\\":[\\"", + Object { + "Fn::GetAtt": Array [ + "ScopeTestDummyAlarmNameAlarmForDummyMetric22CriticalB723921F", + "Arn", + ], + }, + "\\"]},\\"yAxis\\":{}}}]}", + ], + ], + }, + }, + "Type": "AWS::CloudWatch::Dashboard", + }, + "Resource": Object { + "Properties": Object { + "DashboardBody": Object { + "Fn::Join": Array [ + "", + Array [ + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### DummyName\\"}},{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":2,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"markdown\\":\\"This is a very long description.\\\\nSecond line of this very long description.\\\\nThird line of this very long description.\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":3,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"DummyGroup1\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"DummyCustomNamespace\\",\\"DummyMetric1\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric2\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric3\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{DummyCustomNamespace,CustomDimension} CustomDimension=\\\\\\"CustomDimensionValue\\\\\\" DummyMetric4-', 'Sum', 300)\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"DummyMetric3 < 90 for 3 datapoints within 15 minutes\\",\\"value\\":90,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyMetric3 < 50 for 3 datapoints within 15 minutes\\",\\"value\\":50,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":6,\\"y\\":3,\\"properties\\":{\\"view\\":\\"bar\\",\\"title\\":\\"DummyGroup2\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"DummyCustomNamespace\\",\\"DummyMetric10\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric11\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric12\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"DummyAnnotation1\\",\\"value\\":30,\\"fill\\":\\"above\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyAnnotation2\\",\\"value\\":20,\\"fill\\":\\"below\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyMetric12 > 10 for 3 datapoints within 15 minutes\\",\\"value\\":10,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyMetric12 > 50 for 3 datapoints within 15 minutes\\",\\"value\\":50,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":3,\\"properties\\":{\\"view\\":\\"pie\\",\\"title\\":\\"DummyGroup3\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"DummyCustomNamespace\\",\\"DummyMetric20\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric21\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric22\\",\\"CustomDimension\\",\\"CustomDimensionValue\\",{\\"yAxis\\":\\"right\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"DummyAnnotation1\\",\\"value\\":30,\\"fill\\":\\"above\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyAnnotation2\\",\\"value\\":20,\\"fill\\":\\"below\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyAnnotation3\\",\\"value\\":20,\\"fill\\":\\"below\\",\\"yAxis\\":\\"right\\"},{\\"label\\":\\"DummyMetric22 > 10 for 3 datapoints within 15 minutes\\",\\"value\\":10,\\"yAxis\\":\\"right\\"},{\\"label\\":\\"DummyMetric22 > 50 for 3 datapoints within 15 minutes\\",\\"value\\":50,\\"yAxis\\":\\"right\\"}]},\\"yAxis\\":{\\"right\\":{\\"label\\":\\"CustomValue\\"}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":3,\\"x\\":18,\\"y\\":3,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"DummyCustomNamespace\\",\\"DummyMetric40\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric41\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"]]}}]}", + ], + ], + }, + }, + "Type": "AWS::CloudWatch::Dashboard", + }, "ScopeTestDummyAlarmNameAlarmForDummyMetric12Critical71A1C38A": Object { "Properties": Object { "ActionsEnabled": true, @@ -539,6 +647,23 @@ Object { }, "Type": "AWS::CloudWatch::Alarm", }, + "Summary68521F81": Object { + "Properties": Object { + "DashboardBody": Object { + "Fn::Join": Array [ + "", + Array [ + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### DummyName\\"}},{\\"type\\":\\"metric\\",\\"width\\":24,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"DummyGroup1\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"DummyCustomNamespace\\",\\"DummyMetric1\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric2\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric3\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{DummyCustomNamespace,CustomDimension} CustomDimension=\\\\\\"CustomDimensionValue\\\\\\" DummyMetric4-', 'Sum', 300)\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"DummyMetric3 < 90 for 3 datapoints within 15 minutes\\",\\"value\\":90,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyMetric3 < 50 for 3 datapoints within 15 minutes\\",\\"value\\":50,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{}}}]}", + ], + ], + }, + }, + "Type": "AWS::CloudWatch::Dashboard", + }, }, "Rules": Object { "CheckBootstrapVersion": Object {