Search code examples
amazon-cloudwatchaws-cdkaws-fargateaws-cdk-typescript

Converting AWS CloudWatch Metrics Insight query to CDK Metric


I am modifying the sample at https://github.com/cdk-patterns/serverless/tree/main/the-eventbridge-etl/typescript as I want to add a dashboard widget to my CloudFormation Stack that shows the Fargate vCPU usage. I have been able to upgrade the app to use CDK v2, and deployment/functionality has been confirmed. However, I cannot get the vCPU widget in the dashboard to show any data.

If I configure the widget manually, from within AWS CloudWatch's Source field, the query looks as follows:

{
    "metrics": [
        [ { "expression": "SELECT COUNT(ResourceCount) FROM SCHEMA(\"AWS/Usage\", Class,Resource,Service,Type) WHERE Service = 'Fargate' AND Resource = 'vCPU'", "label": "Query1", "id": "q1" } ],
        [ "AWS/Usage", "ResourceCount", "Service", "Fargate", "Type", "Resource", { "id": "m1" } ]
    ],
    "view": "timeSeries",
    "title": "ExtractECSJob",
    "region": "us-west-2",
    "timezone": "Local",
    "stat": "Sum",
    "period": 300
}

However, when I attempt to use CDK, with the following TypeScript code:

        const extractECSWidget = new GraphWidget({
            title: "ExtractECSJob",
            left: [
                new Metric({
                    namespace: "AWS/Usage",
                    metricName: "ResourceCount",
                    statistic: "Sum",
                    period: Duration.seconds(300),
                    dimensionsMap: {
                        "Service": "Fargate",
                        "Type": "Resource",
                        "Resource": "vCPU"
                    }
                })
            ]
        });

This does not translate to the above, and no information is shown in this widget. The new source looks as follows:

{
    "view": "timeSeries",
    "title": "ExtractECSJob",
    "region": "us-west-2",
    "metrics": [
        [ "AWS/Usage", "ResourceCount", "Resource", "vCPU", "Service", "Fargate", "Type", "Resource", { "stat": "Sum" } ]
    ],
    "period": 300
}

How do I map the above metrics source definition to the CDK source construct?

I tried using MathExpression but with the following:

        let metrics = new MathExpression({
            expression: "SELECT COUNT('metricName') FROM SCHEMA('\"AWS/Usage\"', 'Class','Resource','Service','Type') WHERE Service = 'Fargate' AND Resource = 'vCPU'",
            usingMetrics: {}
        })

        const extractECSWidget = new GraphWidget({
            title: "ExtractECSJob",
            left: [
                metrics
            ]
        });

I get the warning during cdk diff:

[Warning at /EventbridgeEtlStack/EventBridgeETLDashboard] Math expression 'SELECT COUNT(metricName) FROM SCHEMA($namespace, Class,Resource,Service,Type) WHERE Service = 'Fargate' AND Resource = 'vCPU'' references unknown identifiers: metricName, namespace, lass, esource, ervice, ype, ervice, argate, esource, vCPU. Please add them to the 'usingMetrics' map.

What should I put in the usingMetrics map? Any help is appreciated.


Solution

  • Thanks to AWS Support I was able to have this fixed. The updated code looks like the following:

            let metrics = new MathExpression({
                expression: "SELECT COUNT(ResourceCount) FROM SCHEMA(\"AWS/Usage\", Class,Resource,Service,Type) WHERE Service = 'Fargate' AND Resource = 'vCPU'",
                usingMetrics: {},
                label: "Query1"
            })
    
            let metric2 = new Metric({
                namespace: "AWS/Usage",
                metricName: "ResourceCount",
                period: cdk.Duration.seconds(300),
                dimensionsMap: {
                    "Service": "Fargate",
                    "Type": "Resource",
                }
            })
    
            const extractECSWidget = new GraphWidget({
                title: "ExtractECSJobTest",
                left: [metrics, metric2],
                region: "us-west-2",
                statistic: "Sum",
                width: 24
            });
    
            dashboardStack.addWidgets(
                extractECSWidget
            );
    

    When running cdk deploy, I still get the same warning (about unknown identifiers being referenced) but the widget is functioning as expected.