Skip to content

Commit 5448009

Browse files
authored
feat(scheduler): metrics for all schedules (#27544)
Class Schedule now provides static methods for accessing all schedules metrics with default configuration, such as `metricAllErrors` for viewing errors when executing targets. Advances #23394 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 7398f0c commit 5448009

File tree

8 files changed

+204
-7
lines changed

8 files changed

+204
-7
lines changed

packages/@aws-cdk/aws-scheduler-alpha/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,16 @@ EventBridge Scheduler publishes additional metrics when your schedule exhausts i
245245

246246
### Metrics for all schedules
247247

248-
TODO: Not yet implemented. See section in [L2 Event Bridge Scheduler RFC](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)
248+
Class `Schedule` provides static methods for accessing all schedules metrics with default configuration,
249+
such as `metricAllErrors` for viewing errors when executing targets.
250+
251+
```ts
252+
new cloudwatch.Alarm(this, 'SchedulesErrorAlarm', {
253+
metric: Schedule.metricAllErrors(),
254+
threshold: 0,
255+
evaluationPeriods: 1,
256+
});
257+
```
249258

250259
### Metrics for a Group
251260

packages/@aws-cdk/aws-scheduler-alpha/lib/schedule.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { IResource, Resource } from 'aws-cdk-lib';
2+
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
23
import { CfnSchedule } from 'aws-cdk-lib/aws-scheduler';
34
import { Construct } from 'constructs';
45
import { IGroup } from './group';
@@ -72,6 +73,99 @@ export interface ScheduleProps {
7273
* An EventBridge Schedule
7374
*/
7475
export class Schedule extends Resource implements ISchedule {
76+
/**
77+
* Return the given named metric for all schedules.
78+
*
79+
* @default - sum over 5 minutes
80+
*/
81+
public static metricAll(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric {
82+
return new cloudwatch.Metric({
83+
namespace: 'AWS/Scheduler',
84+
metricName,
85+
statistic: 'sum',
86+
...props,
87+
});
88+
}
89+
90+
/**
91+
* Metric for the number of invocations that were throttled across all schedules.
92+
*
93+
* @see https://docs.aws.amazon.com/scheduler/latest/UserGuide/scheduler-quotas.html
94+
*
95+
* @default - sum over 5 minutes
96+
*/
97+
public static metricAllThrottled(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
98+
return this.metricAll('InvocationThrottleCount', props);
99+
}
100+
101+
/**
102+
* Metric for all invocation attempts across all schedules.
103+
*
104+
* @default - sum over 5 minutes
105+
*/
106+
public static metricAllAttempts(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
107+
return this.metricAll('InvocationAttemptCount', props);
108+
}
109+
/**
110+
* Emitted when the target returns an exception after EventBridge Scheduler calls the target API across all schedules.
111+
*
112+
* @default - sum over 5 minutes
113+
*/
114+
public static metricAllErrors(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
115+
return this.metricAll('TargetErrorCount', props);
116+
}
117+
118+
/**
119+
* Metric for invocation failures due to API throttling by the target across all schedules.
120+
*
121+
* @default - sum over 5 minutes
122+
*/
123+
public static metricAllTargetThrottled(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
124+
return this.metricAll('TargetErrorThrottledCount', props);
125+
}
126+
127+
/**
128+
* Metric for dropped invocations when EventBridge Scheduler stops attempting to invoke the target after a schedule's retry policy has been exhausted.
129+
* Metric is calculated for all schedules.
130+
*
131+
* @default - sum over 5 minutes
132+
*/
133+
public static metricAllDropped(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
134+
return this.metricAll('InvocationDroppedCount', props);
135+
}
136+
137+
/**
138+
* Metric for invocations delivered to the DLQ across all schedules.
139+
*
140+
* @default - sum over 5 minutes
141+
*/
142+
public static metricAllSentToDLQ(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
143+
return this.metricAll('InvocationsSentToDeadLetterCount', props);
144+
}
145+
146+
/**
147+
* Metric for failed invocations that also failed to deliver to DLQ across all schedules.
148+
*
149+
* @default - sum over 5 minutes
150+
*/
151+
public static metricAllFailedToBeSentToDLQ(errorCode?: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric {
152+
if (errorCode) {
153+
return this.metricAll(`InvocationsFailedToBeSentToDeadLetterCount_${errorCode}`, props);
154+
}
155+
156+
return this.metricAll('InvocationsFailedToBeSentToDeadLetterCount', props);
157+
}
158+
159+
/**
160+
* Metric for delivery of failed invocations to DLQ when the payload of the event sent to the DLQ exceeds the maximum size allowed by Amazon SQS.
161+
* Metric is calculated for all schedules.
162+
*
163+
* @default - sum over 5 minutes
164+
*/
165+
public static metricAllSentToDLQTrunacted(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
166+
return this.metricAll('InvocationsSentToDeadLetterCount_Truncated_MessageSizeExceeded', props);
167+
}
168+
75169
/**
76170
* The schedule group associated with this schedule.
77171
*/

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.assets.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.template.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@
116116
}
117117
}
118118
}
119+
},
120+
"AllSchedulerErrorsAlarmA3246F8C": {
121+
"Type": "AWS::CloudWatch::Alarm",
122+
"Properties": {
123+
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
124+
"EvaluationPeriods": 1,
125+
"MetricName": "TargetErrorCount",
126+
"Namespace": "AWS/Scheduler",
127+
"Period": 300,
128+
"Statistic": "Sum",
129+
"Threshold": 1
130+
}
119131
}
120132
},
121133
"Parameters": {

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/manifest.json

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/tree.json

Lines changed: 32 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
22
import * as cdk from 'aws-cdk-lib';
3+
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
34
import * as iam from 'aws-cdk-lib/aws-iam';
45
import * as lambda from 'aws-cdk-lib/aws-lambda';
56
import * as scheduler from '../lib';
@@ -42,6 +43,12 @@ new scheduler.Schedule(stack, 'DisabledSchedule', {
4243
enabled: false,
4344
});
4445

46+
new cloudwatch.Alarm(stack, 'AllSchedulerErrorsAlarm', {
47+
metric: scheduler.Schedule.metricAllErrors(),
48+
threshold: 1,
49+
evaluationPeriods: 1,
50+
});
51+
4552
new IntegTest(app, 'integtest-schedule', {
4653
testCases: [stack],
4754
});

packages/@aws-cdk/aws-scheduler-alpha/test/schedule.test.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { App, Stack } from 'aws-cdk-lib';
1+
import { App, Stack, Duration } from 'aws-cdk-lib';
22

33
import { Template } from 'aws-cdk-lib/assertions';
44
import * as iam from 'aws-cdk-lib/aws-iam';
@@ -62,4 +62,43 @@ describe('Schedule', () => {
6262
State: 'DISABLED',
6363
});
6464
});
65+
66+
test('returns metric for delivery of failed invocations to DLQ', () => {
67+
// WHEN
68+
const metric = Schedule.metricAllFailedToBeSentToDLQ();
69+
70+
// THEN
71+
expect(metric.namespace).toEqual('AWS/Scheduler');
72+
expect(metric.metricName).toEqual('InvocationsFailedToBeSentToDeadLetterCount');
73+
expect(metric.dimensions).toBeUndefined();
74+
expect(metric.statistic).toEqual('Sum');
75+
expect(metric.period).toEqual(Duration.minutes(5));
76+
});
77+
78+
test('returns metric for delivery of failed invocations to DLQ for specific error code', () => {
79+
// WHEN
80+
const metric = Schedule.metricAllFailedToBeSentToDLQ('test_error_code');
81+
82+
// THEN
83+
expect(metric.namespace).toEqual('AWS/Scheduler');
84+
expect(metric.metricName).toEqual('InvocationsFailedToBeSentToDeadLetterCount_test_error_code');
85+
expect(metric.dimensions).toBeUndefined();
86+
expect(metric.statistic).toEqual('Sum');
87+
expect(metric.period).toEqual(Duration.minutes(5));
88+
});
89+
90+
test('returns metric for all errors with provided statistic and period', () => {
91+
// WHEN
92+
const metric = Schedule.metricAllErrors({
93+
statistic: 'Maximum',
94+
period: Duration.minutes(1),
95+
});
96+
97+
// THEN
98+
expect(metric.namespace).toEqual('AWS/Scheduler');
99+
expect(metric.metricName).toEqual('TargetErrorCount');
100+
expect(metric.dimensions).toBeUndefined();
101+
expect(metric.statistic).toEqual('Maximum');
102+
expect(metric.period).toEqual(Duration.minutes(1));
103+
});
65104
});

0 commit comments

Comments
 (0)