Reputation: 2200
I have a cdk stack with a DDB table created with some alarms over it. Now have successfully add a secondary index to it.
However, how can I programmatically list the secondary indexes that a table has and how can I get the metrics for it.
Background, we have a module which creates the alarms for our DDB tables. That module receives the cdk table object and creates some alarms over it using methods like metricConsumedWriteCapacityUnits
.
I want to extend that alarm creator module to also create alarms for the indexes of the table, for such I need to read the secondary indexes (more concretely a global one) to check if the table has any; and if it does then create the alarms. Those alarms should be over capacity consumption and throttled requests (but might be extended to other metrics).
Upvotes: 3
Views: 1445
Reputation: 2620
Given a table cdk object, how can I list the secondary indexes it has?
This is the tricky bit. The indexes are not available on the ITable
, only the CfnTable
. Getting from the ITable
to the CfnTable
can be done through table.node.defaultChild
. Then the variables with the indexes have to be resolved in the CDK stack.
Having retrieved the secondary indexes, how can I [know] if they are local or global?
This is the easy bit. The indexes are in separate variables, globalSecondaryIndexes
and localSecondaryIndexes
.
Having retrieved a global secondary index, how can I get the metrics associated with it; capacity usage and throttled requests?
By passing { GlobalSecondaryIndexName: <indexName> }
to the dimensions
parameter of the metric call.
Below is a class, based on something I just built for work, that does all of the above. It compiles and should even run (not 100% sure it will run because I removed some intermediate scaffolding from our solution and haven't tested this exact code).
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import * as dynamo from '@aws-cdk/aws-dynamodb';
import { Construct, Duration } from '@aws-cdk/core';
export class DynamoMonitor extends Construct {
private static getIndexNames(dynamoTable: dynamo.ITable) {
// pull the names of any indexes on the current table from construct
const table = dynamoTable.node.defaultChild as dynamo.CfnTable;
const indexes = dynamoTable.stack.resolve(table.globalSecondaryIndexes) as
Array<dynamo.CfnTable.GlobalSecondaryIndexProperty> | undefined;
const indexNames: string[] = [];
if (indexes) {
for (const index of indexes) {
indexNames.push(index.indexName);
}
}
return indexNames;
}
constructor(scope: Construct, id: string, dynamoTable: dynamo.ITable) {
super(scope, id);
const period = Duration.seconds(30);
const threshold = 50;
const evaluationPeriods = 5;
const indexNames = DynamoMonitor.getIndexNames(dynamoTable);
for (const indexName of indexNames) {
const throttleEvents = dynamoTable.metric('WriteThrottleEvents', {
period: period,
dimensions: { GlobalSecondaryIndexName: indexName },
statistic: cloudwatch.Statistic.SAMPLE_COUNT,
unit: cloudwatch.Unit.COUNT,
});
const consumedWriteCapacityUnits = dynamoTable.metricConsumedWriteCapacityUnits({
label: 'ConsumedWriteCapacityUnits',
dimensions: { GlobalSecondaryIndexName: indexName },
period: period,
statistic: cloudwatch.Statistic.SAMPLE_COUNT,
unit: cloudwatch.Unit.COUNT,
});
const throttleRate = new cloudwatch.MathExpression({
expression: '(throttleEvents/consumedWriteCapacityUnits) * 100',
label: 'WriteThrottleRate',
usingMetrics: {
throttleEvents: throttleEvents,
consumedWriteCapacityUnits: consumedWriteCapacityUnits,
},
});
throttleRate.createAlarm(this, `WriteIndex${indexName}ThrottleRateAlarm`, {
threshold: threshold,
evaluationPeriods: evaluationPeriods,
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
alarmDescription: 'this.description',
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
});
}
}
}
Upvotes: 1