{ "title": "БД и пулы соединений", "description": "Доступность БД (vidconf_db_up) и занятость основных пулов (SQLAlchemy/БД, Redis) — метрики читаются вне самих пулов, доступны и при их исчерпании (сессия 33, разбор инцидента 07.08 — .forcc/session-results/32-loadtest-07-08-debug.md). Пороги алертов см. deploy/monitoring/alerts.yml (группа vidconf-db).", "uid": "vidconf-db-pool", "editable": false, "timezone": "browser", "schemaVersion": 39, "version": 1, "time": { "from": "now-1h", "to": "now" }, "refresh": "10s", "tags": ["vidconf", "db", "pool"], "panels": [ { "id": 1, "title": "БД доступна", "description": "vidconf_db_up — отдельное соединение вне основного пула (core/db.py::check_db_up). Алерт DatabaseUnavailable, for: 30s.", "type": "stat", "gridPos": { "h": 4, "w": 6, "x": 0, "y": 0 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "mappings": [ { "type": "value", "options": { "0": { "text": "DOWN", "color": "red" }, "1": { "text": "UP", "color": "green" } } } ], "thresholds": { "mode": "absolute", "steps": [{ "color": "red", "value": null }, { "color": "green", "value": 1 }] } }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "vidconf_db_up", "refId": "A" } ] }, { "id": 2, "title": "Занятость пула БД сейчас, %", "description": "vidconf_db_pool_checked_out / (vidconf_db_pool_size + vidconf_db_pool_max_overflow) * 100. Порог алерта DbConnectionPoolNearExhaustion — 80% дольше минуты.", "type": "stat", "gridPos": { "h": 4, "w": 6, "x": 6, "y": 0 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "unit": "percent", "min": 0, "max": 100, "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "orange", "value": 60 }, { "color": "red", "value": 80 }] } }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "(vidconf_db_pool_checked_out / (vidconf_db_pool_size + vidconf_db_pool_max_overflow)) * 100", "refId": "A" } ] }, { "id": 3, "title": "Занятость пула Redis сейчас, %", "description": "vidconf_redis_pool_in_use / vidconf_redis_pool_max_connections * 100. Порог алерта RedisConnectionPoolNearExhaustion — 80% дольше минуты.", "type": "stat", "gridPos": { "h": 4, "w": 6, "x": 12, "y": 0 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "unit": "percent", "min": 0, "max": 100, "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "orange", "value": 60 }, { "color": "red", "value": 80 }] } }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "(vidconf_redis_pool_in_use / vidconf_redis_pool_max_connections) * 100", "refId": "A" } ] }, { "id": 4, "title": "Активных алертов группы vidconf-db", "description": "ALERTS{alertname=~\"DatabaseUnavailable|.*PoolNearExhaustion\", alertstate=\"firing\"} — снимок того, что прямо сейчас видит Alertmanager/страница Alerts.", "type": "stat", "gridPos": { "h": 4, "w": 6, "x": 18, "y": 0 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "red", "value": 1 }] } }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "count(ALERTS{alertname=~\"DatabaseUnavailable|.*PoolNearExhaustion\", alertstate=\"firing\"}) OR on() vector(0)", "refId": "A" } ] }, { "id": 5, "title": "Занятость пула БД (соединений)", "description": "vidconf_db_pool_checked_out на фоне вместимости (size + max_overflow) — эта картина должна расти под нагрузочным тестом до срабатывания алерта. Ранний сигнал: в инциденте 07.08 занятость росла постепенно по мере входа участников в комнату, а не рывком от общей HTTP-нагрузки.", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10 } }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "vidconf_db_pool_checked_out", "legendFormat": "занято", "refId": "A" }, { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "vidconf_db_pool_size + vidconf_db_pool_max_overflow", "legendFormat": "вместимость (size+overflow)", "refId": "B" } ] }, { "id": 6, "title": "Занятость пула Redis (соединений)", "description": "vidconf_redis_pool_in_use на фоне vidconf_redis_pool_max_connections. Второй потолок того же класса, что у БД (закрыт в 0.0.31, redis-py 8 сменил дефолт max_connections на 100).", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10 } }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "vidconf_redis_pool_in_use", "legendFormat": "занято", "refId": "A" }, { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "vidconf_redis_pool_max_connections", "legendFormat": "вместимость", "refId": "B" } ] }, { "id": 7, "title": "БД доступна во времени", "description": "vidconf_db_up как временной ряд — удобно видеть провал целиком (начало/длительность отказа), не только текущее состояние.", "type": "timeseries", "gridPos": { "h": 6, "w": 12, "x": 0, "y": 12 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "min": 0, "max": 1, "custom": { "drawStyle": "line", "fillOpacity": 20, "lineInterpolation": "stepAfter" }, "mappings": [ { "type": "value", "options": { "0": { "text": "DOWN" }, "1": { "text": "UP" } } } ] }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "vidconf_db_up", "legendFormat": "db_up", "refId": "A" } ] }, { "id": 8, "title": "Сеансы failed / очереди Celery (для сверки с общей нагрузкой)", "description": "Тот же контекст, что на дашборде «Пайплайны пост-обработки» — здесь рядом с пулами, чтобы не переключаться между дашбордами при разборе инцидента.", "type": "timeseries", "gridPos": { "h": 6, "w": 12, "x": 12, "y": 12 }, "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 5 } }, "overrides": [] }, "targets": [ { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "vidconf_pipeline_sessions{status=\"failed\"}", "legendFormat": "сеансов failed", "refId": "A" }, { "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "sum(vidconf_celery_queue_depth)", "legendFormat": "глубина очередей (сумма)", "refId": "B" } ] } ] }