- Add statsd-exporter service to docker-compose.yml (prom/statsd-exporter:v0.27.1) - Add StatsD env vars to airflow-default-env for metrics export - Add airflow job to prometheus.yml scrape configs - Add Airflow Overview dashboard (Grafana provisioning) - Add Airflow alert rules: scheduler down, queue backlog, failures, parse time - Add configs/statsd_mapping.yml for StatsD → Prometheus conversion - Use Prometheus naming convention (_total for counters, _seconds for timers) - Add monitoring plan at plans/monitoring_airflow_plan.md - Update OPERATIONS.md and Makefile for airflow monitoring Tested: all 3 jobs (airflow, clickhouse, kafka) showing UP in Prometheus, metrics flowing (dagbag_size=3, executor slots, heartbeats with _total suffix), all 4 alert rules loaded in Grafana
332 lines
9.6 KiB
YAML
332 lines
9.6 KiB
YAML
apiVersion: 1
|
||
|
||
groups:
|
||
- orgId: 1
|
||
name: airflow_health_group
|
||
folder: Airflow Alerts
|
||
interval: 30s
|
||
rules:
|
||
# --- Alert: Airflow Scheduler Down ---
|
||
- uid: airflow_scheduler_down
|
||
title: Airflow Scheduler Down
|
||
condition: C
|
||
data:
|
||
- refId: A
|
||
relativeTimeRange:
|
||
from: 300
|
||
to: 0
|
||
datasourceUid: prometheus_uid
|
||
model:
|
||
datasource:
|
||
type: prometheus
|
||
uid: prometheus_uid
|
||
editorMode: code
|
||
expr: rate(airflow_scheduler_heartbeat_total[5m])
|
||
instant: false
|
||
intervalMs: 1000
|
||
legendFormat: __auto
|
||
maxDataPoints: 43200
|
||
range: true
|
||
refId: A
|
||
- refId: B
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 0.1
|
||
type: lt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- B
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: A
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: B
|
||
type: threshold
|
||
- refId: C
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 0
|
||
type: gt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- C
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: B
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: C
|
||
type: threshold
|
||
noDataState: Alerting
|
||
execErrState: Error
|
||
for: 2m
|
||
annotations:
|
||
summary: "Airflow scheduler не отправляет heartbeats"
|
||
description: "Scheduler possible down — rate(airflow_scheduler_heartbeat_total) < 0.1 в течение 2 минут"
|
||
labels:
|
||
severity: critical
|
||
|
||
# --- Alert: Airflow Queue Backlog ---
|
||
- uid: airflow_queue_high
|
||
title: Airflow Queue Backlog
|
||
condition: C
|
||
data:
|
||
- refId: A
|
||
relativeTimeRange:
|
||
from: 300
|
||
to: 0
|
||
datasourceUid: prometheus_uid
|
||
model:
|
||
datasource:
|
||
type: prometheus
|
||
uid: prometheus_uid
|
||
editorMode: code
|
||
expr: airflow_executor_queued_tasks
|
||
instant: false
|
||
intervalMs: 1000
|
||
legendFormat: __auto
|
||
maxDataPoints: 43200
|
||
range: true
|
||
refId: A
|
||
- refId: B
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 50
|
||
type: gt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- B
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: A
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: B
|
||
type: threshold
|
||
- refId: C
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 0
|
||
type: gt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- C
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: B
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: C
|
||
type: threshold
|
||
noDataState: OK
|
||
execErrState: Error
|
||
for: 5m
|
||
annotations:
|
||
summary: "В очереди Airflow > 50 задач"
|
||
description: "airflow_executor_queued_tasks = {{ $values.A }} (превышает 50 в течение 5 минут) — возможна перегрузка"
|
||
labels:
|
||
severity: warning
|
||
|
||
# --- Alert: High Task Failure Rate ---
|
||
- uid: airflow_task_failures_high
|
||
title: High Task Failure Rate
|
||
condition: C
|
||
data:
|
||
- refId: A
|
||
relativeTimeRange:
|
||
from: 300
|
||
to: 0
|
||
datasourceUid: prometheus_uid
|
||
model:
|
||
datasource:
|
||
type: prometheus
|
||
uid: prometheus_uid
|
||
editorMode: code
|
||
expr: rate(airflow_task_failures_total[5m])
|
||
instant: false
|
||
intervalMs: 1000
|
||
legendFormat: __auto
|
||
maxDataPoints: 43200
|
||
range: true
|
||
refId: A
|
||
- refId: B
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 0.1
|
||
type: gt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- B
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: A
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: B
|
||
type: threshold
|
||
- refId: C
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 0
|
||
type: gt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- C
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: B
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: C
|
||
type: threshold
|
||
noDataState: OK
|
||
execErrState: Error
|
||
for: 3m
|
||
annotations:
|
||
summary: "Высокий rate падений тасков"
|
||
description: "rate(airflow_task_failures_total) = {{ $values.A }} (превышает 0.1 в течение 3 минут) — проверьте логи DAG"
|
||
labels:
|
||
severity: warning
|
||
|
||
# --- Alert: High DAG Parse Time ---
|
||
- uid: airflow_parse_time_high
|
||
title: High DAG Parse Time
|
||
condition: C
|
||
data:
|
||
- refId: A
|
||
relativeTimeRange:
|
||
from: 300
|
||
to: 0
|
||
datasourceUid: prometheus_uid
|
||
model:
|
||
datasource:
|
||
type: prometheus
|
||
uid: prometheus_uid
|
||
editorMode: code
|
||
expr: airflow_dag_processing_total_parse_time
|
||
instant: false
|
||
intervalMs: 1000
|
||
legendFormat: __auto
|
||
maxDataPoints: 43200
|
||
range: true
|
||
refId: A
|
||
- refId: B
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 30
|
||
type: gt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- B
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: A
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: B
|
||
type: threshold
|
||
- refId: C
|
||
datasourceUid: __expr__
|
||
model:
|
||
conditions:
|
||
- evaluator:
|
||
params:
|
||
- 0
|
||
type: gt
|
||
operator:
|
||
type: and
|
||
query:
|
||
params:
|
||
- C
|
||
reducer:
|
||
params: []
|
||
type: last
|
||
type: query
|
||
datasource:
|
||
type: __expr__
|
||
uid: __expr__
|
||
expression: B
|
||
intervalMs: 1000
|
||
maxDataPoints: 43200
|
||
refId: C
|
||
type: threshold
|
||
noDataState: OK
|
||
execErrState: Error
|
||
for: 5m
|
||
annotations:
|
||
summary: "Парсинг DAG занимает > 30 секунд"
|
||
description: "airflow_dag_processing_total_parse_time = {{ $values.A }}s — возможно, есть тяжелые DAG"
|
||
labels:
|
||
severity: info
|