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
- ✅ Organize related metrics together
- ✅ Use consistent time ranges across widgets
- ✅ Add text widgets for context and documentation
- ✅ Use colors to highlight critical metrics
Operational Excellence
- ✅ Create separate dashboards for different teams
- ✅ Include both system and business metrics
- ✅ Set appropriate Y-axis ranges for readability
- ✅ Use anomaly detection for baseline comparison
Cost Optimization
- ✅ Use 5-minute intervals for most metrics (default)
- ✅ Limit the number of custom metrics
- ✅ Delete unused dashboards
- ✅ Use metric math to reduce API calls
Security
- ✅ Control dashboard access via IAM
- ✅ Don't expose sensitive data in dashboards
- ✅ Use CloudFormation for dashboard as code
- ✅ Version control dashboard configurations
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>
<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>
<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>
<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
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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<summary>Sets the statistic (Average, Sum, Minimum, Maximum, SampleCount).</summary>
custom operation: threshold (float)
Calls CloudWatchAlarmBuilder.Threshold
<summary>Sets the alarm threshold value.</summary>
<summary>Sets the alarm threshold value.</summary>
custom operation: evaluationPeriods (int)
Calls CloudWatchAlarmBuilder.EvaluationPeriods
<summary>Sets the number of periods to evaluate.</summary>
<summary>Sets the number of periods to evaluate.</summary>
custom operation: period (Duration)
Calls CloudWatchAlarmBuilder.Period
<summary>Sets the evaluation period.</summary>
<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>
<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>
<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>
<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>
<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>
<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
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
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>
<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
FsCDK