• Stars
    star
    456
  • Rank 95,985 (Top 2 %)
  • Language
    TypeScript
  • License
    Apache License 2.0
  • Created over 2 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Easy-to-use CDK constructs for monitoring your AWS infrastructure

CDK Monitoring Constructs

NPM version Maven Central PyPI version NuGet version Gitpod Ready-to-Code Mergify

Easy-to-use CDK constructs for monitoring your AWS infrastructure with Amazon CloudWatch.

  • Easily add commonly-used alarms using predefined properties
  • Generate concise CloudWatch dashboards that indicate your alarms
  • Extend the library with your own extensions or custom metrics
  • Consume the library in multiple supported languages

Installation

TypeScript

https://www.npmjs.com/package/cdk-monitoring-constructs

In your package.json:

{
  "dependencies": {
    "cdk-monitoring-constructs": "^5.0.0",

    // peer dependencies of cdk-monitoring-constructs
    "@aws-cdk/aws-apigatewayv2-alpha": "^2.65.0-alpha.0",
    "@aws-cdk/aws-redshift-alpha": "^2.65.0-alpha.0",
    "@aws-cdk/aws-synthetics-alpha": "^2.65.0-alpha.0",
    "aws-cdk-lib": "^2.65.0",
    "constructs": "^10.0.5"

    // ...your other dependencies...
  }
}
Java

See https://mvnrepository.com/artifact/io.github.cdklabs/cdkmonitoringconstructs

Python

See https://pypi.org/project/cdk-monitoring-constructs/

C#

See https://www.nuget.org/packages/Cdklabs.CdkMonitoringConstructs/

Features

You can browse the documentation at https://constructs.dev/packages/cdk-monitoring-constructs/

Item Monitoring Alarms Notes
AWS API Gateway (REST API) (.monitorApiGateway()) TPS, latency, errors Latency, error count/rate, low/high TPS To see metrics, you have to enable Advanced Monitoring
AWS API Gateway V2 (HTTP API) (.monitorApiGatewayV2HttpApi()) TPS, latency, errors Latency, error count/rate, low/high TPS To see route level metrics, you have to enable Advanced Monitoring
AWS AppSync (GraphQL API) (.monitorAppSyncApi()) TPS, latency, errors Latency, error count/rate, low/high TPS
AWS Billing (.monitorBilling()) AWS account cost Total cost (anomaly) Requires enabling the Receive Billing Alerts option in AWS Console / Billing Preferences
AWS Certificate Manager (.monitorCertificate()) Certificate expiration Days until expiration
AWS CloudFront (.monitorCloudFrontDistribution()) TPS, traffic, latency, errors Error rate, low/high TPS
AWS CloudWatch Logs (.monitorLog()) Patterns present in the log group Minimum incoming logs
AWS CloudWatch Synthetics Canary (.monitorSyntheticsCanary()) Latency, error count/rate Error count/rate, latency
AWS CodeBuild (.monitorCodeBuildProject()) Build counts (total, successful, failed), failed rate, duration Failed build count/rate, duration
AWS DocumentDB (.monitorDocumentDbCluster()) CPU, throttling, read/write latency, transactions, cursors CPU
AWS DynamoDB (.monitorDynamoTable()) Read and write capacity provisioned / used Consumed capacity, throttling, latency, errors
AWS DynamoDB Global Secondary Index (.monitorDynamoTableGlobalSecondaryIndex()) Read and write capacity, indexing progress, throttled events
AWS EC2 (.monitorEC2Instances()) CPU, disk operations, network
AWS EC2 Auto Scaling Groups (.monitorAutoScalingGroup()) Group size, instance status
AWS ECS (.monitorFargateService(), .monitorEc2Service(), .monitorSimpleFargateService(), monitorSimpleEc2Service(), .monitorQueueProcessingFargateService(), .monitorQueueProcessingEc2Service()) System resources and task health Unhealthy task count, running tasks count, CPU/memory usage, and bytes processed by load balancer (if any) Use for ecs-patterns load balanced ec2/fargate constructs (NetworkLoadBalancedEc2Service, NetworkLoadBalancedFargateService, ApplicationLoadBalancedEc2Service, ApplicationLoadBalancedFargateService)
AWS ElastiCache (.monitorElastiCacheCluster()) CPU/memory usage, evictions and connections CPU, memory, items count
AWS Glue (.monitorGlueJob()) Traffic, job status, memory/CPU usage Failed/killed task count/rate
AWS Kinesis Data Analytics (.monitorKinesisDataAnalytics) Up/Downtime, CPU/memory usage, KPU usage, checkpoint metrics, and garbage collection metrics Downtime, full restart count
AWS Kinesis Data Stream (.monitorKinesisDataStream()) Put/Get/Incoming Record/s and Throttling Throttling, throughput, iterator max age
AWS Kinesis Firehose (.monitorKinesisFirehose()) Number of records, requests, latency, throttling Throttling
AWS Lambda (.monitorLambdaFunction()) Latency, errors, iterator max age Latency, errors, throttles, iterator max age Optional Lambda Insights metrics (opt-in) support
AWS Load Balancing (.monitorNetworkLoadBalancer(), .monitorFargateApplicationLoadBalancer(), .monitorFargateNetworkLoadBalancer(), .monitorEc2ApplicationLoadBalancer(), .monitorEc2NetworkLoadBalancer()) System resources and task health Unhealthy task count, running tasks count, (for Fargate/Ec2 apps) CPU/memory usage Use for FargateService or Ec2Service backed by a NetworkLoadBalancer or ApplicationLoadBalancer
AWS OpenSearch/Elasticsearch (.monitorOpenSearchCluster(), .monitorElasticsearchCluster()) Indexing and search latency, disk/memory/CPU usage Indexing and search latency, disk/memory/CPU usage, cluster status, KMS keys
AWS RDS (.monitorRdsCluster()) Query duration, connections, latency, disk/CPU usage Connections, disk and CPU usage
AWS Redshift (.monitorRedshiftCluster()) Query duration, connections, latency, disk/CPU usage Query duration, connections, disk and CPU usage
AWS S3 Bucket (.monitorS3Bucket()) Bucket size and number of objects
AWS SecretsManager (.monitorSecretsManager()) Max secret count, min secret sount, secret count change Min/max secret count or change in secret count
AWS SecretsManager Secret (.monitorSecretsManagerSecret()) Days since last rotation Days since last change or rotation
AWS SNS Topic (.monitorSnsTopic()) Message count, size, failed notifications Failed notifications, min/max published messages
AWS SQS Queue (.monitorSqsQueue(), .monitorSqsQueueWithDlq()) Message count, age, size Message count, age, DLQ incoming messages
AWS Step Functions (.monitorStepFunction(), .monitorStepFunctionActivity(), monitorStepFunctionLambdaIntegration(), .monitorStepFunctionServiceIntegration()) Execution count and breakdown per state Duration, failed, failed rate, aborted, throttled, timed out executions
AWS Web Application Firewall (.monitorWebApplicationFirewallAclV2()) Allowed/blocked requests Blocked requests count/rate
Custom metrics (.monitorCustom()) Addition of custom metrics into the dashboard (each group is a widget) Supports anomaly detection

Getting started

Create a facade

Important note: Please, do NOT import anything from the /dist/lib package. This is unsupported and might break any time.

  1. Create an instance of MonitoringFacade, which is the main entrypoint.
  2. Call methods on the facade like .monitorLambdaFunction() and chain them together to define your monitors. You can also use methods to add your own widgets, headers of various sizes, and more.

For examples of monitoring different resources, refer to the unit tests.

export interface MonitoringStackProps extends DeploymentStackProps {
  // ...
}

// This could be in the same stack as your resources, as a nested stack, or a separate stack as you see fit
export class MonitoringStack extends DeploymentStack {
  constructor(parent: App, name: string, props: MonitoringStackProps) {
    super(parent, name, props);

    const monitoring = new MonitoringFacade(this, "Monitoring", {
      // Defaults are provided for these, but they can be customized as desired
      metricFactoryDefaults: { ... },
      alarmFactoryDefaults: { ... },
      dashboardFactory: { ... },
    });

    // Monitor your resources
    monitoring
      .addLargeHeader("Storage")
      .monitorDynamoTable({ /* Monitor a DynamoDB table */ })
      .monitorDynamoTable({ /* and a different table */ })
      .monitorLambdaFunction({ /* and a Lambda function */ })
      .monitorCustom({ /* and some arbitrary metrics in CloudWatch */ })
      // ... etc.
  }
}

Customize actions

Alarms should have an action setup, otherwise they are not very useful. Currently, we support notifying an SNS queue.

const onAlarmTopic = new Topic(this, "AlarmTopic");

const monitoring = new MonitoringFacade(this, "Monitoring", {
  // ...other props
  alarmFactoryDefaults: {
    // ....other props
    action: new SnsAlarmActionStrategy({ onAlarmTopic }),
  },
});

You can override the default topic for any alarm like this:

monitoring
  .monitorSomething(something, {
    addSomeAlarm: {
      Warning: {
        // ...other props
        threshold: 42,
        actionOverride: new SnsAlarmActionStrategy({ onAlarmTopic }),
      }
    }
  });

Custom metrics

For simply adding some custom metrics, you can use .monitorCustom() and specify your own title and metric groups. Each metric group will be rendered as a single graph widget, and all widgets will be placed next to each other. All the widgets will have the same size, which is chosen based on the number of groups to maximize dashboard space usage.

Custom metric monitoring can be created for simple metrics, simple metrics with anomaly detection and search metrics. The first two also support alarming.

Below we are listing a couple of examples. Let us assume that there are three existing metric variables: m1, m2, m3. They can either be created by hand (new Metric({...})) or (preferably) by using metricFactory (that can be obtained from facade). The advantage of using the shared metricFactory is that you do not need to worry about period, etc.

// create metrics manually
const m1 = new Metric(/* ... */);
const metricFactory = monitoringFacade.createMetricFactory();

// create metrics using metric factory
const m1 = metricFactory.createMetric(/* ... */);

Example: metric with anomaly detection

In this case, only one metric is supported. Multiple metrics cannot be rendered with anomaly detection in a single widget due to a CloudWatch limitation.

monitorCustom({
  title: "Metric with anomaly detection",
  metrics: [
    {
      metric: m1,
      anomalyDetectionStandardDeviationToRender: 3
    }
  ]
})

Adding an alarm:

monitorCustom({
  title: "Metric with anomaly detection and alarm",
  metrics: [
    {
      metric: m1,
      alarmFriendlyName: "MetricWithAnomalyDetectionAlarm",
      anomalyDetectionStandardDeviationToRender: 3,
      addAlarmOnAnomaly: {
        Warning: {
          standardDeviationForAlarm: 4,
          alarmWhenAboveTheBand: true,
          alarmWhenBelowTheBand: true
        }
      }
    }
  ]
})

Example: search metrics

monitorCustom({
  title: "Metric search",
  metrics: [
    {
      searchQuery: "My.Prefix.",
      dimensionsMap: {
        FirstDimension: "FirstDimensionValue",
        // Allow any value for the given dimension (pardon the weird typing to satisfy DimensionsMap)
        SecondDimension: undefined as unknown as string
      }
      statistic: MetricStatistic.SUM,
    }
  ]
})

Search metrics do not support setting an alarm, which is a CloudWatch limitation.

Route53 Health Checks

Route53 has strict requirements as to which alarms are allowed to be referenced in Health Checks. You adjust the metric for an alarm sot hat it can be used in a Route53 Health Checks as follows:

monitoring
  .monitorSomething(something, {
    addSomeAlarm: {
      Warning: {
        // ...other props
        metricAdjuster: Route53HealthCheckMetricAdjuster.INSTANCE,
      }
    }
  });

This will ensure the alarm can be used on a Route53 Health Check or otherwise throw an Error indicating why the alarm can't be used. In order to easily find your Route53 Health Check alarms later on, you can apply a custom tag to them as follows:

import { CfnHealthCheck } from "aws-cdk-lib/aws-route53";

monitoring
  .monitorSomething(something, {
    addSomeAlarm: {
      Warning: {
        // ...other props
        customTags: ["route53-health-check"],
        metricAdjuster: Route53HealthCheckMetricAdjuster.INSTANCE,
      }
    }
  });

const alarms = monitoring.createdAlarmsWithTag("route53-health-check");

const healthChecks = alarms.map(({ alarm }) => {
  const id = getHealthCheckConstructId(alarm);

  return new CfnHealthCheck(scope, id, {
    healthCheckConfig: {
      // ...other props
      type: "CLOUDWATCH_METRIC",
      alarmIdentifier: {
        name: alarm.alarmName,
        region: alarm.stack.region,
      },
    },
  });
});

Custom monitoring segments

If you want even more flexibility, you can create your own segment.

This is a general procedure on how to do it:

  1. Extend the Monitoring class
  2. Override the widgets() method (and/or similar ones)
  3. Leverage the metric factory and alarm factory provided by the base class (you can create additional factories, if you will)
  4. Add all alarms to .addAlarm() so they are visible to the user and being placed on the alarm summary dashboard

Both of these monitoring base classes are dashboard segments, so you can add them to your monitoring by calling .addSegment() on the MonitoringFacade.

Custom dashboards

If you want even more flexibility, you can take complete control over dashboard generation by leveraging dynamic dashboarding features. This allows you to create an arbitrary number of dashboards while configuring each of them separately. You can do this in three simple steps:

  1. Create a dynamic dashboard factory
  2. Create IDynamicDashboardSegment implementations
  3. Add Dynamic Segments to your MonitoringFacade

Create a dynamic dashboard factory

The below code sample will generate two dashboards with the following names:

  • ExampleDashboards-HostedService
  • ExampleDashboards-Infrastructure
// create the dynamic dashboard factory.
const factory = new DynamicDashboardFactory(stack, "DynamicDashboards", {
  dashboardNamePrefix: "ExampleDashboards",
  dashboardConfigs: [
    // 'name' is the minimum required configuration
    { name: "HostedService" },
    // below is an example of additional dashboard-specific config options
    {
      name: "Infrastructure",
      range: Duration.hours(3),
      periodOverride: PeriodOverride.AUTO,
      renderingPreference: DashboardRenderingPreference.BITMAP_ONLY
    },
  ],
});

Create IDynamicDashboardSegment implementations

For each construct you want monitored, you will need to create an implementation of an IDynamicDashboardSegment. The following is a basic reference implementation as an example:

export enum DashboardTypes {
  HostedService = "HostedService",
  Infrastructure = "Infrastructure",
}

class ExampleSegment implements IDynamicDashboardSegment {
  widgetsForDashboard(name: string): IWidget[] {
    // this logic is what's responsible for allowing your dynamic segment to return
    // different widgets for different dashboards
    switch (name) {
      case DashboardTypes.HostedService:
        return [new TextWidget({ markdown: "This shows metrics for your service hosted on AWS Infrastructure" })];
      case DashboardTypes.Infrastructure:
        return [new TextWidget({ markdown: "This shows metrics for the AWS Infrastructure supporting your hosted service" })];
      default:
        throw new Error("Unexpected dashboard name!");
    }
  }
}

Add Dynamic Segments to MonitoringFacade

When you have instances of an IDynamicDashboardSegment to use, they can be added to your dashboard like this:

monitoring.addDynamicSegment(new ExampleSegment());

Now, this widget will be added to both dashboards and will show different content depending on the dashboard. Using the above example code, two dashboards will be generated with the following content:

  • Dashboard Name: "ExampleDashboards-HostedService"
    • Content: "This shows metrics for your service hosted on AWS Infrastructure"
  • Dashboard Name: "ExampleDashboards-Infrastructure"
    • Content: "This shows metrics for the AWS Infrastructure supporting your hosted service"

Monitoring scopes

You can monitor complete CDK construct scopes using an aspect. It will automatically discover all monitorable resources within the scope recursively and add them to your dashboard.

monitoring.monitorScope(stack, {
  // With optional configuration
  lambda: {
    props: {
      addLatencyP50Alarm: {
        Critical: { maxLatency: Duration.seconds(10) },
      },
    },
  },

  // Some resources that aren't dependent on nodes (e.g. general metrics across instances/account) may be included
  // by default, which can be explicitly disabled.
  billing: { enabled: false },
  ec2: { enabled: false },
  elasticCache: { enabled: false },
});

Contributing/Security

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.

More Repositories

1

cdk-nag

Check CDK applications for best practices using a combination of available rule packs
TypeScript
782
star
2

cdk-watchful

Watching what's up with your CDK apps since 2019
TypeScript
531
star
3

aws-delivlib

setup and manage continuous delivery pipelines for code libraries in multiple languages
TypeScript
372
star
4

cdk-pipelines-github

TypeScript
321
star
5

construct-hub

AWS CDK construct library that can be used to deploy instances of the Construct Hub in any AWS Account.
TypeScript
200
star
6

cdk-ecr-deployment

A CDK construct to deploy docker image to Amazon ECR
Go
152
star
7

cdk-dynamo-table-viewer

A CDK construct which exposes an endpoint with the contents of a DynamoDB table
TypeScript
124
star
8

cdk-stacksets

TypeScript
80
star
9

cdk-docker-image-deployment

TypeScript
75
star
10

cdk-triggers

TypeScript
73
star
11

cdk-validator-cfnguard

TypeScript
67
star
12

cdk-cloudformation

TypeScript
60
star
13

decdk

Define AWS CDK applications declaratively
TypeScript
60
star
14

cdk-ecs-service-extensions

TypeScript
59
star
15

cdk-from-cfn

A cloudformation json -> cdk typescript transpiler.
Rust
58
star
16

cdk-import

Generates CDK level 1 constructs for public CloudFormation Registry types and modules
TypeScript
52
star
17

cdk-app-cli

The operator CLI for CDK apps.
TypeScript
52
star
18

publib

A unified toolchain for publishing libraries to popular package managers (formally jsii-release)
TypeScript
52
star
19

cdk-drift-monitor

Monitors for CloudFormation stack drifts.
TypeScript
48
star
20

jsii-docgen

Generates reference documentation for jsii modules
TypeScript
48
star
21

aws-cdk-testing-examples

Java
39
star
22

cdk-ecs-codedeploy

TypeScript
34
star
23

cdk-enterprise-iac

Utilities for using CDK within enterprise constraints
TypeScript
33
star
24

cdk-tweet-queue

SQS queue fed with a stream of tweets from a Twitter search
TypeScript
29
star
25

cdk-ssm-documents

TypeScript
27
star
26

awscdk-service-spec

TypeScript
25
star
27

awscdk-appsync-utils

TypeScript
24
star
28

aws-secrets-github-sync

Sync GitHub repository secrets from AWS Secrets Manager
TypeScript
22
star
29

cdk-amazon-chime-resources

TypeScript
22
star
30

construct-hub-webapp

React web app for Construct Hub
TypeScript
21
star
31

json2jsii

Generates jsii-compatible structs from JSON schemas
TypeScript
20
star
32

node-sscaff

Stupid scaffolding: copies an entire directory with variable substitution
TypeScript
20
star
33

cdk-cicd-wrapper

This repository contains the infrastructure as code to wrap your AWS CDK project with CI/CD around it.
TypeScript
20
star
34

jsii-srcmak

Generate multi-language object-oriented source code from typescript
TypeScript
19
star
35

awscdk-v1-stack-finder

TypeScript
18
star
36

awscdk-asset-kubectl

TypeScript
18
star
37

cdk-skylight

CDK Skylight is a set of Level 3 constructs for the Microsoft products on AWS
TypeScript
17
star
38

markmac

Embed program outputs in markdown
TypeScript
17
star
39

cdk-verified-permissions

Amazon Verified Permissions L2 CDK Constructs
TypeScript
16
star
40

awscdk-change-analyzer

A toolkit that analyzes the differences between two cloud infrastructures states.
HTML
13
star
41

cdk-ethereum-node

CDK construct to deploy an Ethereum node running on Amazon Managed Blockchain
TypeScript
11
star
42

aws-lambda-rust

TypeScript
10
star
43

cdk-appflow

This repository contains L2 AWS CDK constructs for Amazon AppFlow
TypeScript
9
star
44

aws-cdk-notices

Static website for the distribution of notices to AWS CDK users.
TypeScript
8
star
45

cdk-hyperledger-fabric-network

CDK construct to deploy a Hyperledger Fabric network running on Amazon Managed Blockchain
TypeScript
7
star
46

cfn-resources

TypeScript
7
star
47

cdk-nag-go

cdk-nag bindings for Go.
Go
7
star
48

awscdk-asset-awscli

TypeScript
7
star
49

cdk-codepipeline-extensions

Go
7
star
50

cdk-aws-sagemaker-role-manager

Create roles and policies for ML Activities and ML Personas
TypeScript
6
star
51

cdklabs-projen-project-types

TypeScript
6
star
52

cdk-golden-signals-dashboard

TypeScript
6
star
53

awscdk-lambda-dotnet

TypeScript
5
star
54

cdk-deployer

A CDK construct library for deploying artifacts via CodeDeploy.
TypeScript
4
star
55

awscdk-dynamodb-global-tables

TypeScript
4
star
56

node-backpack

TypeScript
3
star
57

cfunctions

TypeScript
3
star
58

cdk-dynamo-table-viewer-go

A CDK construct which exposes an endpoint with the contents of a DynamoDB table Topics Resources License
Go
3
star
59

cdk-cdk8s-reinvent-2021

Java
2
star
60

construct-hub-probe

Probe package intended to test construct hub instances
TypeScript
2
star
61

construct-hub-cli

TypeScript
1
star
62

cdk-assets

TypeScript
1
star
63

cloud-assembly-schema

TypeScript
1
star
64

cdk-ecs-codedeploy-go

Go
1
star
65

cdk-generate-synthetic-examples

Find all classes in the JSII assembly that don't yet have any example code associated with them, and generate a synthetic example that shows how to instantiate the type.
TypeScript
1
star
66

cdk-ecs-service-extensions-go

Go
1
star
67

cdk-aws-sagemaker-role-manager-go

Go
1
star