Header menu logo FsCDK

CloudWatch Dashboard

CloudWatch Dashboards provide at-a-glance views of your AWS resources and applications. Monitor metrics, logs, and alarms in a customizable visual interface.

Quick Start

#r "../src/bin/Release/net8.0/publish/Amazon.JSII.Runtime.dll"
#r "../src/bin/Release/net8.0/publish/Constructs.dll"
#r "../src/bin/Release/net8.0/publish/Amazon.CDK.Lib.dll"
#r "../src/bin/Release/net8.0/publish/FsCDK.dll"

open FsCDK
open Amazon.CDK
open Amazon.CDK.AWS.CloudWatch
open Amazon.CDK.AWS.Lambda
open Amazon.CDK.AWS.DynamoDB

Basic Dashboard

Create a simple dashboard to monitor Lambda functions.

stack "BasicDashboard" {
    let! myFunction =
        lambda "MyFunction" {
            runtime Runtime.DOTNET_8
            handler "App::Handler"
            code "./lambda"
        }

    let invocationsMetric = myFunction.MetricInvocations()
    let errorsMetric = myFunction.MetricErrors()

    dashboard "lambda-monitoring" {

        widgets
            [ graphWidget "Invocations" { left [ invocationsMetric ] }
              graphWidget "Errors" { left [ errorsMetric ] } ]

    }
}

Multi-Resource Dashboard

Monitor multiple services in one dashboard.

stack "MultiResourceDashboard" {
    let! apiFunction =
        lambda "API" {
            runtime Runtime.DOTNET_8
            handler "App::API"
            code "./lambda"
        }

    let! dataTable =
        table "Data" {
            partitionKey "id" AttributeType.STRING
            billingMode BillingMode.PAY_PER_REQUEST
        }

    let apiMetric = apiFunction.MetricInvocations()
    let apiDuration = apiFunction.MetricDuration()
    let tableReads = dataTable.MetricConsumedReadCapacityUnits()
    let tableWrites = dataTable.MetricConsumedWriteCapacityUnits()

    dashboard "application-monitoring" {
        defaultInterval (Duration.Minutes(5.0))

        widgets
            [
              // First row: Lambda metrics
              graphWidget "API Invocations and Duration" {
                  left [ apiMetric ]
                  right [ apiDuration ]
              }

              // Second row: DynamoDB metrics
              graphWidget "DynamoDB Read/Write Capacity" {
                  left [ tableReads ]
                  right [ tableWrites ]
              } ]
    }
}

Dashboard with Alarms

Include CloudWatch alarms for critical metrics.

stack "DashboardWithAlarms" {
    let! webFunction =
        lambda "WebApp" {
            runtime Runtime.DOTNET_8
            handler "App::Handle"
            code "./lambda"
        }

    let errorMetric = webFunction.MetricErrors()

    let! errorAlarm =
        // CloudWatch Alarm for Lambda errors
        cloudwatchAlarm "lambda-error-alarm" {
            description "Alert when error rate is high"
            metric errorMetric
            dimensions [ "FunctionName", "my-function" ]
            statistic "Sum"
            threshold 10.0
            evaluationPeriods 2
            period (Duration.Minutes 5.0)
        }

    dashboard "web-app-alerts" {

        widgets
            [ graphWidget "Lambda Errors" { left [ errorMetric ] }
              alarmWidget "Lambda Errors Alarm" { alarm errorAlarm } ]
    }
}

Dashboard with Text Widgets

Add explanatory text and documentation.

stack "DocumentedDashboard" {
    let mainText =
        "# Production System Overview\n\nThis dashboard monitors critical production metrics.\n\n**Contact:** ops@example.com"

    dashboard "production-overview" {
        widgets
            [ textWidget {
                  markdown mainText
                  width 24
                  height 4
                  background TextWidgetBackground.SOLID
              } ]
    }
}

Custom Time Range

Set specific time ranges for the dashboard.

stack "CustomTimeRange" {
    dashboard "HistoricalDashboard last-7-days" {
        defaultInterval (Duration.Days(7.0))
        startTime "-P7D" // ISO 8601 duration: 7 days ago
        endTime "PT0H" // Now
    }
}

Log Insights Widget

Query and visualize CloudWatch Logs.

stack "LogsDashboard" {
    let logWidget =
        logQueryWidget "Error Logs" {
            queryLines
                [ "fields @timestamp, @message"
                  " | filter @message like /ERROR/"
                  " | sort @timestamp desc"
                  " | limit 20" ]

            logGroupNames [ "/aws/lambda/my-function" ]
            width 12
            height 6
        }

    dashboard "LogsDashboard application-logs" { widgets [ logWidget ] }
}

Single Value Widgets

Display current metric values prominently.

stack "SingleValueDashboard" {
    let activeUsers =
        Metric(MetricProps(Namespace = "MyApp", MetricName = "ActiveUsers"))

    let currentRequests =
        Metric(MetricProps(Namespace = "MyApp", MetricName = "CurrentRequests"))

    dashboard "CurrentStatsDashboard current-stats" {
        widgets
            [ singleValueWidget "Active Users" { metrics [ activeUsers ] }
              singleValueWidget "Current Requests" { metrics [ currentRequests ] } ]
    }
}

Best Practices

Design

Operational Excellence

Cost Optimization

Security

namespace FsCDK
namespace Amazon
namespace Amazon.CDK
namespace Amazon.CDK.AWS
namespace Amazon.CDK.AWS.CloudWatch
namespace Amazon.CDK.AWS.Lambda
namespace Amazon.CDK.AWS.DynamoDB
val stack: name: string -> StackBuilder
<summary>Creates an AWS CDK Stack construct.</summary>
<param name="name">The name of the stack.</param>
<code lang="fsharp"> stack "MyStack" { lambda myFunction bucket myBucket } </code>
val myFunction: IFunction
val lambda: name: string -> FunctionBuilder
<summary>Creates a Lambda function configuration.</summary>
<param name="name">The function name.</param>
<code lang="fsharp"> lambda "MyFunction" { handler "index.handler" runtime Runtime.NODEJS_18_X code "./lambda" timeout 30.0 } </code>
custom operation: runtime (Runtime) Calls FunctionBuilder.Runtime
<summary>Sets the runtime for the Lambda function.</summary>
<param name="config">The function configuration.</param>
<param name="runtime">The Lambda runtime.</param>
<code lang="fsharp"> lambda "MyFunction" { runtime Runtime.NODEJS_18_X } </code>
Multiple items
type Runtime = inherit DeputyBase new: name: string * ?family: Nullable<RuntimeFamily> * ?props: ILambdaRuntimeProps -> unit member RuntimeEquals: other: Runtime -> bool member ToString: unit -> string member BundlingImage: DockerImage member Family: Nullable<RuntimeFamily> member IsVariable: bool member Name: string member SupportsCodeGuruProfiling: bool member SupportsInlineCode: bool ...

--------------------
Runtime(name: string, ?family: System.Nullable<RuntimeFamily>, ?props: ILambdaRuntimeProps) : Runtime
property Runtime.DOTNET_8: Runtime with get
custom operation: handler (string) Calls FunctionBuilder.Handler
<summary>Sets the handler for the Lambda function.</summary>
<param name="config">The function configuration.</param>
<param name="handler">The handler name (e.g., "index.handler").</param>
<code lang="fsharp"> lambda "MyFunction" { handler "index.handler" } </code>
custom operation: code (Code) Calls FunctionBuilder.Code
<summary>Sets the code source from a Code object.</summary>
<param name="config">The function configuration.</param>
<param name="path">The Code object.</param>
<code lang="fsharp"> lambda "MyFunction" { code (Code.FromBucket myBucket "lambda.zip") } </code>
val invocationsMetric: Metric
IFunction.MetricInvocations(?props: IMetricOptions) : Metric
val errorsMetric: Metric
IFunction.MetricErrors(?props: IMetricOptions) : Metric
val dashboard: name: string -> DashboardBuilder
<summary>Creates a CloudWatch Dashboard with AWS monitoring best practices.</summary>
<param name="name">The dashboard name.</param>
<code lang="fsharp"> dashboard "MyAppDashboard" { dashboardName "my-app-production" defaultInterval (Duration.Minutes(5.0)) widgetRow [ DashboardWidgets.metricWidget "API Requests" [requestMetric] DashboardWidgets.metricWidget "Error Rate" [errorMetric] ] widgetRow [ DashboardWidgets.singleValueWidget "Current Users" [userMetric] ] } </code>
custom operation: widgets (IWidget seq) Calls DashboardBuilder.Widgets
<summary>Adds a single widget to the dashboard.</summary>
val graphWidget: title: string -> GraphWidgetBuilder
<summary>Creates a Graph Widget for CloudWatch Dashboards.</summary>
<param name="title">The widget title.</param>
<code lang="fsharp"> graphWidget "API Requests" { left [ apiRequestMetric ] period (Duration.Minutes(1.0)) stacked true } </code>
custom operation: left (IMetric seq) Calls GraphWidgetBuilder.Left
val apiFunction: IFunction
val dataTable: ITable
val table: name: string -> TableBuilder
<summary>Creates a DynamoDB table configuration.</summary>
<param name="name">The table name.</param>
<code lang="fsharp"> table "MyTable" { partitionKey "id" AttributeType.STRING billingMode BillingMode.PAY_PER_REQUEST } </code>
custom operation: partitionKey (string) (AttributeType) Calls TableBuilder.PartitionKey
<summary>Sets the partition key for the table.</summary>
<param name="config">The current table configuration.</param>
<param name="name">The attribute name for the partition key.</param>
<param name="attrType">The attribute type (STRING, NUMBER, or BINARY).</param>
<code lang="fsharp"> table "MyTable" { partitionKey "id" AttributeType.STRING } </code>
[<Struct>] type AttributeType = | BINARY = 0 | NUMBER = 1 | STRING = 2
field AttributeType.STRING: AttributeType = 2
custom operation: billingMode (BillingMode) Calls TableBuilder.BillingMode
<summary>Sets the billing mode for the table.</summary>
<param name="config">The current table configuration.</param>
<param name="mode">The billing mode (PAY_PER_REQUEST or PROVISIONED).</param>
<code lang="fsharp"> table "MyTable" { billingMode BillingMode.PAY_PER_REQUEST } </code>
[<Struct>] type BillingMode = | PAY_PER_REQUEST = 0 | PROVISIONED = 1
field BillingMode.PAY_PER_REQUEST: BillingMode = 0
val apiMetric: Metric
val apiDuration: Metric
IFunction.MetricDuration(?props: IMetricOptions) : Metric
val tableReads: Metric
ITable.MetricConsumedReadCapacityUnits(?props: IMetricOptions) : Metric
val tableWrites: Metric
ITable.MetricConsumedWriteCapacityUnits(?props: IMetricOptions) : Metric
custom operation: defaultInterval (Duration) Calls DashboardBuilder.DefaultInterval
<summary>Sets the default time range interval for metrics.</summary>
type Duration = inherit DeputyBase member FormatTokenToNumber: unit -> string member IsUnresolved: unit -> bool member Minus: rhs: Duration -> Duration member Plus: rhs: Duration -> Duration member ToDays: ?opts: ITimeConversionOptions -> float member ToHours: ?opts: ITimeConversionOptions -> float member ToHumanString: unit -> string member ToIsoString: unit -> string member ToMilliseconds: ?opts: ITimeConversionOptions -> float ...
Duration.Minutes(amount: float) : Duration
custom operation: right (IMetric seq) Calls GraphWidgetBuilder.Right
val webFunction: IFunction
val errorMetric: Metric
val errorAlarm: IAlarm
val cloudwatchAlarm: name: string -> CloudWatchAlarmBuilder
custom operation: description (string) Calls CloudWatchAlarmBuilder.Description
<summary>Sets the alarm description.</summary>
custom operation: metric (IMetric) Calls CloudWatchAlarmBuilder.Metric
<summary>Sets the IMetric. If you use this, don't define metricName or metricNamespace.</summary>
custom operation: dimensions ((string * string) list) Calls CloudWatchAlarmBuilder.Dimensions
<summary>Sets the metric dimensions for filtering (e.g., FunctionName, DBInstanceIdentifier).</summary>
custom operation: statistic (string) Calls CloudWatchAlarmBuilder.Statistic
<summary>Sets the statistic (Average, Sum, Minimum, Maximum, SampleCount).</summary>
custom operation: threshold (float) Calls CloudWatchAlarmBuilder.Threshold
<summary>Sets the alarm threshold value.</summary>
custom operation: evaluationPeriods (int) Calls CloudWatchAlarmBuilder.EvaluationPeriods
<summary>Sets the number of periods to evaluate.</summary>
custom operation: period (Duration) Calls CloudWatchAlarmBuilder.Period
<summary>Sets the evaluation period.</summary>
val alarmWidget: title: string -> AlarmWidgetBuilder
<summary>Creates an Alarm Widget for CloudWatch Dashboards.</summary>
<param name="title">The widget title.</param>
<code lang="fsharp"> alarmWidget "High Error Rate" { alarm errorAlarm leftYAxis (YAxisProps(...)) } </code>
custom operation: alarm (IAlarm) Calls AlarmWidgetBuilder.Alarm
val mainText: string
val textWidget: TextWidgetBuilder
<summary>Creates a Text Widget for CloudWatch Dashboards.</summary>
<code lang="fsharp"> textWidget { markdown "# Application Alerts\n- High CPU Usage\n- Memory Leak Detected" background TextWidgetBackground.SOLID height 6.0 } </code>
custom operation: markdown (string) Calls TextWidgetBuilder.Markdown
custom operation: width (float) Calls TextWidgetBuilder.Width
custom operation: height (float) Calls TextWidgetBuilder.Height
custom operation: background (TextWidgetBackground) Calls TextWidgetBuilder.Background
[<Struct>] type TextWidgetBackground = | SOLID = 0 | TRANSPARENT = 1
field TextWidgetBackground.SOLID: TextWidgetBackground = 0
Duration.Days(amount: float) : Duration
custom operation: startTime (string) Calls DashboardBuilder.StartTime
<summary>Sets the start time for the dashboard.</summary>
custom operation: endTime (string) Calls DashboardBuilder.EndTime
<summary>Sets the end time for the dashboard.</summary>
val logWidget: LogQueryWidget
val logQueryWidget: title: string -> LogQueryWidgetBuilder
<summary>Creates a Log Query Widget for CloudWatch Dashboards.</summary>
<param name="title">The widget title.</param>
<code lang="fsharp"> logQueryWidget "Error Logs" { logGroupNames [ "/aws/lambda/my-function" ] queryLines [ "fields @timestamp, @message" "filter @message like /ERROR/" ] } </code>
custom operation: queryLines (string seq) Calls LogQueryWidgetBuilder.QueryLines
custom operation: logGroupNames (string seq) Calls LogQueryWidgetBuilder.LogGroupNames
custom operation: width (int) Calls LogQueryWidgetBuilder.Width
custom operation: height (int) Calls LogQueryWidgetBuilder.Height
val activeUsers: Metric
Multiple items
type Metric = inherit DeputyBase interface IMetric new: props: IMetricProps -> unit member AttachTo: scope: IConstruct -> Metric member CreateAlarm: scope: Construct * id: string * props: ICreateAlarmOptions -> Alarm member ToMetricConfig: unit -> IMetricConfig member ToString: unit -> string member With: props: IMetricOptions -> Metric static member AnomalyDetectionFor: props: IAnomalyDetectionMetricOptions -> MathExpression static member GrantPutMetricData: grantee: IGrantable -> Grant ...

--------------------
Metric(props: IMetricProps) : Metric
Multiple items
type MetricProps = interface IMetricProps interface ICommonMetricOptions new: unit -> unit member Account: string member Color: string member DimensionsMap: IDictionary<string,string> member Id: string member Label: string member MetricName: string member Namespace: string ...

--------------------
MetricProps() : MetricProps
val currentRequests: Metric
val singleValueWidget: title: string -> SingleValueWidgetBuilder
<summary>Creates a Single Value Widget for CloudWatch Dashboards.</summary>
<param name="title">The widget title.</param>
<code lang="fsharp"> singleValueWidget "Active Users" { metrics [ activeUserMetric ] fullPrecision true } </code>
custom operation: metrics (IMetric seq) Calls SingleValueWidgetBuilder.Metrics

Type something to start searching.