(@aws-cdk/aws-lambda): Version.metric() function uses wrong metric options when the version is associated with an alias
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### The Issue
When the Lambda function version is associated with an alias, its `metric()` function (or other metric helper functions such as `metricErrors()` or `metricInvocations()`) uses the wrong values of `dimensions` property for the metrics. Consider the snippet below where we have a Lambda function and an alias:
```typescript
const lambdaFunction = new Function(this, "MyFunction", {
...
functionName: "MyFunctionName"
...
});
const alias = new Alias(this, "MyFunctionAlias", {
aliasName: "live",
version: lambdaFunction.currentVersion
});
return lambdaFunction.version.metricErrors();
```
That code will return a metric with a `dimensions` property like this:
```js
{
FunctionName: "MyFunctionName",
Resource: `arn:aws:lambda:us-west-2:123456789012:function:MyFunctionName:42`,
}
```
_(42 is the function version)_
In reality, the correct dimensions for function version's metrics should be like this:
```js
{
"FunctionName": "MyFunctionName",
"Resource': "MyFunctionName:live"
"ExecutedVersion": "42"
}
```
_(live is the name of the function alias)_
You can probably verify that by running using `ListMetrics` API of CloudWatch against `AWS/Lambda` namespace:
```js
❯ aws cloudwatch list-metrics --namespace AWS/Lambda --metric-name Errors --region=us-west-2
{
"Metrics": [
{
"Namespace": "AWS/Lambda",
"Dimensions": [
{
"Name": "FunctionName",
"Value": "MyFunctionName"
},
{
"Name": "ExecutedVersion",
"Value": "5"
},
{
"Name": "Resource",
"Value": "MyFunctionName:live"
}
],
"MetricName": "Errors"
}
]
}
```
---
**References:**
* Current implementation of [`metric()` function](https://github.com/aws/aws-cdk/blob/7966f8d48c4bff26beb22856d289f9d0c7e7081d/packages/%40aws-cdk/aws-lambda/lib/lambda-version.ts#L223-L235)
```
public metric(metricName: string, props: cloudwatch.MetricOptions = {}): cloudwatch.Metric {
// Metrics on Aliases need the "bare" function name, and the alias' ARN, this differs from the base behavior.
return super.metric(metricName, {
dimensions: {
FunctionName: this.lambda.functionName,
// construct the ARN from the underlying lambda so that alarms on an alias
// don't cause a circular dependency with CodeDeploy
// see: https://github.com/aws/aws-cdk/issues/2231
Resource: `${this.lambda.functionArn}:${this.version}`,
},
...props,
});
}
```
* AWS docs that briefly describes the `ExecutedVersion` dimension: https://docs.aws.amazon.com/lambda/latest/dg/monitoring-metrics.html
### The proposal
Users should be able to:
1. Pass an alias to `Version.metric*()` functions
2. Pass a function version to `Alias.metric*()` functions
Either case, the functions would return metrics with the same dimensions described above.
### Environment
- **CDK CLI Version:** `1.98.0 (build 79f4512)`
- **Module Version:** `1.98`
- **Node.js Version:** `v10.0.0`
- **OS:** all
- **Language (Version):** all
### Other information
Contributor guide
Research direction
Start with packages/@aws-cdk/aws-lambda/lib/lambda-version.ts, especially the metric() implementation linked in the issue, and review the AWS Lambda monitoring-metrics documentation. Reproduce the dimensions with a version associated with an alias, then check the metric helper behavior for both Version and Alias. Done means the returned metrics use the alias Resource and ExecutedVersion dimensions described in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, observability
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100