Datadog Dashboards

Quote

“The real key to modern infrastructure isn’t perfect automation, but correlation — linking downstream effects back to upstream causes.”

Kelsey Hightower, tweet (2019)

Pipeline Watch Dashboard

A custom dashboard gathering all useful metrics to monitor during pipeline runs.

Create the Dashboard

  1. Go to Dashboards > New Dashboard
  2. Name it Pipeline Watch
  3. Choose Screenboard layout (free-form, not grid)

Adding Section Headers

Use Notes & Links widgets as section headers:

  1. Click + Add WidgetNotes & Links
  2. Enter markdown for the header, e.g.:
   ## Cloud Run Job
  1. Style: set background color to match your theme, make text bold
  2. Drag to span the full width

Screenboard Layout

Drag the Notes & Links section headers to span the full width. Place Query Value widgets in a row at the top of each section. Stack Timeseries widgets in a 2-column grid below. The screenboard editor can be buggy — dragging widgets near edges may push others down. Save frequently.


Section 1: Cloud Run Job

Widget: Pipeline Runs (Query Value)

SettingValue
TypeQuery Value
Metricsum:gcp.run.job.completed_execution_count{job_name:data-pipeline-pipeline}.as_count()
Aggregatorsum
TitlePipeline Runs

Widget: DAG Task Executions (Query Value)

SettingValue
TypeQuery Value
Metricsum:gcp.run.job.completed_execution_count{job_name:data-pipeline-*}.as_count()
Aggregatorsum
TitleDAG Task Executions

data-pipeline-pipeline vs data-pipeline-*

data-pipeline-pipeline is the main job. Each Airflow DAG task (pipeline-daily, data-pipeline-pipeline, etc.) runs as a separate Cloud Run job. Using job_name:data-pipeline-* captures all task executions.

Widget: DAG Task Duration (Timeseries, bars)

SettingValue
TypeTimeseries (bars)
SourceAPM Metrics
MetricTotal Time
Servicedata-pipeline-pipeline
Operationpipeline.step
Group Byresource_name
TitleDAG Task Duration

This breaks down each pipeline step by name and shows how long each took. The steps that load into the gold layer are typically the most resource-intensive, since they run aggregation logic and write final business-ready tables.

Widget: Pipeline Peak CPU (Query Value)

SettingValue
TypeQuery Value
Metricavg:gcp.run.container.cpu.utilizations.avg{job_name:data-pipeline-pipeline}
Aggregatormax
TitlePipeline Peak CPU

Widget: Pipeline Peak Memory (Query Value)

SettingValue
TypeQuery Value
Metricavg:gcp.run.container.memory.usage{job_name:data-pipeline-pipeline}
Aggregatormax
TitlePipeline Peak Memory

Correct Metric Name

Use gcp.run.container.memory.usage (not utilizations). Cloud Run jobs are ephemeral (1-2 min runtime), so timeseries charts show tiny blips — Query Value with max aggregator is better.

Correct Widget Config

Set metric to avg:gcp.run.container.memory.usage{job_name:data-pipeline-pipeline}, type Query Value, aggregator max. This shows peak memory used during the job’s short execution window rather than a nearly-invisible timeseries blip.


Section 2: SQL Server VM

Widget: SQL VM — Available Memory (Query Value)

SettingValue
TypeQuery Value
Metricavg:system.mem.usable{host:data-pipeline-sql}
Aggregatorlast
TitleSQL VM — Available Memory

Widget: SQL VM — Memory (Timeseries)

SettingValue
TypeTimeseries
Query 1avg:system.mem.used{host:data-pipeline-sql}
Query 2avg:system.mem.usable{host:data-pipeline-sql}
TitleSQL VM — Memory

Widget: SQL VM — CPU (Timeseries)

SettingValue
TypeTimeseries
Query 1avg:system.cpu.user{host:data-pipeline-sql}
Query 2avg:system.cpu.system{host:data-pipeline-sql}
Query 3avg:system.cpu.iowait{host:data-pipeline-sql}
TitleSQL VM — CPU

Widget: SQL VM — System Load (Timeseries)

SettingValue
TypeTimeseries
Query 1avg:system.load.1{host:data-pipeline-sql}
Query 2avg:system.load.5{host:data-pipeline-sql}
TitleSQL VM — System Load

Widget: SQL VM — Disk I/O Wait (Timeseries)

SettingValue
TypeTimeseries
Metricavg:system.io.await{host:data-pipeline-sql} by {device}
TitleSQL VM — Disk I/O Wait

Widget: SQL VM — Disk Utilization (Timeseries)

SettingValue
TypeTimeseries
Metricavg:system.io.util{host:data-pipeline-sql} by {device}
TitleSQL VM — Disk Utilization

Widget: SQL VM — Disk IOPS (Timeseries)

SettingValue
TypeTimeseries
Query 1avg:system.io.r_s{host:data-pipeline-sql}
Query 2avg:system.io.w_s{host:data-pipeline-sql}
TitleSQL VM — Disk IOPS

Widget: SQL VM — Network (Timeseries)

SettingValue
TypeTimeseries
Query 1avg:system.net.bytes_sent{host:data-pipeline-sql}
Query 2avg:system.net.bytes_rcvd{host:data-pipeline-sql}
TitleSQL VM — Network

Section 3: SQL Server Database

Widget: SQL Server — Connections (Query Value)

SettingValue
TypeQuery Value
Metricavg:sqlserver.stats.connections{host:data-pipeline-sql}
Aggregatorlast
TitleSQL Server — Connections

Widget: SQL Server — Connections by Login (Top List)

SettingValue
TypeTop List
Metricmax:sqlserver.sqlserver.connections.by_login{host:data-pipeline-sql}
Aggregationmax by login_name
Reduce values in timeframe tomax
TitleSQL Server — Connections by Login

Two Aggregation Steps Matter

  • Spatial aggregation (left side): max by login_name — groups by login and takes the peak per login
  • Temporal aggregation (right side): reduce values in timeframe to max — takes the peak value across the selected time window

Using sum for either will inflate the numbers (sums every 15-second check interval). Always use max for both to see realistic connection counts.

Correct Aggregation Setup

In the Top List widget editor: spatial aggregation = max by login_name, temporal aggregation (reduce values) = max. This correctly shows the peak concurrent connection count per login over the selected timeframe without artificial inflation from polling intervals.

Widget: SQL Server — Buffer Cache Hit Ratio (Timeseries)

SettingValue
TypeTimeseries
Metricavg:sqlserver.buffer.cache_hit_ratio{host:data-pipeline-sql}
TitleSQL Server — Buffer Cache Hit Ratio

Buffer Cache Target

Should stay above 99%. Drops below 95% indicate memory pressure.

Widget: SQL Server — Lock Waits (Timeseries)

SettingValue
TypeTimeseries
Metricavg:sqlserver.stats.lock_waits{host:data-pipeline-sql}
TitleSQL Server — Lock Waits

Widget: SQL Server — Batch Requests/sec (Timeseries)

SettingValue
TypeTimeseries
Metricavg:sqlserver.stats.batch_requests{host:data-pipeline-sql}
TitleSQL Server — Batch Requests/sec

Widget: SQL Server — Page Life Expectancy (Timeseries)

SettingValue
TypeTimeseries
Metricavg:sqlserver.buffer.page_life_expectancy{host:data-pipeline-sql}
TitleSQL Server — Page Life Expectancy

Page Life Expectancy Target

Higher is better. Drops below 300 seconds indicate memory pressure and frequent page evictions.

Widget: SQL Server — Checkpoint Pages/sec (Timeseries)

SettingValue
TypeTimeseries
Metricavg:sqlserver.buffer.checkpoint_pages{host:data-pipeline-sql}
TitleSQL Server — Checkpoint Pages/sec

SQL Server DBA Dashboard

A dedicated dashboard for SQL Server database administration — deadlock monitoring, blocking detection, buffer pool health, and connection tracking. Separate from Pipeline Watch. The financial metrics displayed here (such as deadlock counts during index calculation windows) complement the business-level views in index-snapshot-metrics.

Create the Dashboard

  1. Go to Dashboards > New Dashboard
  2. Name it SQL Server DBA
  3. Choose Screenboard layout (free-form)

Widget 1: Deadlock Count (Query Value)

The most important widget — shows the total number of deadlocks detected.

  1. + Add WidgetQuery Value
  2. Metric: sqlserver.deadlocks.total
  3. Aggregation: sum
  4. Timeframe: Past 1 Hour
  5. Title: “Deadlock Count”
  6. Conditional Formatting:
    • Green background when value = 0
    • Red background when value > 0
  7. Click Save

Widget 2: Active Connections by Login (Timeseries)

Shows who is connected to SQL Server over time, broken down by login name and application.

  1. + Add WidgetTimeseries
  2. Metric: sqlserver.connections.by_login
  3. Group by: login_name, program_name
  4. Display: Bars (stacked)
  5. Title: “Active Connections by Login”
  6. Click Save

Widget 3: Batch Requests/sec (Timeseries)

Overall SQL Server throughput indicator.

  1. + Add WidgetTimeseries
  2. Metric: sqlserver.stats.batch_requests
  3. Display: Line
  4. Title: “Batch Requests/sec”
  5. Click Save

Widget 4: Lock Waits/sec (Timeseries)

Tracks how often queries are waiting for locks. Spikes correlate with blocking and potential deadlocks.

  1. + Add WidgetTimeseries
  2. Metric: sqlserver.stats.lock_waits
  3. Display: Line
  4. Title: “Lock Waits/sec”
  5. Click Save

Widget 5: Buffer Cache Hit Ratio (Query Value)

Should be > 99% for a healthy server. Low values indicate insufficient memory.

  1. + Add WidgetQuery Value
  2. Metric: sqlserver.buffer.cache_hit_ratio
  3. Title: “Buffer Cache Hit %”
  4. Conditional Formatting:
    • Green when value > 99
    • Yellow when value > 95
    • Red when value 95
  5. Click Save

Widget 6: Buffer Pool Size (Timeseries)

Tracks SQL Server’s buffer pool memory usage over time.

  1. + Add WidgetTimeseries
  2. Metric: sqlserver.buffer.pool_size
  3. Display: Area
  4. Title: “Buffer Pool (pages)”
  5. Click Save

Airflow Orchestration Dashboard

A custom dashboard definition is stored at infra/datadog/airflow_dashboard.json. To import it:

  1. In Datadog → Dashboards → New Dashboard → name it “Airflow” → click New Dashboard (grid layout)
  2. Inside the dashboard, click the gear icon (⚙️) → Import Dashboard JSON
  3. Paste the contents of infra/datadog/airflow_dashboard.json

Airflow Dashboard Widgets (11 total)

WidgetTypeMetric(s)
Scheduler HeartbeatCounterairflow.scheduler_heartbeat
DAG Bag SizeCounterairflow.dagbag_size
Running TasksCounterairflow.executor.running_tasks
Open SlotsCounterairflow.executor.open_slots
Successes vs FailuresBar chartairflow.ti.finish.*.success / *.failed
DAG Run DurationLine chartairflow.dagrun.duration.success.*.avg per DAG
Task Queued Duration (p95)Line chartairflow.dag.*.queued_duration.95percentile
DAG Parse TimeLine chartairflow.dag_processing.total_parse_time
Pool SlotsArea chartairflow.pool.open_slots / used_slots
Scheduler LoopLine chartairflow.scheduler.tasks.executable / starving / loop_duration
Container LogsLog streamLive logs from scheduler, webserver, triggerer

Airflow Duration Units

Airflow emits durations in microseconds. To display as seconds in Datadog, edit the widget → Y-axis → set unit to microsecond and Datadog auto-formats (e.g., 56,000,000 µs → 56s).