{ "annotations": { "list": [] }, "editable": true, "graphTooltip": 0, "id": null, "links": [], "panels": [ { "datasource": { "type": "loki", "uid": "loki" }, "description": "HTTP-запросы core в секунду (access-лог HttpAccessLogMiddleware; строка «HTTP <метод> <путь> -> <код>»). gRPC-ингресс здесь не виден — его считают панели gRPC (HTTP-статус gRPC-вызовов всегда 200).", "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "lineWidth": 1, "showPoints": "never" }, "unit": "reqps" }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "id": 1, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { "mode": "multi", "sort": "none" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "sum(rate({service=\"core\"} |= \"HTTP \" [1m]))", "legendFormat": "HTTP core", "refId": "A" } ], "title": "HTTP RPS (core)", "type": "timeseries" }, { "datasource": { "type": "loki", "uid": "loki" }, "description": "RPC-вызовы gRPC в секунду по deal-процессам (access-лог RpcCallLoggingInterceptor; строка «gRPC <метод>: <статус>»). gRPC-health не логируется — фоновые liveness-пробы в счёт не попадают.", "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "lineWidth": 1, "showPoints": "never" }, "unit": "reqps" }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, "id": 2, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { "mode": "multi", "sort": "none" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "sum by (service) (rate({service=~\"core|telegram-service|ai-service|ml-service\"} |= \"gRPC \" [1m]))", "legendFormat": "{{service}}", "refId": "A" } ], "title": "gRPC RPS по сервисам", "type": "timeseries" }, { "datasource": { "type": "loki", "uid": "loki" }, "description": "Топ-10 HTTP-путей core по частоте вызовов, запросов/сек. По access-логу core (поле Path, query-строка не логируется).", "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "lineWidth": 1, "showPoints": "never" }, "unit": "reqps" }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 }, "id": 3, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { "mode": "multi", "sort": "none" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "topk(10, sum by (Path) (rate({service=\"core\"} | json | Path =~ \".+\" [5m])))", "legendFormat": "{{Path}}", "refId": "A" } ], "title": "HTTP RPS по путям (top-10, core)", "type": "timeseries" }, { "datasource": { "type": "loki", "uid": "loki" }, "description": "Перцентили длительности запроса core (access-лог core, поле DurationMs — миллисекунды всего пути). p95 резко растёт при недоступности БД/внешних вызовов.", "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "lineWidth": 1, "showPoints": "never" }, "unit": "ms" }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 }, "id": 4, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { "mode": "multi", "sort": "none" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "quantile_over_time(0.5, {service=\"core\"} | json | DurationMs =~ \"[0-9]+\" | unwrap DurationMs [1m])", "legendFormat": "p50", "refId": "A" }, { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "quantile_over_time(0.95, {service=\"core\"} | json | DurationMs =~ \"[0-9]+\" | unwrap DurationMs [1m])", "legendFormat": "p95", "refId": "B" } ], "title": "Длительность HTTP-запросов core (p50/p95), мс", "type": "timeseries" }, { "datasource": { "type": "loki", "uid": "loki" }, "description": "Топ-10 gRPC-методов по частоте вызовов (access-лог gRPC, поле RpcMethod — полное имя метода с пакетом).", "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "lineWidth": 1, "showPoints": "never" }, "unit": "reqps" }, "overrides": [] }, "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 }, "id": 5, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { "mode": "multi", "sort": "none" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "topk(10, sum by (RpcMethod) (rate({service=~\"core|telegram-service|ai-service|ml-service\"} |= \"gRPC \" | json | RpcMethod =~ \".+\" [5m])))", "legendFormat": "{{RpcMethod}}", "refId": "A" } ], "title": "gRPC-методы по частоте (top-10)", "type": "timeseries" }, { "datasource": { "type": "loki", "uid": "loki" }, "description": "Суммарная нагрузка (HTTP + gRPC) в секунду по всем deal-процессам за последнюю минуту.", "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null } ] }, "unit": "reqps" }, "overrides": [] }, "gridPos": { "h": 5, "w": 12, "x": 0, "y": 24 }, "id": 6, "options": { "colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" ], "fields": "", "values": false }, "textMode": "auto" }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "sum(rate({service=~\"core|telegram-service|ai-service|ml-service\"} |~ \"(HTTP|gRPC) \" [1m]))", "legendFormat": "RPS", "refId": "A" } ], "title": "RPS (HTTP+gRPC) сейчас", "type": "stat" }, { "gridPos": { "h": 5, "w": 12, "x": 12, "y": 24 }, "id": 7, "options": { "content": "RPS/нагрузка получены из access-логов (Promtail → Loki) как ленточное дополнение к метрикам. С этапа 12 (пакет A) RPS/латентность/ошибки есть и в OTel-метриках → Prometheus: дашборд Deal-Metrics-Overview (источник — Prometheus). Строка на запрос: HTTP-путь и gRPC-метод пишутся HTTP access-логом и RpcCallLoggingInterceptor без query/заголовков/тел — секретов в этих панелях нет.", "mode": "markdown" }, "title": "Откуда эти цифры", "type": "text" } ], "refresh": "1m", "schemaVersion": 39, "tags": [ "deal" ], "templating": { "list": [] }, "time": { "from": "now-6h", "to": "now" }, "timepicker": {}, "timezone": "", "title": "Deal-Rps", "uid": "deal-rps", "version": 1, "weekStart": "" }