cdk-monitoring-constructs


Namecdk-monitoring-constructs JSON
Version 9.4.0 PyPI version JSON
download
home_pagehttps://github.com/cdklabs/cdk-monitoring-constructs
Summarycdk-monitoring-constructs
upload_time2025-03-21 14:11:47
maintainerNone
docs_urlNone
authorCDK Monitoring Constructs Team<monitoring-cdk-constructs@amazon.com>
requires_python~=3.8
licenseApache-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # CDK Monitoring Constructs

[![NPM version](https://badge.fury.io/js/cdk-monitoring-constructs.svg)](https://badge.fury.io/js/cdk-monitoring-constructs)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.cdklabs/cdkmonitoringconstructs/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.cdklabs/cdkmonitoringconstructs)
[![PyPI version](https://badge.fury.io/py/cdk-monitoring-constructs.svg)](https://badge.fury.io/py/cdk-monitoring-constructs)
[![NuGet version](https://badge.fury.io/nu/Cdklabs.CdkMonitoringConstructs.svg)](https://badge.fury.io/nu/Cdklabs.CdkMonitoringConstructs)
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs)
[![Mergify](https://img.shields.io/endpoint.svg?url=https://gh.mergify.io/badges/cdklabs/cdk-monitoring-constructs&style=flat)](https://mergify.io)

Easy-to-use CDK constructs for monitoring your AWS infrastructure with [Amazon CloudWatch](https://aws.amazon.com/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

<details><summary><strong>TypeScript</strong></summary>

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

In your `package.json`:

```json
{
  "dependencies": {
    "cdk-monitoring-constructs": "^9.0.0",

    // peer dependencies of cdk-monitoring-constructs
    "aws-cdk-lib": "^2.160.0",
    "constructs": "^10.0.5"

    // ...your other dependencies...
  }
}
```

</details><details><summary><strong>Java</strong></summary>

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

</details><details><summary><strong>Python</strong></summary>

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

</details><details><summary><strong>C#</strong></summary>

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

</details>

## 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 | |
| Amazon Aurora (`.monitorAuroraCluster()`) | Query duration, connections, latency, CPU usage, Serverless Database Capacity | Connections, Serverless Database Capacity and CPU usage | |
| AWS Billing (`.monitorBilling()`) | AWS account cost | Total cost (anomaly) | [Requires enabling](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/gs_monitor_estimated_charges_with_cloudwatch.html#gs_turning_on_billing_metrics) 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 RDS (`.monitorRdsInstance()`) | 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 | |
| FluentBit (`.monitorFluentBit()`) | Num of input records, Output failures & retries, Filter metrics, Storage metrics | | FluentBit needs proper configuration with  metrics enabled: [Official sample configuration](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/send-fb-internal-metrics-to-cw). This function creates MetricFilters to publish all FluentBit metrics. |
| 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](https://github.com/cdklabs/cdk-monitoring-constructs/tree/main/test/monitoring).

```python
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 topic.

```python
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:

```python
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.

```python
// create metrics manually
const m1 = new Metric(/* ... */);
```

```python
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.

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

Adding an alarm:

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

#### Example: search metrics

```python
monitorCustom({
  title: "Metric search",
  metricGroups: [
    {
      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](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-types.html) as to which alarms are allowed to be referenced in Health Checks.
You adjust the metric for an alarm so that it can be used in a Route53 Health Checks as follows:

```python
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:

```python
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`.

### Modifying or omitting widgets from default dashboard segments

While the dashboard widgets defined in the library are meant to cover most use cases, they might not be what you're looking for.

To modify the widgets:

1. Extend the appropriate `Monitoring` class (e.g., `LambdaFunctionMonitoring` for `monitorLambdaFunction`) and override the relevant methods (e.g., `widgets`):

   ```python
   export class MyCustomizedLambdaFunctionMonitoring extends LambdaFunctionMonitoring {
     widgets(): IWidget[] {
       return [
         // Whatever widgets you want instead of what LambdaFunctionMonitoring has
       ];
     }
   }
   ```
2. Use the facade's `addSegment` method with your custom class:

   ```python
   declare const facade: MonitoringFacade;

   facade.addSegment(new MyCustomizedLambdaFunctionMonitoring(facade, {
     // Props for LambdaFunctionMonitoring
   }));
   ```

### 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

```python
// 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:

```python
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:

```python
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"

### Cross-account cross-Region Dashboards

Facades can be configured for different regions/accounts as a whole:

```python
new MonitoringFacade(stack, "Monitoring", {
  metricFactoryDefaults: {
    // Different region/account than what you're deploying to
    region: "us-west-2",
    account: "01234567890",
  }
});
```

Or at a more granular level:

```python
monitoring
  .monitorDynamoTable({
    // Table from the same account/region
    table: Table.fromTableName(stack, "ImportedTable", "MyTableName"),
  })
  .monitorDynamoTable({
    // Table from another account/region
    table: Table.fromTableArn(
      stack,
      "XaXrImportedTable",
      "arn:aws:dynamodb:us-west-2:01234567890:table/my-other-table",
    ),
    region: "us-west-2",
    account: "01234567890",
  });
```

The order of precedence of the region/account values is:

1. The individual metric factory's props (e.g. via the `monitorDynamoTable` props).
2. The facade's `metricFactoryDefaults` props.
3. The region/account that the stack is deployed to.

Note that while this allows for cross-account cross-Region dashboarding, cross-Region alarming is not supported by CloudWatch.

### 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.

```python
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

See [CONTRIBUTING](CONTRIBUTING.md) for more information.

## Security policy

See [SECURITY](SECURITY.md) for more information.

## License

This project is licensed under the Apache-2.0 License.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/cdklabs/cdk-monitoring-constructs",
    "name": "cdk-monitoring-constructs",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "~=3.8",
    "maintainer_email": null,
    "keywords": null,
    "author": "CDK Monitoring Constructs Team<monitoring-cdk-constructs@amazon.com>",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/24/67/bbf8370339681001dda1e497ad51ff054af7de778c39d4e5756d25d0c13b/cdk_monitoring_constructs-9.4.0.tar.gz",
    "platform": null,
    "description": "# CDK Monitoring Constructs\n\n[![NPM version](https://badge.fury.io/js/cdk-monitoring-constructs.svg)](https://badge.fury.io/js/cdk-monitoring-constructs)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.cdklabs/cdkmonitoringconstructs/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.cdklabs/cdkmonitoringconstructs)\n[![PyPI version](https://badge.fury.io/py/cdk-monitoring-constructs.svg)](https://badge.fury.io/py/cdk-monitoring-constructs)\n[![NuGet version](https://badge.fury.io/nu/Cdklabs.CdkMonitoringConstructs.svg)](https://badge.fury.io/nu/Cdklabs.CdkMonitoringConstructs)\n[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs)\n[![Mergify](https://img.shields.io/endpoint.svg?url=https://gh.mergify.io/badges/cdklabs/cdk-monitoring-constructs&style=flat)](https://mergify.io)\n\nEasy-to-use CDK constructs for monitoring your AWS infrastructure with [Amazon CloudWatch](https://aws.amazon.com/cloudwatch/).\n\n* Easily add commonly-used alarms using predefined properties\n* Generate concise CloudWatch dashboards that indicate your alarms\n* Extend the library with your own extensions or custom metrics\n* Consume the library in multiple supported languages\n\n## Installation\n\n<details><summary><strong>TypeScript</strong></summary>\n\n> https://www.npmjs.com/package/cdk-monitoring-constructs\n\nIn your `package.json`:\n\n```json\n{\n  \"dependencies\": {\n    \"cdk-monitoring-constructs\": \"^9.0.0\",\n\n    // peer dependencies of cdk-monitoring-constructs\n    \"aws-cdk-lib\": \"^2.160.0\",\n    \"constructs\": \"^10.0.5\"\n\n    // ...your other dependencies...\n  }\n}\n```\n\n</details><details><summary><strong>Java</strong></summary>\n\nSee https://mvnrepository.com/artifact/io.github.cdklabs/cdkmonitoringconstructs\n\n</details><details><summary><strong>Python</strong></summary>\n\nSee https://pypi.org/project/cdk-monitoring-constructs/\n\n</details><details><summary><strong>C#</strong></summary>\n\nSee https://www.nuget.org/packages/Cdklabs.CdkMonitoringConstructs/\n\n</details>\n\n## Features\n\nYou can browse the documentation at https://constructs.dev/packages/cdk-monitoring-constructs/\n\n| Item | Monitoring | Alarms | Notes |\n| ---- | ---------- | ------ | ----- |\n| 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 |\n| 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 |\n| AWS AppSync (GraphQL API) (`.monitorAppSyncApi()`) | TPS, latency, errors | Latency, error count/rate, low/high TPS | |\n| Amazon Aurora (`.monitorAuroraCluster()`) | Query duration, connections, latency, CPU usage, Serverless Database Capacity | Connections, Serverless Database Capacity and CPU usage | |\n| AWS Billing (`.monitorBilling()`) | AWS account cost | Total cost (anomaly) | [Requires enabling](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/gs_monitor_estimated_charges_with_cloudwatch.html#gs_turning_on_billing_metrics) the **Receive Billing Alerts** option in AWS Console / Billing Preferences |\n| AWS Certificate Manager (`.monitorCertificate()`) | Certificate expiration | Days until expiration | |\n| AWS CloudFront (`.monitorCloudFrontDistribution()`) | TPS, traffic, latency, errors | Error rate, low/high TPS | |\n| AWS CloudWatch Logs (`.monitorLog()`) | Patterns present in the log group | Minimum incoming logs | |\n| AWS CloudWatch Synthetics Canary (`.monitorSyntheticsCanary()`) | Latency, error count/rate | Error count/rate, latency | |\n| AWS CodeBuild (`.monitorCodeBuildProject()`) | Build counts (total, successful, failed), failed rate, duration | Failed build count/rate, duration | |\n| AWS DocumentDB (`.monitorDocumentDbCluster()`) | CPU, throttling, read/write latency, transactions, cursors | CPU | |\n| AWS DynamoDB (`.monitorDynamoTable()`) | Read and write capacity provisioned / used | Consumed capacity, throttling, latency, errors | |\n| AWS DynamoDB Global Secondary Index (`.monitorDynamoTableGlobalSecondaryIndex()`) | Read and write capacity, indexing progress, throttled events | | |\n| AWS EC2 (`.monitorEC2Instances()`) | CPU, disk operations, network | | |\n| AWS EC2 Auto Scaling Groups (`.monitorAutoScalingGroup()`) | Group size, instance status | | |\n| 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) |\n| AWS ElastiCache (`.monitorElastiCacheCluster()`) | CPU/memory usage, evictions and connections | CPU, memory, items count | |\n| AWS Glue (`.monitorGlueJob()`) | Traffic, job status, memory/CPU usage | Failed/killed task count/rate | |\n| AWS Kinesis Data Analytics (`.monitorKinesisDataAnalytics`) | Up/Downtime, CPU/memory usage, KPU usage, checkpoint metrics, and garbage collection metrics | Downtime, full restart count | |\n| AWS Kinesis Data Stream (`.monitorKinesisDataStream()`) | Put/Get/Incoming Record/s and Throttling | Throttling, throughput, iterator max age | |\n| AWS Kinesis Firehose (`.monitorKinesisFirehose()`) | Number of records, requests, latency, throttling | Throttling | |\n| AWS Lambda (`.monitorLambdaFunction()`) | Latency, errors, iterator max age | Latency, errors, throttles, iterator max age | Optional Lambda Insights metrics (opt-in) support |\n| 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 |\n| 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 | |\n| AWS RDS (`.monitorRdsCluster()`) | Query duration, connections, latency, disk/CPU usage | Connections, disk and CPU usage | |\n| AWS RDS (`.monitorRdsInstance()`) | Query duration, connections, latency, disk/CPU usage | Connections, disk and CPU usage | |\n| AWS Redshift (`.monitorRedshiftCluster()`) | Query duration, connections, latency, disk/CPU usage | Query duration, connections, disk and CPU usage | |\n| AWS S3 Bucket (`.monitorS3Bucket()`) | Bucket size and number of objects | | |\n| AWS SecretsManager (`.monitorSecretsManager()`) | Max secret count, min secret sount, secret count change | Min/max secret count or change in secret count | |\n| AWS SecretsManager Secret (`.monitorSecretsManagerSecret()`) | Days since last rotation | Days since last change or rotation | |\n| AWS SNS Topic (`.monitorSnsTopic()`) | Message count, size, failed notifications | Failed notifications, min/max published messages | |\n| AWS SQS Queue (`.monitorSqsQueue()`, `.monitorSqsQueueWithDlq()`) | Message count, age, size | Message count, age, DLQ incoming messages | |\n| AWS Step Functions (`.monitorStepFunction()`, `.monitorStepFunctionActivity()`, `monitorStepFunctionLambdaIntegration()`, `.monitorStepFunctionServiceIntegration()`) | Execution count and breakdown per state | Duration, failed, failed rate, aborted, throttled, timed out executions | |\n| AWS Web Application Firewall (`.monitorWebApplicationFirewallAclV2()`) | Allowed/blocked requests | Blocked requests count/rate | |\n| FluentBit (`.monitorFluentBit()`) | Num of input records, Output failures & retries, Filter metrics, Storage metrics | | FluentBit needs proper configuration with  metrics enabled: [Official sample configuration](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/send-fb-internal-metrics-to-cw). This function creates MetricFilters to publish all FluentBit metrics. |\n| Custom metrics (`.monitorCustom()`) | Addition of custom metrics into the dashboard (each group is a widget) | | Supports anomaly detection |\n\n## Getting started\n\n### Create a facade\n\n*Important note*: **Please, do NOT import anything from the `/dist/lib` package.** This is unsupported and might break any time.\n\n1. Create an instance of `MonitoringFacade`, which is the main entrypoint.\n2. 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.\n\nFor examples of monitoring different resources, refer to [the unit tests](https://github.com/cdklabs/cdk-monitoring-constructs/tree/main/test/monitoring).\n\n```python\nexport interface MonitoringStackProps extends DeploymentStackProps {\n  // ...\n}\n\n// This could be in the same stack as your resources, as a nested stack, or a separate stack as you see fit\nexport class MonitoringStack extends DeploymentStack {\n  constructor(parent: App, name: string, props: MonitoringStackProps) {\n    super(parent, name, props);\n\n    const monitoring = new MonitoringFacade(this, \"Monitoring\", {\n      // Defaults are provided for these, but they can be customized as desired\n      metricFactoryDefaults: { ... },\n      alarmFactoryDefaults: { ... },\n      dashboardFactory: { ... },\n    });\n\n    // Monitor your resources\n    monitoring\n      .addLargeHeader(\"Storage\")\n      .monitorDynamoTable({ /* Monitor a DynamoDB table */ })\n      .monitorDynamoTable({ /* and a different table */ })\n      .monitorLambdaFunction({ /* and a Lambda function */ })\n      .monitorCustom({ /* and some arbitrary metrics in CloudWatch */ })\n      // ... etc.\n  }\n}\n```\n\n### Customize actions\n\nAlarms should have an action setup, otherwise they are not very useful. Currently, we support notifying an SNS topic.\n\n```python\nconst onAlarmTopic = new Topic(this, \"AlarmTopic\");\n\nconst monitoring = new MonitoringFacade(this, \"Monitoring\", {\n  // ...other props\n  alarmFactoryDefaults: {\n    // ....other props\n    action: new SnsAlarmActionStrategy({ onAlarmTopic }),\n  },\n});\n```\n\nYou can override the default topic for any alarm like this:\n\n```python\nmonitoring\n  .monitorSomething(something, {\n    addSomeAlarm: {\n      Warning: {\n        // ...other props\n        threshold: 42,\n        actionOverride: new SnsAlarmActionStrategy({ onAlarmTopic }),\n      }\n    }\n  });\n```\n\n### Custom metrics\n\nFor simply adding some custom metrics, you can use `.monitorCustom()` and specify your own title and metric groups.\nEach metric group will be rendered as a single graph widget, and all widgets will be placed next to each other.\nAll the widgets will have the same size, which is chosen based on the number of groups to maximize dashboard space usage.\n\nCustom metric monitoring can be created for simple metrics, simple metrics with anomaly detection and search metrics.\nThe first two also support alarming.\n\nBelow we are listing a couple of examples. Let us assume that there are three existing metric variables: `m1`, `m2`, `m3`.\nThey can either be created by hand (`new Metric({...})`) or (preferably) by using `metricFactory` (that can be obtained from facade).\nThe advantage of using the shared `metricFactory` is that you do not need to worry about period, etc.\n\n```python\n// create metrics manually\nconst m1 = new Metric(/* ... */);\n```\n\n```python\nconst metricFactory = monitoringFacade.createMetricFactory();\n\n// create metrics using metric factory\nconst m1 = metricFactory.createMetric(/* ... */);\n```\n\n#### Example: metric with anomaly detection\n\nIn this case, only one metric is supported.\nMultiple metrics cannot be rendered with anomaly detection in a single widget due to a CloudWatch limitation.\n\n```python\nmonitorCustom({\n  title: \"Metric with anomaly detection\",\n  metricGroups: [\n    {\n      metric: m1,\n      anomalyDetectionStandardDeviationToRender: 3\n    }\n  ]\n})\n```\n\nAdding an alarm:\n\n```python\nmonitorCustom({\n  title: \"Metric with anomaly detection and alarm\",\n  metricGroups: [\n    {\n      metric: m1,\n      alarmFriendlyName: \"MetricWithAnomalyDetectionAlarm\",\n      anomalyDetectionStandardDeviationToRender: 3,\n      addAlarmOnAnomaly: {\n        Warning: {\n          standardDeviationForAlarm: 4,\n          alarmWhenAboveTheBand: true,\n          alarmWhenBelowTheBand: true\n        }\n      }\n    }\n  ]\n})\n```\n\n#### Example: search metrics\n\n```python\nmonitorCustom({\n  title: \"Metric search\",\n  metricGroups: [\n    {\n      searchQuery: \"My.Prefix.\",\n      dimensionsMap: {\n        FirstDimension: \"FirstDimensionValue\",\n        // Allow any value for the given dimension (pardon the weird typing to satisfy DimensionsMap)\n        SecondDimension: undefined as unknown as string\n      }\n      statistic: MetricStatistic.SUM,\n    }\n  ]\n})\n```\n\nSearch metrics do not support setting an alarm, which is a CloudWatch limitation.\n\n### Route53 Health Checks\n\nRoute53 has [strict requirements](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-types.html) as to which alarms are allowed to be referenced in Health Checks.\nYou adjust the metric for an alarm so that it can be used in a Route53 Health Checks as follows:\n\n```python\nmonitoring\n  .monitorSomething(something, {\n    addSomeAlarm: {\n      Warning: {\n        // ...other props\n        metricAdjuster: Route53HealthCheckMetricAdjuster.INSTANCE,\n      }\n    }\n  });\n```\n\nThis 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.\nIn order to easily find your Route53 Health Check alarms later on, you can apply a custom tag to them as follows:\n\n```python\nimport { CfnHealthCheck } from \"aws-cdk-lib/aws-route53\";\n\nmonitoring\n  .monitorSomething(something, {\n    addSomeAlarm: {\n      Warning: {\n        // ...other props\n        customTags: [\"route53-health-check\"],\n        metricAdjuster: Route53HealthCheckMetricAdjuster.INSTANCE,\n      }\n    }\n  });\n\nconst alarms = monitoring.createdAlarmsWithTag(\"route53-health-check\");\n\nconst healthChecks = alarms.map(({ alarm }) => {\n  const id = getHealthCheckConstructId(alarm);\n\n  return new CfnHealthCheck(scope, id, {\n    healthCheckConfig: {\n      // ...other props\n      type: \"CLOUDWATCH_METRIC\",\n      alarmIdentifier: {\n        name: alarm.alarmName,\n        region: alarm.stack.region,\n      },\n    },\n  });\n});\n```\n\n### Custom monitoring segments\n\nIf you want even more flexibility, you can create your own segment.\n\nThis is a general procedure on how to do it:\n\n1. Extend the `Monitoring` class\n2. Override the `widgets()` method (and/or similar ones)\n3. Leverage the metric factory and alarm factory provided by the base class (you can create additional factories, if you will)\n4. Add all alarms to `.addAlarm()` so they are visible to the user and being placed on the alarm summary dashboard\n\nBoth of these monitoring base classes are dashboard segments, so you can add them to your monitoring by calling `.addSegment()` on the `MonitoringFacade`.\n\n### Modifying or omitting widgets from default dashboard segments\n\nWhile the dashboard widgets defined in the library are meant to cover most use cases, they might not be what you're looking for.\n\nTo modify the widgets:\n\n1. Extend the appropriate `Monitoring` class (e.g., `LambdaFunctionMonitoring` for `monitorLambdaFunction`) and override the relevant methods (e.g., `widgets`):\n\n   ```python\n   export class MyCustomizedLambdaFunctionMonitoring extends LambdaFunctionMonitoring {\n     widgets(): IWidget[] {\n       return [\n         // Whatever widgets you want instead of what LambdaFunctionMonitoring has\n       ];\n     }\n   }\n   ```\n2. Use the facade's `addSegment` method with your custom class:\n\n   ```python\n   declare const facade: MonitoringFacade;\n\n   facade.addSegment(new MyCustomizedLambdaFunctionMonitoring(facade, {\n     // Props for LambdaFunctionMonitoring\n   }));\n   ```\n\n### Custom dashboards\n\nIf 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:\n\n1. Create a dynamic dashboard factory\n2. Create `IDynamicDashboardSegment` implementations\n3. Add Dynamic Segments to your `MonitoringFacade`\n\n#### Create a dynamic dashboard factory\n\nThe below code sample will generate two dashboards with the following names:\n\n* ExampleDashboards-HostedService\n* ExampleDashboards-Infrastructure\n\n```python\n// create the dynamic dashboard factory.\nconst factory = new DynamicDashboardFactory(stack, \"DynamicDashboards\", {\n  dashboardNamePrefix: \"ExampleDashboards\",\n  dashboardConfigs: [\n    // 'name' is the minimum required configuration\n    { name: \"HostedService\" },\n    // below is an example of additional dashboard-specific config options\n    {\n      name: \"Infrastructure\",\n      range: Duration.hours(3),\n      periodOverride: PeriodOverride.AUTO,\n      renderingPreference: DashboardRenderingPreference.BITMAP_ONLY\n    },\n  ],\n});\n```\n\n#### Create `IDynamicDashboardSegment` implementations\n\nFor 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:\n\n```python\nexport enum DashboardTypes {\n  HostedService = \"HostedService\",\n  Infrastructure = \"Infrastructure\",\n}\n\nclass ExampleSegment implements IDynamicDashboardSegment {\n  widgetsForDashboard(name: string): IWidget[] {\n    // this logic is what's responsible for allowing your dynamic segment to return\n    // different widgets for different dashboards\n    switch (name) {\n      case DashboardTypes.HostedService:\n        return [new TextWidget({ markdown: \"This shows metrics for your service hosted on AWS Infrastructure\" })];\n      case DashboardTypes.Infrastructure:\n        return [new TextWidget({ markdown: \"This shows metrics for the AWS Infrastructure supporting your hosted service\" })];\n      default:\n        throw new Error(\"Unexpected dashboard name!\");\n    }\n  }\n}\n```\n\n#### Add Dynamic Segments to MonitoringFacade\n\nWhen you have instances of an `IDynamicDashboardSegment` to use, they can be added to your dashboard like this:\n\n```python\nmonitoring.addDynamicSegment(new ExampleSegment());\n```\n\nNow, 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:\n\n* Dashboard Name: \"ExampleDashboards-HostedService\"\n\n  * Content: \"This shows metrics for your service hosted on AWS Infrastructure\"\n* Dashboard Name: \"ExampleDashboards-Infrastructure\"\n\n  * Content: \"This shows metrics for the AWS Infrastructure supporting your hosted service\"\n\n### Cross-account cross-Region Dashboards\n\nFacades can be configured for different regions/accounts as a whole:\n\n```python\nnew MonitoringFacade(stack, \"Monitoring\", {\n  metricFactoryDefaults: {\n    // Different region/account than what you're deploying to\n    region: \"us-west-2\",\n    account: \"01234567890\",\n  }\n});\n```\n\nOr at a more granular level:\n\n```python\nmonitoring\n  .monitorDynamoTable({\n    // Table from the same account/region\n    table: Table.fromTableName(stack, \"ImportedTable\", \"MyTableName\"),\n  })\n  .monitorDynamoTable({\n    // Table from another account/region\n    table: Table.fromTableArn(\n      stack,\n      \"XaXrImportedTable\",\n      \"arn:aws:dynamodb:us-west-2:01234567890:table/my-other-table\",\n    ),\n    region: \"us-west-2\",\n    account: \"01234567890\",\n  });\n```\n\nThe order of precedence of the region/account values is:\n\n1. The individual metric factory's props (e.g. via the `monitorDynamoTable` props).\n2. The facade's `metricFactoryDefaults` props.\n3. The region/account that the stack is deployed to.\n\nNote that while this allows for cross-account cross-Region dashboarding, cross-Region alarming is not supported by CloudWatch.\n\n### Monitoring scopes\n\nYou 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.\n\n```python\nmonitoring.monitorScope(stack, {\n  // With optional configuration\n  lambda: {\n    props: {\n      addLatencyP50Alarm: {\n        Critical: { maxLatency: Duration.seconds(10) },\n      },\n    },\n  },\n\n  // Some resources that aren't dependent on nodes (e.g. general metrics across instances/account) may be included\n  // by default, which can be explicitly disabled.\n  billing: { enabled: false },\n  ec2: { enabled: false },\n  elasticCache: { enabled: false },\n});\n```\n\n## Contributing\n\nSee [CONTRIBUTING](CONTRIBUTING.md) for more information.\n\n## Security policy\n\nSee [SECURITY](SECURITY.md) for more information.\n\n## License\n\nThis project is licensed under the Apache-2.0 License.\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "cdk-monitoring-constructs",
    "version": "9.4.0",
    "project_urls": {
        "Homepage": "https://github.com/cdklabs/cdk-monitoring-constructs",
        "Source": "https://github.com/cdklabs/cdk-monitoring-constructs"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2909a371c8b5a6e4fe8920e3b3a6e9e704f58fa1d10dc7b6ff183f62a37e15b5",
                "md5": "730b5adb1bb1646522ca41205876436a",
                "sha256": "26930f559d87dd83233923d813a0bd58f80c9cda9274bb0c81eddaa6a81846d0"
            },
            "downloads": -1,
            "filename": "cdk_monitoring_constructs-9.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "730b5adb1bb1646522ca41205876436a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "~=3.8",
            "size": 1342937,
            "upload_time": "2025-03-21T14:11:45",
            "upload_time_iso_8601": "2025-03-21T14:11:45.623293Z",
            "url": "https://files.pythonhosted.org/packages/29/09/a371c8b5a6e4fe8920e3b3a6e9e704f58fa1d10dc7b6ff183f62a37e15b5/cdk_monitoring_constructs-9.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2467bbf8370339681001dda1e497ad51ff054af7de778c39d4e5756d25d0c13b",
                "md5": "d135f95caaa1cd2017994b70411f2225",
                "sha256": "7cfe9ded7acecf837d79327b7892981015c1128887b64d454bfad905460e50c8"
            },
            "downloads": -1,
            "filename": "cdk_monitoring_constructs-9.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "d135f95caaa1cd2017994b70411f2225",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "~=3.8",
            "size": 1344721,
            "upload_time": "2025-03-21T14:11:47",
            "upload_time_iso_8601": "2025-03-21T14:11:47.506695Z",
            "url": "https://files.pythonhosted.org/packages/24/67/bbf8370339681001dda1e497ad51ff054af7de778c39d4e5756d25d0c13b/cdk_monitoring_constructs-9.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-03-21 14:11:47",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "cdklabs",
    "github_project": "cdk-monitoring-constructs",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "cdk-monitoring-constructs"
}
        
Elapsed time: 1.55277s