Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cloudwatch): Additional Properties for Cloudwatch AlarmStatusWidget #19387

Merged
merged 13 commits into from Mar 24, 2022
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-cloudwatch/README.md
Expand Up @@ -436,6 +436,20 @@ dashboard.addWidgets(
);
```

An alarm status widget only showing firing alarms, sorted by state and timestamp:

```ts
declare const dashboard: cloudwatch.Dashboard;
declare const errorAlarm: cloudwatch.Alarm;

dashboard.addWidgets(new cloudwatch.AlarmStatusWidget({
title: "Errors",
alarms: [errorAlarm],
markussiebert marked this conversation as resolved.
Show resolved Hide resolved
sortBy: cloudwatch.AlarmStatusWidgetSortBy.STATE_UPDATED_TIMESTAMP,
states: [cloudwatch.AlarmState.ALARM],
}));
```

### Query results widget

A `LogQueryWidget` shows the results of a query from Logs Insights:
Expand Down
47 changes: 47 additions & 0 deletions packages/@aws-cdk/aws-cloudwatch/lib/alarm-status-widget.ts
@@ -1,6 +1,33 @@
import { IAlarm } from './alarm-base';
import { AlarmState } from './alarm-rule';
import { ConcreteWidget } from './widget';


/**
* The sort possibilities for AlarmStatusWidgets
*/
export enum AlarmStatusWidgetSortBy {

/**
* Choose DEFAULT to sort them in alphabetical order by alarm name.
*/
DEFAULT = 'default',

/**
* Choose STATE_UPDATED_TIMESTAMP to sort them first by alarm state, with alarms in ALARM state first,
* INSUFFICIENT_DATA alarms next, and OK alarms last.
* Within each group, the alarms are sorted by when they last changed state, with more recent state changes listed first.
*/
STATE_UPDATED_TIMESTAMP = 'stateUpdatedTimestamp',

/**
* Choose TIMESTAMP to sort them by the time when the alarms most recently changed state,
* no matter the current alarm state.
* The alarm that changed state most recently is listed first.
*/
TIMESTAMP = 'timestamp',
}

/**
* Properties for an Alarm Status Widget
*/
Expand All @@ -27,6 +54,24 @@ export interface AlarmStatusWidgetProps {
* @default 3
*/
readonly height?: number;

/**
* Specifies how to sort the alarms in the widget.
*
* @default DEFAULT
markussiebert marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly sortBy?: AlarmStatusWidgetSortBy;

/**
* Use this field to filter the list of alarms displayed in the widget to only those alarms currently in the specified states.
* You can specify one or more alarm states in the value for this field.
* The alarm states that you can specify are ALARM, INSUFFICIENT_DATA, and OK.
*
* If you omit this field or specify an empty array, all the alarms specifed in alarms are displayed.
*
* @default - [] - all the alarms specifed in alarms are displayed.
markussiebert marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly states?: AlarmState[];
}

/**
Expand Down Expand Up @@ -56,6 +101,8 @@ export class AlarmStatusWidget extends ConcreteWidget {
properties: {
title: this.props.title ? this.props.title : 'Alarm Status',
alarms: this.props.alarms.map((alarm) => alarm.alarmArn),
states: this.props.states ?? [],
sortBy: this.props.sortBy ?? AlarmStatusWidgetSortBy.DEFAULT,
markussiebert marked this conversation as resolved.
Show resolved Hide resolved
},
},
];
Expand Down
@@ -1,5 +1,5 @@
import { Stack } from '@aws-cdk/core';
import { Metric, Alarm, AlarmStatusWidget } from '../lib';
import { Metric, Alarm, AlarmStatusWidget, AlarmStatusWidgetSortBy, AlarmState } from '../lib';
describe('Alarm Status Widget', () => {
test('alarm status widget', () => {
// GIVEN
Expand All @@ -25,10 +25,43 @@ describe('Alarm Status Widget', () => {
properties: {
title: 'Alarm Status',
alarms: [{ 'Fn::GetAtt': ['Alarm7103F465', 'Arn'] }],
sortBy: 'default',
states: [],
},
},
]);
});
test('alarm status widget custom props', () => {
// GIVEN
const stack = new Stack();
const metric = new Metric({ namespace: 'CDK', metricName: 'Test' });
const alarm = new Alarm(stack, 'Alarm', {
metric,
threshold: 1,
evaluationPeriods: 1,
});

// WHEN
const widget = new AlarmStatusWidget({
alarms: [alarm],
sortBy: AlarmStatusWidgetSortBy.STATE_UPDATED_TIMESTAMP,
states: [AlarmState.ALARM],
});

// THEN
expect(stack.resolve(widget.toJson())).toEqual([
{
type: 'alarm',
width: 6,
height: 3,
properties: {
title: 'Alarm Status',
alarms: [{ 'Fn::GetAtt': ['Alarm7103F465', 'Arn'] }],
sortBy: 'stateUpdatedTimestamp',
states: ['ALARM'],
},
},
]);

});
});