diff --git a/deploy/openobserve/README.md b/deploy/openobserve/README.md index 6d4fabe..b0fa327 100644 --- a/deploy/openobserve/README.md +++ b/deploy/openobserve/README.md @@ -57,6 +57,21 @@ SELECT route, FROM app_requests GROUP BY route ORDER BY err_pct DESC ``` +## 一键导入现成仪表盘(QPS / P95 / 分位 / 错误率) + +备好了 [dashboard-api-metrics.json](dashboard-api-metrics.json),4 个面板:各接口每分钟请求数(QPS 源)、 +P95 耗时折线、P50/P95/P99 分位表、5xx 错误率表。 + +- **UI 导入**:Dashboards → 右上 **Import** → 选该 JSON 文件 → Import(每次导入新建,不覆盖)。 +- **或 API 导入**: + ```bash + curl -u admin@shaguabijia.local:Complexpass#123 -H 'Content-Type: application/json' \ + -X POST 'http://localhost:5080/api/default/dashboards?folder=default' \ + --data-binary @deploy/openobserve/dashboard-api-metrics.json + ``` + +导入后进仪表盘,右上角时间调到「最近 15 分钟 / 1 小时」、开自动刷新即可。低流量下 QPS 面板看「每分钟请求数」比「每秒」直观。 + ## 停止 / 清数据 ```bash diff --git a/deploy/openobserve/dashboard-api-metrics.json b/deploy/openobserve/dashboard-api-metrics.json new file mode 100644 index 0000000..2812958 --- /dev/null +++ b/deploy/openobserve/dashboard-api-metrics.json @@ -0,0 +1,301 @@ +{ + "version": 8, + "title": "接口监控 (QPS / 耗时 / 错误率)", + "description": "app-server 接口 QPS、P50/P95/P99 耗时、5xx 错误率。数据流 app_requests。", + "role": "", + "tabs": [ + { + "tabId": "default", + "name": "Default", + "panels": [ + { + "id": "panel_qps", + "type": "line", + "title": "各接口 每分钟请求数 (QPS 源)", + "description": "", + "config": { + "show_legends": true, + "legends_position": null, + "decimals": 2.0, + "axis_border_show": false, + "base_map": null, + "map_view": null + }, + "queryType": "sql", + "queries": [ + { + "query": "SELECT histogram(_timestamp, '1 minute') as ts, route, count(*) as reqs FROM app_requests GROUP BY ts, route ORDER BY ts", + "vrlFunctionQuery": "", + "customQuery": true, + "fields": { + "stream": "app_requests", + "stream_type": "logs", + "x": [ + { + "label": "ts", + "alias": "ts", + "column": "ts", + "color": null, + "sortBy": "ASC" + } + ], + "y": [ + { + "label": "reqs", + "alias": "reqs", + "column": "reqs", + "color": null + } + ], + "z": [], + "breakdown": [ + { + "label": "route", + "alias": "route", + "column": "route", + "color": null + } + ], + "filter": { + "filterType": "group", + "logicalOperator": "AND", + "conditions": [] + } + }, + "config": { + "promql_legend": "", + "layer_type": "scatter", + "weight_fixed": 1.0 + } + } + ], + "layout": { + "x": 0, + "y": 0, + "w": 24, + "h": 9, + "i": 1 + } + }, + { + "id": "panel_p95", + "type": "line", + "title": "各接口 P95 耗时 (ms)", + "description": "", + "config": { + "show_legends": true, + "legends_position": null, + "decimals": 2.0, + "axis_border_show": false, + "base_map": null, + "map_view": null + }, + "queryType": "sql", + "queries": [ + { + "query": "SELECT histogram(_timestamp, '1 minute') as ts, route, approx_percentile_cont(duration_ms, 0.95) as p95_ms FROM app_requests GROUP BY ts, route ORDER BY ts", + "vrlFunctionQuery": "", + "customQuery": true, + "fields": { + "stream": "app_requests", + "stream_type": "logs", + "x": [ + { + "label": "ts", + "alias": "ts", + "column": "ts", + "color": null, + "sortBy": "ASC" + } + ], + "y": [ + { + "label": "p95_ms", + "alias": "p95_ms", + "column": "p95_ms", + "color": null + } + ], + "z": [], + "breakdown": [ + { + "label": "route", + "alias": "route", + "column": "route", + "color": null + } + ], + "filter": { + "filterType": "group", + "logicalOperator": "AND", + "conditions": [] + } + }, + "config": { + "promql_legend": "", + "layer_type": "scatter", + "weight_fixed": 1.0 + } + } + ], + "layout": { + "x": 24, + "y": 0, + "w": 24, + "h": 9, + "i": 2 + } + }, + { + "id": "panel_pctl", + "type": "table", + "title": "各接口 耗时分位 P50/P95/P99 (ms)", + "description": "", + "config": { + "show_legends": true, + "legends_position": null, + "decimals": 2.0, + "axis_border_show": false, + "base_map": null, + "map_view": null + }, + "queryType": "sql", + "queries": [ + { + "query": "SELECT route, approx_percentile_cont(duration_ms,0.5) as p50, approx_percentile_cont(duration_ms,0.95) as p95, approx_percentile_cont(duration_ms,0.99) as p99, count(*) as cnt FROM app_requests GROUP BY route ORDER BY p95 DESC", + "vrlFunctionQuery": "", + "customQuery": true, + "fields": { + "stream": "app_requests", + "stream_type": "logs", + "x": [ + { + "label": "route", + "alias": "route", + "column": "route", + "color": null + } + ], + "y": [ + { + "label": "p50", + "alias": "p50", + "column": "p50", + "color": null + }, + { + "label": "p95", + "alias": "p95", + "column": "p95", + "color": null + }, + { + "label": "p99", + "alias": "p99", + "column": "p99", + "color": null + }, + { + "label": "cnt", + "alias": "cnt", + "column": "cnt", + "color": null + } + ], + "z": [], + "breakdown": [], + "filter": { + "filterType": "group", + "logicalOperator": "AND", + "conditions": [] + } + }, + "config": { + "promql_legend": "", + "layer_type": "scatter", + "weight_fixed": 1.0 + } + } + ], + "layout": { + "x": 0, + "y": 9, + "w": 24, + "h": 9, + "i": 3 + } + }, + { + "id": "panel_err", + "type": "table", + "title": "各接口 错误率 (5xx %)", + "description": "", + "config": { + "show_legends": true, + "legends_position": null, + "decimals": 2.0, + "axis_border_show": false, + "base_map": null, + "map_view": null + }, + "queryType": "sql", + "queries": [ + { + "query": "SELECT route, count(*) FILTER (WHERE status >= 500) * 100.0 / count(*) as err_pct, count(*) as cnt FROM app_requests GROUP BY route ORDER BY err_pct DESC", + "vrlFunctionQuery": "", + "customQuery": true, + "fields": { + "stream": "app_requests", + "stream_type": "logs", + "x": [ + { + "label": "route", + "alias": "route", + "column": "route", + "color": null + } + ], + "y": [ + { + "label": "err_pct", + "alias": "err_pct", + "column": "err_pct", + "color": null + }, + { + "label": "cnt", + "alias": "cnt", + "column": "cnt", + "color": null + } + ], + "z": [], + "breakdown": [], + "filter": { + "filterType": "group", + "logicalOperator": "AND", + "conditions": [] + } + }, + "config": { + "promql_legend": "", + "layer_type": "scatter", + "weight_fixed": 1.0 + } + } + ], + "layout": { + "x": 24, + "y": 9, + "w": 24, + "h": 9, + "i": 4 + } + } + ] + } + ], + "variables": { + "list": [] + } +} \ No newline at end of file