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(dynamodb): add metrics for dynamodb table #6149

Merged
merged 7 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 117 additions & 1 deletion packages/@aws-cdk/aws-dynamodb/lib/table.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as appscaling from '@aws-cdk/aws-applicationautoscaling';
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import * as iam from '@aws-cdk/aws-iam';
import { Aws, Construct, IResource, Lazy, RemovalPolicy, Resource, Stack } from '@aws-cdk/core';
import { CfnTable } from './dynamodb.generated';
Expand Down Expand Up @@ -236,6 +237,53 @@ export interface ITable extends IResource {
* @param grantee The principal to grant access to
*/
grantReadWriteData(grantee: iam.IGrantable): iam.Grant;

/**
* Metric for the number of Errors executing all Lambdas
*/
metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric;

/**
* Metric for the consumed read capacity units
*
* @param props properties of a metric
*/
metricConsumedReadCapacityUnits(props?: cloudwatch.MetricOptions): cloudwatch.Metric;

/**
* Metric for the consumed write capacity units
*
* @param props properties of a metric
*/
metricConsumedWriteCapacityUnits(props?: cloudwatch.MetricOptions): cloudwatch.Metric;

/**
* Metric for the system errors
*
* @param props properties of a metric
*/
metricSystemErrors(props?: cloudwatch.MetricOptions): cloudwatch.Metric;

/**
* Metric for the user errors
*
* @param props properties of a metric
*/
metricUserErrors(props?: cloudwatch.MetricOptions): cloudwatch.Metric;

/**
* Metric for the conditional check failed requests
*
* @param props properties of a metric
*/
metricConditionalCheckFailedRequests(props?: cloudwatch.MetricOptions): cloudwatch.Metric;

/**
* Metric for the successful request latency
*
* @param props properties of a metric
*/
metricSuccessfulRequestLatency(props?: cloudwatch.MetricOptions): cloudwatch.Metric;
}

/**
Expand Down Expand Up @@ -339,6 +387,74 @@ abstract class TableBase extends Resource implements ITable {
return this.grant(grantee, 'dynamodb:*');
}

/**
* Return the given named metric for this Table
*/
public metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric {
return new cloudwatch.Metric({
namespace: 'AWS/DynamoDB',
metricName,
dimensions: {
TableName: this.tableName,
},
...props
});
}

/**
* Metric for the consumed read capacity units this table
*
* @default sum over a minute
*/
public metricConsumedReadCapacityUnits(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
return this.metric('ConsumedReadCapacityUnits', { statistic: 'sum', ...props});
}

/**
* Metric for the consumed write capacity units this table
*
* @default sum over a minute
*/
public metricConsumedWriteCapacityUnits(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
return this.metric('ConsumedWriteCapacityUnits', { statistic: 'sum', ...props});
}

/**
* Metric for the system errors this table
*
* @default sum over a minute
*/
public metricSystemErrors(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
return this.metric('SystemErrors', { statistic: 'sum', ...props});
}

/**
* Metric for the user errors this table
*
* @default sum over a minute
*/
public metricUserErrors(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
return this.metric('UserErrors', { statistic: 'sum', ...props});
}

/**
* Metric for the conditional check failed requests this table
*
* @default sum over a minute
*/
public metricConditionalCheckFailedRequests(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
return this.metric('ConditionalCheckFailedRequests', { statistic: 'sum', ...props});
}

/**
* Metric for the successful request latency this table
*
* @default avg over a minute
*/
public metricSuccessfulRequestLatency(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
return this.metric('SuccessfulRequestLatency', { statistic: 'avg', ...props});
}

protected abstract get hasIndex(): boolean;
}

Expand Down Expand Up @@ -924,4 +1040,4 @@ export enum StreamViewType {
interface ScalableAttributePair {
scalableReadAttribute?: ScalableTableAttribute;
scalableWriteAttribute?: ScalableTableAttribute;
}
}
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-dynamodb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@
},
"dependencies": {
"@aws-cdk/aws-applicationautoscaling": "1.23.0",
"@aws-cdk/aws-cloudwatch": "1.23.0",
"@aws-cdk/aws-iam": "1.23.0",
"@aws-cdk/core": "1.23.0"
},
"homepage": "https://github.com/aws/aws-cdk",
"peerDependencies": {
"@aws-cdk/aws-applicationautoscaling": "1.23.0",
"@aws-cdk/aws-cloudwatch": "1.23.0",
"@aws-cdk/aws-iam": "1.23.0",
"@aws-cdk/core": "1.23.0"
},
Expand Down
117 changes: 117 additions & 0 deletions packages/@aws-cdk/aws-dynamodb/test/test.dynamodb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,123 @@ export = {
test.done();
},

'metrics': {
'Can use metricConsumedReadCapacityUnits on a Dynamodb Table'(test: Test) {
// GIVEN
const stack = new Stack();
const table = new Table(stack, 'Table', {
partitionKey: { name: 'id', type: AttributeType.STRING }
});

// THEN
test.deepEqual(stack.resolve(table.metricConsumedReadCapacityUnits()), {
period: { amount: 5, unit: { label: 'minutes', inSeconds: 60 } },
dimensions: { TableName: { Ref: 'TableCD117FA1' } },
namespace: 'AWS/DynamoDB',
metricName: 'ConsumedReadCapacityUnits',
statistic: 'Sum',
});

test.done();
},

'Can use metricConsumedWriteCapacityUnits on a Dynamodb Table'(test: Test) {
// GIVEN
const stack = new Stack();
const table = new Table(stack, 'Table', {
partitionKey: { name: 'id', type: AttributeType.STRING }
});

// THEN
test.deepEqual(stack.resolve(table.metricConsumedWriteCapacityUnits()), {
period: { amount: 5, unit: { label: 'minutes', inSeconds: 60 } },
dimensions: { TableName: { Ref: 'TableCD117FA1' } },
namespace: 'AWS/DynamoDB',
metricName: 'ConsumedWriteCapacityUnits',
statistic: 'Sum',
});

test.done();
},

'Can use metricSystemErrors on a Dynamodb Table'(test: Test) {
// GIVEN
const stack = new Stack();
const table = new Table(stack, 'Table', {
partitionKey: { name: 'id', type: AttributeType.STRING }
});

// THEN
test.deepEqual(stack.resolve(table.metricSystemErrors()), {
period: { amount: 5, unit: { label: 'minutes', inSeconds: 60 } },
dimensions: { TableName: { Ref: 'TableCD117FA1' } },
namespace: 'AWS/DynamoDB',
metricName: 'SystemErrors',
statistic: 'Sum',
});

test.done();
},

'Can use metricUserErrors on a Dynamodb Table'(test: Test) {
// GIVEN
const stack = new Stack();
const table = new Table(stack, 'Table', {
partitionKey: { name: 'id', type: AttributeType.STRING }
});

// THEN
test.deepEqual(stack.resolve(table.metricUserErrors()), {
period: { amount: 5, unit: { label: 'minutes', inSeconds: 60 } },
dimensions: { TableName: { Ref: 'TableCD117FA1' } },
namespace: 'AWS/DynamoDB',
metricName: 'UserErrors',
statistic: 'Sum',
});

test.done();
},

'Can use metricConditionalCheckFailedRequests on a Dynamodb Table'(test: Test) {
// GIVEN
const stack = new Stack();
const table = new Table(stack, 'Table', {
partitionKey: { name: 'id', type: AttributeType.STRING }
});

// THEN
test.deepEqual(stack.resolve(table.metricConditionalCheckFailedRequests()), {
period: { amount: 5, unit: { label: 'minutes', inSeconds: 60 } },
dimensions: { TableName: { Ref: 'TableCD117FA1' } },
namespace: 'AWS/DynamoDB',
metricName: 'ConditionalCheckFailedRequests',
statistic: 'Sum',
});

test.done();
},

'Can use metricSuccessfulRequestLatency on a Dynamodb Table'(test: Test) {
// GIVEN
const stack = new Stack();
const table = new Table(stack, 'Table', {
partitionKey: { name: 'id', type: AttributeType.STRING }
});

// THEN
test.deepEqual(stack.resolve(table.metricSuccessfulRequestLatency()), {
period: { amount: 5, unit: { label: 'minutes', inSeconds: 60 } },
dimensions: { TableName: { Ref: 'TableCD117FA1' } },
namespace: 'AWS/DynamoDB',
metricName: 'SuccessfulRequestLatency',
statistic: 'Average',
});

test.done();
},

},

'grants': {

'"grant" allows adding arbitrary actions associated with this table resource'(test: Test) {
Expand Down