Skip to content

Commit d4116ea

Browse files
author
Eugene Cheung
authored
feat: handle cross-account/region for metric math, search, and anomaly detection in MetricFactory (#415)
This expands on what was implemented in #311, which only handled regular metrics via `createMetric`. --- _By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_
1 parent 694a6e9 commit d4116ea

File tree

9 files changed

+707
-209
lines changed

9 files changed

+707
-209
lines changed

API.md

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

lib/common/metric/MetricFactory.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,26 @@ export class MetricFactory {
108108
* @param label metric label (required, as there is no reasonable default)
109109
* @param color metric color; if undefined, uses a CloudWatch provided color (preferred)
110110
* @param period specify a custom period; if undefined, uses the global default
111+
* @param region specify a custom region; if undefined, uses the global default
112+
* @param account specify a custom account; if undefined, uses the global default
111113
*/
112114
createMetricMath(
113115
expression: string,
114116
usingMetrics: Record<string, IMetric>,
115117
label: string,
116118
color?: string,
117-
period?: Duration
119+
period?: Duration,
120+
region?: string,
121+
account?: string
118122
): MetricWithAlarmSupport {
119123
return new MathExpression({
120124
label,
121125
color,
122126
expression,
123127
usingMetrics,
124128
period: period ?? this.globalDefaults.period ?? DefaultMetricPeriod,
129+
searchRegion: region ?? this.globalDefaults.region,
130+
searchAccount: account ?? this.globalDefaults.account,
125131
});
126132
}
127133

@@ -136,14 +142,18 @@ export class MetricFactory {
136142
* @param namespace specify a custom namespace; if undefined, uses the global default
137143
* @param label specify custom label for search metrics; default is " " as it cannot be empty string
138144
* @param period specify a custom period; if undefined, uses the global default
145+
* @param region specify a custom region; if undefined, uses the global default
146+
* @param account specify a custom account; if undefined, uses the global default
139147
*/
140148
createMetricSearch(
141149
query: string,
142150
dimensionsMap: DimensionsMap,
143151
statistic: MetricStatistic,
144152
namespace?: string,
145153
label?: string,
146-
period?: Duration
154+
period?: Duration,
155+
region?: string,
156+
account?: string
147157
): IMetric {
148158
const finalPeriod =
149159
period ?? this.globalDefaults.period ?? DefaultMetricPeriod;
@@ -169,6 +179,8 @@ export class MetricFactory {
169179
// cannot be an empty string and undefined is no good either
170180
label: label ?? " ",
171181
period: finalPeriod,
182+
searchRegion: region ?? this.globalDefaults.region,
183+
searchAccount: account ?? this.globalDefaults.account,
172184
});
173185
}
174186

@@ -185,14 +197,18 @@ export class MetricFactory {
185197
* @param color metric color; if undefined, uses a CloudWatch provided color (preferred)
186198
* @param expressionId expression ID of the metric; uses `m1` if undefined
187199
* @param period specify a custom period; if undefined, uses the global default
200+
* @param region specify a custom region; if undefined, uses the global default
201+
* @param account specify a custom account; if undefined, uses the global default
188202
*/
189203
createMetricAnomalyDetection(
190204
metric: IMetric,
191205
stdev: number,
192206
label: string,
193207
color?: string,
194208
expressionId?: string,
195-
period?: Duration
209+
period?: Duration,
210+
region?: string,
211+
account?: string
196212
): MetricWithAlarmSupport {
197213
const finalExpressionId = expressionId ?? "m1";
198214
const usingMetrics: Record<string, IMetric> = {};
@@ -203,6 +219,8 @@ export class MetricFactory {
203219
usingMetrics,
204220
expression: `ANOMALY_DETECTION_BAND(${finalExpressionId},${stdev})`,
205221
period: period ?? this.globalDefaults.period ?? DefaultMetricPeriod,
222+
searchRegion: region ?? this.globalDefaults.region,
223+
searchAccount: account ?? this.globalDefaults.account,
206224
});
207225
}
208226

lib/common/metric/XaxrMathExpression.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ export interface XaxrMathExpressionProps extends MathExpressionProps {
2828
readonly region?: string;
2929
}
3030

31+
// TODO: remove this as a breaking change
3132
/**
3233
* Custom wrapper class for MathExpression that supports account and region specification.
3334
* @see https://github.com/aws/aws-cdk/issues/9039
35+
*
36+
* @deprecated Use MathExpression from aws-cdk-lib/aws-cloudwatch instead.
3437
*/
3538
export class XaxrMathExpression implements IMetric {
3639
private props: XaxrMathExpressionProps;
@@ -41,22 +44,22 @@ export class XaxrMathExpression implements IMetric {
4144
this.mathExpression = new MathExpression(props);
4245
}
4346

47+
/**
48+
* @deprecated Use MathExpression from aws-cdk-lib/aws-cloudwatch instead.
49+
*/
4450
with(options: MathExpressionOptions): IMetric {
45-
return new XaxrMathExpression({
51+
return new MathExpression({
4652
...this.props,
4753
...options,
54+
searchAccount: this.props.account,
55+
searchRegion: this.props.region,
4856
});
4957
}
5058

59+
/**
60+
* @deprecated Use MathExpression from aws-cdk-lib/aws-cloudwatch instead.
61+
*/
5162
toMetricConfig(): MetricConfig {
52-
const defaultMetricConfig = this.mathExpression.toMetricConfig();
53-
return {
54-
...defaultMetricConfig,
55-
renderingProperties: {
56-
...defaultMetricConfig.renderingProperties,
57-
accountId: this.props.account,
58-
region: this.props.region,
59-
},
60-
};
63+
return this.mathExpression.toMetricConfig();
6164
}
6265
}

lib/monitoring/aws-billing/BillingMetricFactory.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import { Duration } from "aws-cdk-lib";
2-
import { IMetric, Metric } from "aws-cdk-lib/aws-cloudwatch";
2+
import { IMetric, MathExpression, Metric } from "aws-cdk-lib/aws-cloudwatch";
33

4-
import {
5-
MetricStatistic,
6-
MetricWithAlarmSupport,
7-
XaxrMathExpression,
8-
} from "../../common";
4+
import { MetricStatistic, MetricWithAlarmSupport } from "../../common";
95

106
export const BillingRegion = "us-east-1";
117
export const BillingCurrency = "USD";
@@ -17,20 +13,17 @@ const DefaultServiceLimit = 10;
1713

1814
export class BillingMetricFactory {
1915
metricSearchTopCostByServiceInUsd(): IMetric {
20-
// standard MathExpression class does not support region
21-
// TODO: revisit after migration to CDK 1.126.0
22-
23-
const search = new XaxrMathExpression({
16+
const search = new MathExpression({
2417
period: BillingPeriod,
25-
region: BillingRegion,
18+
searchRegion: BillingRegion,
2619
expression: `SEARCH('{${BillingNamespace},Currency,ServiceName} MetricName="${BillingMetric}"', 'Maximum', ${BillingPeriod.toSeconds()})`,
2720
usingMetrics: {},
2821
label: " ",
2922
});
3023

31-
return new XaxrMathExpression({
24+
return new MathExpression({
3225
period: BillingPeriod,
33-
region: BillingRegion,
26+
searchRegion: BillingRegion,
3427
expression: `SORT(search, MAX, DESC, ${DefaultServiceLimit})`,
3528
usingMetrics: { search },
3629
label: " ",

0 commit comments

Comments
 (0)