diff --git a/api-reference/monitors.openapi.en.json b/api-reference/monitors.openapi.en.json index ca9a4c39..301f9075 100644 --- a/api-reference/monitors.openapi.en.json +++ b/api-reference/monitors.openapi.en.json @@ -2208,6 +2208,291 @@ } } } + }, + "/monit/query/explore": { + "post": { + "description": "Run an Explore query against a configured data source and return frames, samples, or logs.", + "operationId": "monit-read-query-explore", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryExploreRequest" + }, + "example": { + "datasource_id": 101, + "expr": "rate(http_requests_total[5m])", + "args": {}, + "execution": { + "kind": "range", + "from_ms": 1787187600000, + "to_ms": 1787191200000, + "max_data_points": 1200, + "min_step_seconds": 15 + } + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ExploreData" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "format": "explore_result.v1", + "result": { + "kind": "frames", + "frames": [ + { + "kind": "time_series", + "fields": [ + { + "name": "time", + "type": "time", + "values": [ + "2026-08-20T10:00:00Z", + "2026-08-20T10:01:00Z" + ] + }, + { + "name": "value", + "type": "float", + "labels": { + "job": "api" + }, + "values": [ + 1.25, + null + ] + } + ] + } + ] + }, + "execution": { + "kind": "range", + "effective_step_seconds": 60 + } + } + } + } + } + }, + "400": { + "description": "Standard HTTP error; error.reason: invalid_request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "Standard HTTP error; error.reason: access_denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Standard HTTP error; error.reason: datasource_not_found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "413": { + "description": "Standard HTTP error; error.reason: source_too_large, result_too_large.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "429": { + "description": "Standard HTTP error; error.reason: overloaded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "499": { + "description": "Standard HTTP error; error.reason: canceled.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Standard HTTP error; error.reason: internal.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Standard HTTP error; error.reason: no_active_edge, edge_upgrade_required, mixed_edge_versions, edge_unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "504": { + "description": "Standard HTTP error; error.reason: timeout.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "summary": "Run Explore query", + "tags": [ + "Monitors/Diagnostics" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **100 requests/minute**; **16 requests/second** per account |\n| Permissions | **Datasources Read** (`monit`) |\n| Edge requirement | Supported deployments require **monit-edge v0.68.0 or later** |\n\n## Usage\n\n- Use this endpoint when you need the data source's native result shape; `/monit/query/data` returns the stable `query_result.v1` contract instead. Dispatch on `data.result.kind` (`frames`, `samples`, or `logs`) here.\n- `execution.kind` decides which companion fields are accepted: `instant` needs only `to_ms`, `range` requires `from_ms`, `to_ms`, and `max_data_points`, and `window` takes `from_ms` and `to_ms`. `step_seconds` is not accepted; the step is derived from `max_data_points` and `min_step_seconds`.\n- `args` carries macro substitutions such as Grafana-style variables; every value is a string.\n- A `logs` result is capped at 1,000 entries and reports `applied_limit` plus `has_more`. Time-series and sample results are capped at 1,000 items each and the whole success response at 8 MiB.\n- Query execution may take up to 35 seconds across WebAPI forwarding and Edge execution. Configure client timeouts to at least 40 seconds.", + "href": "/en/api-reference/monitors/diagnostics/monit-read-query-explore", + "metadata": { + "sidebarTitle": "Run Explore query" + } + } + } + }, + "/monit/prometheus/api/v1/label/{label_name}/values": { + "get": { + "description": "Read label values from a Prometheus-compatible data source through the Monitors proxy.", + "operationId": "monit-prometheus-read-label-values", + "parameters": [ + { + "name": "label_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Label name to enumerate values for, for example `job`." + }, + { + "name": "X-DSID", + "in": "header", + "required": true, + "schema": { + "type": "string" + }, + "description": "Data source ID to query. Must reference a Prometheus-compatible data source owned by the authenticated account." + } + ], + "responses": { + "200": { + "description": "Native Prometheus label-values response returned by the data source.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrometheusLabelValuesResponse" + }, + "example": { + "status": "success", + "data": [ + "api", + "db", + "worker" + ] + } + } + } + }, + "400": { + "description": "The `X-DSID` header is missing or invalid, the data source does not exist, or it is not a Prometheus data source. Returned as `text/plain`.", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "description": "The data source lookup or the proxied request failed. Returned as `text/plain`.", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "503": { + "description": "No monit-edge in the data source's cluster supports the data source resource proxy. Returned as `text/plain`; upgrade monit-edge.", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + } + }, + "summary": "List Prometheus label values", + "tags": [ + "Monitors/Data sources" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n| Edge requirement | Supported deployments require **monit-edge v0.35.0 or later** |\n\n## Usage\n\n- Pass the target data source in the `X-DSID` header. It must be a Prometheus-compatible data source owned by the authenticated account; use `/monit/datasource/list` to obtain its ID.\n- The 200 body is the data source's native Prometheus HTTP API payload, **not** the standard `{ request_id, data }` envelope. Failures raised before the data source is reached are returned as `text/plain` with the matching 4xx or 5xx status.\n- When `X-DSID` is omitted, the request falls back to the platform's own Prometheus proxy. Send the header to query a specific data source.", + "href": "/en/api-reference/monitors/data-sources/monit-prometheus-read-label-values", + "metadata": { + "sidebarTitle": "List Prometheus label values" + } + } + } } }, "components": { @@ -5039,6 +5324,309 @@ "reason" ], "type": "object" + }, + "QueryExploreRequest": { + "type": "object", + "description": "Explore query request. All four top-level fields are required and unknown fields are rejected.", + "required": [ + "datasource_id", + "expr", + "args", + "execution" + ], + "properties": { + "datasource_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "maximum": 9007199254740991, + "description": "Data source ID from `/monit/datasource/list`. Must be a positive JavaScript-safe integer and belong to the authenticated account." + }, + "expr": { + "type": "string", + "minLength": 1, + "description": "Query expression in the data source's native language (PromQL, LogsQL, SQL, and so on). Non-empty UTF-8 of at most 64 KiB; some data source types enforce a lower limit." + }, + "args": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "maxProperties": 128, + "description": "Macro substitutions keyed by variable name, used for Grafana-style variables. Keys are at most 256 bytes, values at most 64 KiB, with a 128 KiB total budget." + }, + "execution": { + "$ref": "#/components/schemas/QueryExploreExecution" + } + } + }, + "QueryExploreExecution": { + "type": "object", + "description": "Time semantics of the query. The accepted companion fields depend on `kind`: `instant` takes only `to_ms` (plus optional `from_ms`), `range` requires `from_ms`, `to_ms`, and `max_data_points`, and `window` takes only `from_ms` and `to_ms`. `step_seconds` is never accepted over HTTP.", + "required": [ + "kind" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "instant", + "range", + "window" + ], + "description": "Execution kind. `instant` evaluates at a single point in time, `range` evaluates a series over a range, and `window` returns raw rows inside a time window." + }, + "from_ms": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in milliseconds for the start of the range. Required for `range` and `window`; optional for `instant`." + }, + "to_ms": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in milliseconds for the end of the range. Required for every execution kind." + }, + "max_data_points": { + "type": "integer", + "format": "int64", + "minimum": 2, + "maximum": 5000, + "description": "Maximum number of points to return. Required for `range` and rejected for `instant` and `window`." + }, + "min_step_seconds": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Lower bound, in seconds, for the step derived from `max_data_points`. Optional and only accepted for `range`." + } + } + }, + "ExploreData": { + "type": "object", + "description": "Explore query result payload.", + "required": [ + "format", + "result" + ], + "properties": { + "format": { + "type": "string", + "enum": [ + "explore_result.v1" + ], + "description": "Result contract version; always `explore_result.v1`." + }, + "result": { + "$ref": "#/components/schemas/ExploreResult" + }, + "execution": { + "$ref": "#/components/schemas/ExploreResponseExecution" + } + } + }, + "ExploreResult": { + "type": "object", + "description": "Result body. Exactly one of `frames`, `samples`, or `entries` is present and matches `kind`.", + "required": [ + "kind" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "frames", + "samples", + "logs" + ], + "description": "Result shape. `frames` returns columnar tables or time series, `samples` returns instant values with labels, and `logs` returns log entries." + }, + "frames": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreFrame" + }, + "description": "Columnar frames. Present when `kind` is `frames`; at most 1,000 frames." + }, + "samples": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreSample" + }, + "description": "Instant samples. Present when `kind` is `samples`; at most 1,000 samples." + }, + "entries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreLogEntry" + }, + "description": "Log entries. Present when `kind` is `logs`; never longer than `applied_limit`." + }, + "applied_limit": { + "type": "integer", + "description": "Entry limit applied to a logs result; at most 1000." + }, + "has_more": { + "type": "boolean", + "description": "Whether a logs result was truncated by `applied_limit`." + } + } + }, + "ExploreFrame": { + "type": "object", + "description": "One columnar frame. Every field in the frame has the same number of values.", + "required": [ + "kind", + "fields" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "table", + "time_series" + ], + "description": "Frame shape. `table` is an unlabeled table, while `time_series` carries exactly one time field and one float field." + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreField" + }, + "description": "Columns of the frame." + } + } + }, + "ExploreField": { + "type": "object", + "description": "One column of a frame. Values are columnar and may contain nulls.", + "required": [ + "name", + "type", + "values" + ], + "properties": { + "name": { + "type": "string", + "description": "Column name, at most 1 MiB of UTF-8." + }, + "type": { + "type": "string", + "enum": [ + "string", + "float", + "time" + ], + "description": "Column type. `string` is rejected inside a `time_series` frame; `float` holds numbers and `time` holds UTC RFC3339Nano strings." + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Label set of this column. Only `time_series` value fields may carry labels; a `table` field must not." + }, + "values": { + "type": "array", + "items": { + "description": "One cell. `time` cells are UTC RFC3339Nano strings; `float` cells may be the strings `NaN`, `+Inf`, and `-Inf`; any cell may be null except a time value inside a `time_series` frame." + }, + "description": "Column values in row order." + } + } + }, + "ExploreSample": { + "type": "object", + "description": "One instant sample.", + "required": [ + "labels", + "value" + ], + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Label set of the sample. May be empty but never null." + }, + "value": { + "description": "Sample value: a number, or one of the strings `NaN`, `+Inf`, and `-Inf`. Never null." + } + } + }, + "ExploreLogEntry": { + "type": "object", + "description": "One log entry.", + "required": [ + "timestamp_ns", + "fields" + ], + "properties": { + "timestamp_ns": { + "type": "string", + "description": "Entry time as a canonical unsigned decimal string of Unix epoch nanoseconds, at most 20 digits." + }, + "fields": { + "type": "object", + "additionalProperties": true, + "description": "Log fields as raw JSON values. Integer literals outside JavaScript's safe integer range are returned as decimal strings." + } + } + }, + "ExploreResponseExecution": { + "type": "object", + "description": "Execution actually used, present when the data source returned a stepped result.", + "required": [ + "kind", + "effective_step_seconds" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "range" + ], + "description": "Execution kind; always `range` when this object is present." + }, + "effective_step_seconds": { + "type": "integer", + "format": "int64", + "description": "Step, in seconds, the query was executed with after applying `max_data_points` and `min_step_seconds`." + } + } + }, + "PrometheusLabelValuesResponse": { + "type": "object", + "description": "Native Prometheus HTTP API response returned by the queried data source. This endpoint does not wrap the payload in the Flashduty response envelope.", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "success", + "error" + ], + "description": "Prometheus result status. `success` carries `data`; `error` carries `errorType` and `error`." + }, + "data": { + "type": "array", + "items": { + "type": "string", + "description": "One label value." + }, + "description": "Label values, present when `status` is `success`." + }, + "errorType": { + "type": "string", + "description": "Prometheus error class, present when `status` is `error`." + }, + "error": { + "type": "string", + "description": "Human-readable Prometheus error message, present when `status` is `error`." + } + } } } } diff --git a/api-reference/monitors.openapi.zh.json b/api-reference/monitors.openapi.zh.json index da729118..951455b0 100644 --- a/api-reference/monitors.openapi.zh.json +++ b/api-reference/monitors.openapi.zh.json @@ -2208,6 +2208,291 @@ } } } + }, + "/monit/query/explore": { + "post": { + "description": "对已配置的数据源执行探索查询,返回 frames、samples 或 logs 形态的结果。", + "operationId": "monit-read-query-explore", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryExploreRequest" + }, + "example": { + "datasource_id": 101, + "expr": "rate(http_requests_total[5m])", + "args": {}, + "execution": { + "kind": "range", + "from_ms": 1787187600000, + "to_ms": 1787191200000, + "max_data_points": 1200, + "min_step_seconds": 15 + } + } + } + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ExploreData" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "format": "explore_result.v1", + "result": { + "kind": "frames", + "frames": [ + { + "kind": "time_series", + "fields": [ + { + "name": "time", + "type": "time", + "values": [ + "2026-08-20T10:00:00Z", + "2026-08-20T10:01:00Z" + ] + }, + { + "name": "value", + "type": "float", + "labels": { + "job": "api" + }, + "values": [ + 1.25, + null + ] + } + ] + } + ] + }, + "execution": { + "kind": "range", + "effective_step_seconds": 60 + } + } + } + } + } + }, + "400": { + "description": "标准 HTTP 错误;error.reason:invalid_request。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "标准 HTTP 错误;error.reason:access_denied。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "标准 HTTP 错误;error.reason:datasource_not_found。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "413": { + "description": "标准 HTTP 错误;error.reason:source_too_large、result_too_large。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "429": { + "description": "标准 HTTP 错误;error.reason:overloaded。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "499": { + "description": "标准 HTTP 错误;error.reason:canceled。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "标准 HTTP 错误;error.reason:internal。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "标准 HTTP 错误;error.reason:no_active_edge、edge_upgrade_required、mixed_edge_versions、edge_unavailable。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "504": { + "description": "标准 HTTP 错误;error.reason:timeout。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "summary": "执行探索查询", + "tags": [ + "Monitors/诊断分析" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **100 次/分钟**;**16 次/秒** |\n| 权限要求 | **数据源查看**(`monit`) |\n| Edge 版本要求 | 受支持的部署要求 **monit-edge v0.68.0 或更高版本** |\n\n## 使用说明\n\n- 需要数据源原生结果形态时使用本接口;`/monit/query/data` 返回稳定的 `query_result.v1` 契约。本接口根据 `data.result.kind`(`frames`、`samples` 或 `logs`)分发结果。\n- `execution.kind` 决定可接受的配套字段:`instant` 只需 `to_ms`,`range` 需要 `from_ms`、`to_ms` 和 `max_data_points`,`window` 需要 `from_ms` 和 `to_ms`。不接受 `step_seconds`,步长由 `max_data_points` 与 `min_step_seconds` 推导。\n- `args` 用于宏替换(例如 Grafana 风格变量),取值均为字符串。\n- `logs` 结果最多返回 1,000 条,并通过 `applied_limit` 与 `has_more` 说明截断情况。时序与采样结果各最多 1,000 条,成功响应整体上限 8 MiB。\n- WebAPI 跨实例转发与 Edge 执行合计可能耗时 35 秒,客户端超时建议至少 40 秒。", + "href": "/zh/api-reference/monitors/diagnostics/monit-read-query-explore", + "metadata": { + "sidebarTitle": "执行探索查询" + } + } + } + }, + "/monit/prometheus/api/v1/label/{label_name}/values": { + "get": { + "description": "通过监控代理从 Prometheus 兼容数据源读取标签值列表。", + "operationId": "monit-prometheus-read-label-values", + "parameters": [ + { + "name": "label_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "要枚举取值的标签名,例如 `job`。" + }, + { + "name": "X-DSID", + "in": "header", + "required": true, + "schema": { + "type": "string" + }, + "description": "要查询的数据源 ID,必须是当前账户下 Prometheus 兼容类型的数据源。" + } + ], + "responses": { + "200": { + "description": "数据源返回的原生 Prometheus 标签值响应。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrometheusLabelValuesResponse" + }, + "example": { + "status": "success", + "data": [ + "api", + "db", + "worker" + ] + } + } + } + }, + "400": { + "description": "`X-DSID` 请求头缺失或非法、数据源不存在,或该数据源不是 Prometheus 类型。以 `text/plain` 返回。", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "description": "数据源查询或代理请求失败。以 `text/plain` 返回。", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "503": { + "description": "数据源所在集群中没有支持数据源资源代理的 monit-edge。以 `text/plain` 返回,请升级 monit-edge。", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + } + }, + "summary": "查询 Prometheus 标签值列表", + "tags": [ + "Monitors/告警数据源" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 任意有效的 `app_key`(只读,不受特定权限分类限制) |\n| Edge 版本要求 | 受支持的部署要求 **monit-edge v0.35.0 或更高版本** |\n\n## 使用说明\n\n- 通过 `X-DSID` 请求头指定目标数据源,必须是当前账户下 Prometheus 兼容类型的数据源;可用 `/monit/datasource/list` 获取 ID。\n- 200 响应体是数据源原生的 Prometheus HTTP API 结构,**不是**统一的 `{ request_id, data }` envelope。未到达数据源前发生的失败以 `text/plain` 返回,并携带对应的 4xx/5xx 状态码。\n- 省略 `X-DSID` 时会回退到平台自有的 Prometheus 代理;需要查询指定数据源时必须携带该请求头。", + "href": "/zh/api-reference/monitors/data-sources/monit-prometheus-read-label-values", + "metadata": { + "sidebarTitle": "查询 Prometheus 标签值列表" + } + } + } } }, "components": { @@ -5039,6 +5324,309 @@ "reason" ], "type": "object" + }, + "QueryExploreRequest": { + "type": "object", + "description": "探索查询请求。四个顶层字段均为必填,未知字段会被拒绝。", + "required": [ + "datasource_id", + "expr", + "args", + "execution" + ], + "properties": { + "datasource_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "maximum": 9007199254740991, + "description": "数据源 ID,来自 `/monit/datasource/list`。必须是正数且不超过 JavaScript 安全整数范围,且属于当前账户。" + }, + "expr": { + "type": "string", + "minLength": 1, + "description": "使用数据源原生语言的查询表达式(如 PromQL、LogsQL、SQL 等)。非空 UTF-8 字符串,最长 64 KiB;部分数据源类型限制更小。" + }, + "args": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "maxProperties": 128, + "description": "宏替换参数,按变量名索引,用于 Grafana 风格变量。键最长 256 字节,值最长 64 KiB,总预算 128 KiB。" + }, + "execution": { + "$ref": "#/components/schemas/QueryExploreExecution" + } + } + }, + "QueryExploreExecution": { + "type": "object", + "description": "查询的时间语义。可接受的配套字段取决于 `kind`:`instant` 只需 `to_ms`(`from_ms` 可选),`range` 需要 `from_ms`、`to_ms` 和 `max_data_points`,`window` 需要 `from_ms` 和 `to_ms`。HTTP 接口不接受 `step_seconds`。", + "required": [ + "kind" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "instant", + "range", + "window" + ], + "description": "执行类型。`instant` 在单个时间点取值,`range` 在时间范围内取序列,`window` 返回时间窗口内的原始行。" + }, + "from_ms": { + "type": "integer", + "format": "int64", + "description": "范围起点的 Unix 毫秒时间戳。`range` 和 `window` 必填,`instant` 可选。" + }, + "to_ms": { + "type": "integer", + "format": "int64", + "description": "范围终点的 Unix 毫秒时间戳。所有执行类型均必填。" + }, + "max_data_points": { + "type": "integer", + "format": "int64", + "minimum": 2, + "maximum": 5000, + "description": "返回的数据点数量上限。`range` 必填,`instant` 与 `window` 不接受该字段。" + }, + "min_step_seconds": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "由 `max_data_points` 推导出的步长下限(秒)。可选,仅在 `range` 下接受。" + } + } + }, + "ExploreData": { + "type": "object", + "description": "探索查询结果载荷。", + "required": [ + "format", + "result" + ], + "properties": { + "format": { + "type": "string", + "enum": [ + "explore_result.v1" + ], + "description": "结果契约版本,固定为 `explore_result.v1`。" + }, + "result": { + "$ref": "#/components/schemas/ExploreResult" + }, + "execution": { + "$ref": "#/components/schemas/ExploreResponseExecution" + } + } + }, + "ExploreResult": { + "type": "object", + "description": "结果主体。`frames`、`samples`、`entries` 三者中只有与 `kind` 匹配的一个会出现。", + "required": [ + "kind" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "frames", + "samples", + "logs" + ], + "description": "结果形态。`frames` 返回列式表格或时序,`samples` 返回带标签的瞬时值,`logs` 返回日志条目。" + }, + "frames": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreFrame" + }, + "description": "列式 Frame 列表,`kind` 为 `frames` 时出现,最多 1,000 个。" + }, + "samples": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreSample" + }, + "description": "瞬时采样列表,`kind` 为 `samples` 时出现,最多 1,000 条。" + }, + "entries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreLogEntry" + }, + "description": "日志条目列表,`kind` 为 `logs` 时出现,长度不超过 `applied_limit`。" + }, + "applied_limit": { + "type": "integer", + "description": "日志结果实际生效的条数上限,最大 1000。" + }, + "has_more": { + "type": "boolean", + "description": "日志结果是否因 `applied_limit` 被截断。" + } + } + }, + "ExploreFrame": { + "type": "object", + "description": "单个列式 Frame,Frame 内所有字段的取值数量一致。", + "required": [ + "kind", + "fields" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "table", + "time_series" + ], + "description": "Frame 形态。`table` 为无标签表格,`time_series` 恰好包含一个时间字段和一个 float 字段。" + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExploreField" + }, + "description": "Frame 的列。" + } + } + }, + "ExploreField": { + "type": "object", + "description": "Frame 的一列。取值按列组织,可以包含 null。", + "required": [ + "name", + "type", + "values" + ], + "properties": { + "name": { + "type": "string", + "description": "列名,最长 1 MiB 的 UTF-8 字符串。" + }, + "type": { + "type": "string", + "enum": [ + "string", + "float", + "time" + ], + "description": "列类型。`time_series` 内不接受 `string`;`float` 存放数值,`time` 取值为 UTC RFC3339Nano 字符串。" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "该列的标签集合。仅 `time_series` 的取值字段可以携带标签,`table` 字段不允许。" + }, + "values": { + "type": "array", + "items": { + "description": "单个单元格。`time` 为 UTC RFC3339Nano 字符串,`float` 可以是字符串 `NaN`、`+Inf`、`-Inf`,除 `time_series` 中的时间值外均可以为 null。" + }, + "description": "按行顺序排列的列取值。" + } + } + }, + "ExploreSample": { + "type": "object", + "description": "单个瞬时采样。", + "required": [ + "labels", + "value" + ], + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "采样的标签集合。可以为空,但不能为 null。" + }, + "value": { + "description": "采样值:数字,或字符串 `NaN`、`+Inf`、`-Inf`。不能为 null。" + } + } + }, + "ExploreLogEntry": { + "type": "object", + "description": "单条日志。", + "required": [ + "timestamp_ns", + "fields" + ], + "properties": { + "timestamp_ns": { + "type": "string", + "description": "条目时间,使用 Unix 纪元纳秒的规范无符号十进制字符串表示,最长 20 位。" + }, + "fields": { + "type": "object", + "additionalProperties": true, + "description": "日志字段的原始 JSON 取值。超出 JavaScript 安全整数范围的整数字面量会以十进制字符串返回。" + } + } + }, + "ExploreResponseExecution": { + "type": "object", + "description": "实际使用的执行信息,数据源返回带步长结果时出现。", + "required": [ + "kind", + "effective_step_seconds" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "range" + ], + "description": "执行类型;该对象出现时固定为 `range`。" + }, + "effective_step_seconds": { + "type": "integer", + "format": "int64", + "description": "应用 `max_data_points` 与 `min_step_seconds` 后实际执行的步长(秒)。" + } + } + }, + "PrometheusLabelValuesResponse": { + "type": "object", + "description": "所查询数据源返回的原生 Prometheus HTTP API 响应。本接口不会把结果包装进 Flashduty 统一响应 envelope。", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "success", + "error" + ], + "description": "Prometheus 结果状态。`success` 携带 `data`,`error` 携带 `errorType` 与 `error`。" + }, + "data": { + "type": "array", + "items": { + "type": "string", + "description": "一个标签值。" + }, + "description": "标签值列表,`status` 为 `success` 时出现。" + }, + "errorType": { + "type": "string", + "description": "Prometheus 错误类别,`status` 为 `error` 时出现。" + }, + "error": { + "type": "string", + "description": "Prometheus 错误信息,`status` 为 `error` 时出现。" + } + } } } } diff --git a/api-reference/openapi.en.json b/api-reference/openapi.en.json index 2cb4760c..3c812eee 100644 --- a/api-reference/openapi.en.json +++ b/api-reference/openapi.en.json @@ -8899,6 +8899,200 @@ ], "type": "object" }, + "ExploreData": { + "description": "Explore query result payload.", + "properties": { + "execution": { + "$ref": "#/components/schemas/ExploreResponseExecution" + }, + "format": { + "description": "Result contract version; always `explore_result.v1`.", + "enum": [ + "explore_result.v1" + ], + "type": "string" + }, + "result": { + "$ref": "#/components/schemas/ExploreResult" + } + }, + "required": [ + "format", + "result" + ], + "type": "object" + }, + "ExploreField": { + "description": "One column of a frame. Values are columnar and may contain nulls.", + "properties": { + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "Label set of this column. Only `time_series` value fields may carry labels; a `table` field must not.", + "type": "object" + }, + "name": { + "description": "Column name, at most 1 MiB of UTF-8.", + "type": "string" + }, + "type": { + "description": "Column type. `string` is rejected inside a `time_series` frame; `float` holds numbers and `time` holds UTC RFC3339Nano strings.", + "enum": [ + "string", + "float", + "time" + ], + "type": "string" + }, + "values": { + "description": "Column values in row order.", + "items": { + "description": "One cell. `time` cells are UTC RFC3339Nano strings; `float` cells may be the strings `NaN`, `+Inf`, and `-Inf`; any cell may be null except a time value inside a `time_series` frame." + }, + "type": "array" + } + }, + "required": [ + "name", + "type", + "values" + ], + "type": "object" + }, + "ExploreFrame": { + "description": "One columnar frame. Every field in the frame has the same number of values.", + "properties": { + "fields": { + "description": "Columns of the frame.", + "items": { + "$ref": "#/components/schemas/ExploreField" + }, + "type": "array" + }, + "kind": { + "description": "Frame shape. `table` is an unlabeled table, while `time_series` carries exactly one time field and one float field.", + "enum": [ + "table", + "time_series" + ], + "type": "string" + } + }, + "required": [ + "kind", + "fields" + ], + "type": "object" + }, + "ExploreLogEntry": { + "description": "One log entry.", + "properties": { + "fields": { + "additionalProperties": true, + "description": "Log fields as raw JSON values. Integer literals outside JavaScript's safe integer range are returned as decimal strings.", + "type": "object" + }, + "timestamp_ns": { + "description": "Entry time as a canonical unsigned decimal string of Unix epoch nanoseconds, at most 20 digits.", + "type": "string" + } + }, + "required": [ + "timestamp_ns", + "fields" + ], + "type": "object" + }, + "ExploreResponseExecution": { + "description": "Execution actually used, present when the data source returned a stepped result.", + "properties": { + "effective_step_seconds": { + "description": "Step, in seconds, the query was executed with after applying `max_data_points` and `min_step_seconds`.", + "format": "int64", + "type": "integer" + }, + "kind": { + "description": "Execution kind; always `range` when this object is present.", + "enum": [ + "range" + ], + "type": "string" + } + }, + "required": [ + "kind", + "effective_step_seconds" + ], + "type": "object" + }, + "ExploreResult": { + "description": "Result body. Exactly one of `frames`, `samples`, or `entries` is present and matches `kind`.", + "properties": { + "applied_limit": { + "description": "Entry limit applied to a logs result; at most 1000.", + "type": "integer" + }, + "entries": { + "description": "Log entries. Present when `kind` is `logs`; never longer than `applied_limit`.", + "items": { + "$ref": "#/components/schemas/ExploreLogEntry" + }, + "type": "array" + }, + "frames": { + "description": "Columnar frames. Present when `kind` is `frames`; at most 1,000 frames.", + "items": { + "$ref": "#/components/schemas/ExploreFrame" + }, + "type": "array" + }, + "has_more": { + "description": "Whether a logs result was truncated by `applied_limit`.", + "type": "boolean" + }, + "kind": { + "description": "Result shape. `frames` returns columnar tables or time series, `samples` returns instant values with labels, and `logs` returns log entries.", + "enum": [ + "frames", + "samples", + "logs" + ], + "type": "string" + }, + "samples": { + "description": "Instant samples. Present when `kind` is `samples`; at most 1,000 samples.", + "items": { + "$ref": "#/components/schemas/ExploreSample" + }, + "type": "array" + } + }, + "required": [ + "kind" + ], + "type": "object" + }, + "ExploreSample": { + "description": "One instant sample.", + "properties": { + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "Label set of the sample. May be empty but never null.", + "type": "object" + }, + "value": { + "description": "Sample value: a number, or one of the strings `NaN`, `+Inf`, and `-Inf`. Never null." + } + }, + "required": [ + "labels", + "value" + ], + "type": "object" + }, "ExportStatusPageSubscribersRequest": { "description": "Parameters for exporting a status page subscriber list.", "properties": { @@ -16758,6 +16952,39 @@ ], "type": "object" }, + "PrometheusLabelValuesResponse": { + "description": "Native Prometheus HTTP API response returned by the queried data source. This endpoint does not wrap the payload in the Flashduty response envelope.", + "properties": { + "data": { + "description": "Label values, present when `status` is `success`.", + "items": { + "description": "One label value.", + "type": "string" + }, + "type": "array" + }, + "error": { + "description": "Human-readable Prometheus error message, present when `status` is `error`.", + "type": "string" + }, + "errorType": { + "description": "Prometheus error class, present when `status` is `error`.", + "type": "string" + }, + "status": { + "description": "Prometheus result status. `success` carries `data`; `error` carries `errorType` and `error`.", + "enum": [ + "success", + "error" + ], + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + }, "PublishedArtifactItem": { "description": "One published artifact in the gallery. Time fields are Unix timestamps in milliseconds.", "properties": { @@ -16899,6 +17126,82 @@ ], "type": "object" }, + "QueryExploreExecution": { + "description": "Time semantics of the query. The accepted companion fields depend on `kind`: `instant` takes only `to_ms` (plus optional `from_ms`), `range` requires `from_ms`, `to_ms`, and `max_data_points`, and `window` takes only `from_ms` and `to_ms`. `step_seconds` is never accepted over HTTP.", + "properties": { + "from_ms": { + "description": "Unix timestamp in milliseconds for the start of the range. Required for `range` and `window`; optional for `instant`.", + "format": "int64", + "type": "integer" + }, + "kind": { + "description": "Execution kind. `instant` evaluates at a single point in time, `range` evaluates a series over a range, and `window` returns raw rows inside a time window.", + "enum": [ + "instant", + "range", + "window" + ], + "type": "string" + }, + "max_data_points": { + "description": "Maximum number of points to return. Required for `range` and rejected for `instant` and `window`.", + "format": "int64", + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "min_step_seconds": { + "description": "Lower bound, in seconds, for the step derived from `max_data_points`. Optional and only accepted for `range`.", + "format": "int64", + "minimum": 1, + "type": "integer" + }, + "to_ms": { + "description": "Unix timestamp in milliseconds for the end of the range. Required for every execution kind.", + "format": "int64", + "type": "integer" + } + }, + "required": [ + "kind" + ], + "type": "object" + }, + "QueryExploreRequest": { + "description": "Explore query request. All four top-level fields are required and unknown fields are rejected.", + "properties": { + "args": { + "additionalProperties": { + "type": "string" + }, + "description": "Macro substitutions keyed by variable name, used for Grafana-style variables. Keys are at most 256 bytes, values at most 64 KiB, with a 128 KiB total budget.", + "maxProperties": 128, + "type": "object" + }, + "datasource_id": { + "description": "Data source ID from `/monit/datasource/list`. Must be a positive JavaScript-safe integer and belong to the authenticated account.", + "format": "int64", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "execution": { + "$ref": "#/components/schemas/QueryExploreExecution" + }, + "expr": { + "description": "Query expression in the data source's native language (PromQL, LogsQL, SQL, and so on). Non-empty UTF-8 of at most 64 KiB; some data source types enforce a lower limit.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "datasource_id", + "expr", + "args", + "execution" + ], + "type": "object" + }, "QueryField": { "description": "One typed column. `string` fields contain string or null values; `time` fields contain RFC 3339 Nano strings or null; `float` fields contain numbers, null, or the special strings `NaN`, `+Inf`, and `-Inf`.", "properties": { @@ -41885,6 +42188,96 @@ } } }, + "/monit/prometheus/api/v1/label/{label_name}/values": { + "get": { + "description": "Read label values from a Prometheus-compatible data source through the Monitors proxy.", + "operationId": "monit-prometheus-read-label-values", + "parameters": [ + { + "description": "Label name to enumerate values for, for example `job`.", + "in": "path", + "name": "label_name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Data source ID to query. Must reference a Prometheus-compatible data source owned by the authenticated account.", + "in": "header", + "name": "X-DSID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": [ + "api", + "db", + "worker" + ], + "status": "success" + }, + "schema": { + "$ref": "#/components/schemas/PrometheusLabelValuesResponse" + } + } + }, + "description": "Native Prometheus label-values response returned by the data source." + }, + "400": { + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "description": "The `X-DSID` header is missing or invalid, the data source does not exist, or it is not a Prometheus data source. Returned as `text/plain`." + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "description": "The data source lookup or the proxied request failed. Returned as `text/plain`." + }, + "503": { + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "description": "No monit-edge in the data source's cluster supports the data source resource proxy. Returned as `text/plain`; upgrade monit-edge." + } + }, + "summary": "List Prometheus label values", + "tags": [ + "Monitors/Data sources" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n| Edge requirement | Supported deployments require **monit-edge v0.35.0 or later** |\n\n## Usage\n\n- Pass the target data source in the `X-DSID` header. It must be a Prometheus-compatible data source owned by the authenticated account; use `/monit/datasource/list` to obtain its ID.\n- The 200 body is the data source's native Prometheus HTTP API payload, **not** the standard `{ request_id, data }` envelope. Failures raised before the data source is reached are returned as `text/plain` with the matching 4xx or 5xx status.\n- When `X-DSID` is omitted, the request falls back to the platform's own Prometheus proxy. Send the header to query a specific data source.", + "href": "/en/api-reference/monitors/data-sources/monit-prometheus-read-label-values", + "metadata": { + "sidebarTitle": "List Prometheus label values" + } + } + } + }, "/monit/query/data": { "post": { "description": "Run a synchronous ad-hoc query against a configured data source and return a stable `query_result.v1` result whose natural shape is frames, records, or samples. This public API requires monit-edge v0.65.0 or later.", @@ -42008,6 +42401,201 @@ } } }, + "/monit/query/explore": { + "post": { + "description": "Run an Explore query against a configured data source and return frames, samples, or logs.", + "operationId": "monit-read-query-explore", + "requestBody": { + "content": { + "application/json": { + "example": { + "args": {}, + "datasource_id": 101, + "execution": { + "from_ms": 1787187600000, + "kind": "range", + "max_data_points": 1200, + "min_step_seconds": 15, + "to_ms": 1787191200000 + }, + "expr": "rate(http_requests_total[5m])" + }, + "schema": { + "$ref": "#/components/schemas/QueryExploreRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "execution": { + "effective_step_seconds": 60, + "kind": "range" + }, + "format": "explore_result.v1", + "result": { + "frames": [ + { + "fields": [ + { + "name": "time", + "type": "time", + "values": [ + "2026-08-20T10:00:00Z", + "2026-08-20T10:01:00Z" + ] + }, + { + "labels": { + "job": "api" + }, + "name": "value", + "type": "float", + "values": [ + 1.25, + null + ] + } + ], + "kind": "time_series" + } + ], + "kind": "frames" + } + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/ExploreData" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: invalid_request." + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: access_denied." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: datasource_not_found." + }, + "413": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: source_too_large, result_too_large." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: overloaded." + }, + "499": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: canceled." + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: internal." + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: no_active_edge, edge_upgrade_required, mixed_edge_versions, edge_unavailable." + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Standard HTTP error; error.reason: timeout." + } + }, + "summary": "Run Explore query", + "tags": [ + "Monitors/Diagnostics" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **100 requests/minute**; **16 requests/second** per account |\n| Permissions | **Datasources Read** (`monit`) |\n| Edge requirement | Supported deployments require **monit-edge v0.68.0 or later** |\n\n## Usage\n\n- Use this endpoint when you need the data source's native result shape; `/monit/query/data` returns the stable `query_result.v1` contract instead. Dispatch on `data.result.kind` (`frames`, `samples`, or `logs`) here.\n- `execution.kind` decides which companion fields are accepted: `instant` needs only `to_ms`, `range` requires `from_ms`, `to_ms`, and `max_data_points`, and `window` takes `from_ms` and `to_ms`. `step_seconds` is not accepted; the step is derived from `max_data_points` and `min_step_seconds`.\n- `args` carries macro substitutions such as Grafana-style variables; every value is a string.\n- A `logs` result is capped at 1,000 entries and reports `applied_limit` plus `has_more`. Time-series and sample results are capped at 1,000 items each and the whole success response at 8 MiB.\n- Query execution may take up to 35 seconds across WebAPI forwarding and Edge execution. Configure client timeouts to at least 40 seconds.", + "href": "/en/api-reference/monitors/diagnostics/monit-read-query-explore", + "metadata": { + "sidebarTitle": "Run Explore query" + } + } + } + }, "/monit/rule/audit/detail": { "post": { "description": "Return the audit record (including the `content` field, a JSON string of the rule snapshot at that point in time).", diff --git a/api-reference/openapi.zh.json b/api-reference/openapi.zh.json index 69393af0..c798f6da 100644 --- a/api-reference/openapi.zh.json +++ b/api-reference/openapi.zh.json @@ -8899,6 +8899,200 @@ ], "type": "object" }, + "ExploreData": { + "description": "探索查询结果载荷。", + "properties": { + "execution": { + "$ref": "#/components/schemas/ExploreResponseExecution" + }, + "format": { + "description": "结果契约版本,固定为 `explore_result.v1`。", + "enum": [ + "explore_result.v1" + ], + "type": "string" + }, + "result": { + "$ref": "#/components/schemas/ExploreResult" + } + }, + "required": [ + "format", + "result" + ], + "type": "object" + }, + "ExploreField": { + "description": "Frame 的一列。取值按列组织,可以包含 null。", + "properties": { + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "该列的标签集合。仅 `time_series` 的取值字段可以携带标签,`table` 字段不允许。", + "type": "object" + }, + "name": { + "description": "列名,最长 1 MiB 的 UTF-8 字符串。", + "type": "string" + }, + "type": { + "description": "列类型。`time_series` 内不接受 `string`;`float` 存放数值,`time` 取值为 UTC RFC3339Nano 字符串。", + "enum": [ + "string", + "float", + "time" + ], + "type": "string" + }, + "values": { + "description": "按行顺序排列的列取值。", + "items": { + "description": "单个单元格。`time` 为 UTC RFC3339Nano 字符串,`float` 可以是字符串 `NaN`、`+Inf`、`-Inf`,除 `time_series` 中的时间值外均可以为 null。" + }, + "type": "array" + } + }, + "required": [ + "name", + "type", + "values" + ], + "type": "object" + }, + "ExploreFrame": { + "description": "单个列式 Frame,Frame 内所有字段的取值数量一致。", + "properties": { + "fields": { + "description": "Frame 的列。", + "items": { + "$ref": "#/components/schemas/ExploreField" + }, + "type": "array" + }, + "kind": { + "description": "Frame 形态。`table` 为无标签表格,`time_series` 恰好包含一个时间字段和一个 float 字段。", + "enum": [ + "table", + "time_series" + ], + "type": "string" + } + }, + "required": [ + "kind", + "fields" + ], + "type": "object" + }, + "ExploreLogEntry": { + "description": "单条日志。", + "properties": { + "fields": { + "additionalProperties": true, + "description": "日志字段的原始 JSON 取值。超出 JavaScript 安全整数范围的整数字面量会以十进制字符串返回。", + "type": "object" + }, + "timestamp_ns": { + "description": "条目时间,使用 Unix 纪元纳秒的规范无符号十进制字符串表示,最长 20 位。", + "type": "string" + } + }, + "required": [ + "timestamp_ns", + "fields" + ], + "type": "object" + }, + "ExploreResponseExecution": { + "description": "实际使用的执行信息,数据源返回带步长结果时出现。", + "properties": { + "effective_step_seconds": { + "description": "应用 `max_data_points` 与 `min_step_seconds` 后实际执行的步长(秒)。", + "format": "int64", + "type": "integer" + }, + "kind": { + "description": "执行类型;该对象出现时固定为 `range`。", + "enum": [ + "range" + ], + "type": "string" + } + }, + "required": [ + "kind", + "effective_step_seconds" + ], + "type": "object" + }, + "ExploreResult": { + "description": "结果主体。`frames`、`samples`、`entries` 三者中只有与 `kind` 匹配的一个会出现。", + "properties": { + "applied_limit": { + "description": "日志结果实际生效的条数上限,最大 1000。", + "type": "integer" + }, + "entries": { + "description": "日志条目列表,`kind` 为 `logs` 时出现,长度不超过 `applied_limit`。", + "items": { + "$ref": "#/components/schemas/ExploreLogEntry" + }, + "type": "array" + }, + "frames": { + "description": "列式 Frame 列表,`kind` 为 `frames` 时出现,最多 1,000 个。", + "items": { + "$ref": "#/components/schemas/ExploreFrame" + }, + "type": "array" + }, + "has_more": { + "description": "日志结果是否因 `applied_limit` 被截断。", + "type": "boolean" + }, + "kind": { + "description": "结果形态。`frames` 返回列式表格或时序,`samples` 返回带标签的瞬时值,`logs` 返回日志条目。", + "enum": [ + "frames", + "samples", + "logs" + ], + "type": "string" + }, + "samples": { + "description": "瞬时采样列表,`kind` 为 `samples` 时出现,最多 1,000 条。", + "items": { + "$ref": "#/components/schemas/ExploreSample" + }, + "type": "array" + } + }, + "required": [ + "kind" + ], + "type": "object" + }, + "ExploreSample": { + "description": "单个瞬时采样。", + "properties": { + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "采样的标签集合。可以为空,但不能为 null。", + "type": "object" + }, + "value": { + "description": "采样值:数字,或字符串 `NaN`、`+Inf`、`-Inf`。不能为 null。" + } + }, + "required": [ + "labels", + "value" + ], + "type": "object" + }, "ExportStatusPageSubscribersRequest": { "description": "导出状态页订阅者列表所需的参数。", "properties": { @@ -16758,6 +16952,39 @@ ], "type": "object" }, + "PrometheusLabelValuesResponse": { + "description": "所查询数据源返回的原生 Prometheus HTTP API 响应。本接口不会把结果包装进 Flashduty 统一响应 envelope。", + "properties": { + "data": { + "description": "标签值列表,`status` 为 `success` 时出现。", + "items": { + "description": "一个标签值。", + "type": "string" + }, + "type": "array" + }, + "error": { + "description": "Prometheus 错误信息,`status` 为 `error` 时出现。", + "type": "string" + }, + "errorType": { + "description": "Prometheus 错误类别,`status` 为 `error` 时出现。", + "type": "string" + }, + "status": { + "description": "Prometheus 结果状态。`success` 携带 `data`,`error` 携带 `errorType` 与 `error`。", + "enum": [ + "success", + "error" + ], + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + }, "PublishedArtifactItem": { "description": "产物库中的一个已发布产物。时间字段均为 Unix 毫秒时间戳。", "properties": { @@ -16899,6 +17126,82 @@ ], "type": "object" }, + "QueryExploreExecution": { + "description": "查询的时间语义。可接受的配套字段取决于 `kind`:`instant` 只需 `to_ms`(`from_ms` 可选),`range` 需要 `from_ms`、`to_ms` 和 `max_data_points`,`window` 需要 `from_ms` 和 `to_ms`。HTTP 接口不接受 `step_seconds`。", + "properties": { + "from_ms": { + "description": "范围起点的 Unix 毫秒时间戳。`range` 和 `window` 必填,`instant` 可选。", + "format": "int64", + "type": "integer" + }, + "kind": { + "description": "执行类型。`instant` 在单个时间点取值,`range` 在时间范围内取序列,`window` 返回时间窗口内的原始行。", + "enum": [ + "instant", + "range", + "window" + ], + "type": "string" + }, + "max_data_points": { + "description": "返回的数据点数量上限。`range` 必填,`instant` 与 `window` 不接受该字段。", + "format": "int64", + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "min_step_seconds": { + "description": "由 `max_data_points` 推导出的步长下限(秒)。可选,仅在 `range` 下接受。", + "format": "int64", + "minimum": 1, + "type": "integer" + }, + "to_ms": { + "description": "范围终点的 Unix 毫秒时间戳。所有执行类型均必填。", + "format": "int64", + "type": "integer" + } + }, + "required": [ + "kind" + ], + "type": "object" + }, + "QueryExploreRequest": { + "description": "探索查询请求。四个顶层字段均为必填,未知字段会被拒绝。", + "properties": { + "args": { + "additionalProperties": { + "type": "string" + }, + "description": "宏替换参数,按变量名索引,用于 Grafana 风格变量。键最长 256 字节,值最长 64 KiB,总预算 128 KiB。", + "maxProperties": 128, + "type": "object" + }, + "datasource_id": { + "description": "数据源 ID,来自 `/monit/datasource/list`。必须是正数且不超过 JavaScript 安全整数范围,且属于当前账户。", + "format": "int64", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "execution": { + "$ref": "#/components/schemas/QueryExploreExecution" + }, + "expr": { + "description": "使用数据源原生语言的查询表达式(如 PromQL、LogsQL、SQL 等)。非空 UTF-8 字符串,最长 64 KiB;部分数据源类型限制更小。", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "datasource_id", + "expr", + "args", + "execution" + ], + "type": "object" + }, "QueryField": { "description": "一个类型化列。`string` 字段包含字符串或 null;`time` 字段包含 RFC 3339 Nano 字符串或 null;`float` 字段包含数字、null 或特殊字符串 `NaN`、`+Inf`、`-Inf`。", "properties": { @@ -41885,6 +42188,96 @@ } } }, + "/monit/prometheus/api/v1/label/{label_name}/values": { + "get": { + "description": "通过监控代理从 Prometheus 兼容数据源读取标签值列表。", + "operationId": "monit-prometheus-read-label-values", + "parameters": [ + { + "description": "要枚举取值的标签名,例如 `job`。", + "in": "path", + "name": "label_name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "要查询的数据源 ID,必须是当前账户下 Prometheus 兼容类型的数据源。", + "in": "header", + "name": "X-DSID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": [ + "api", + "db", + "worker" + ], + "status": "success" + }, + "schema": { + "$ref": "#/components/schemas/PrometheusLabelValuesResponse" + } + } + }, + "description": "数据源返回的原生 Prometheus 标签值响应。" + }, + "400": { + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "description": "`X-DSID` 请求头缺失或非法、数据源不存在,或该数据源不是 Prometheus 类型。以 `text/plain` 返回。" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "description": "数据源查询或代理请求失败。以 `text/plain` 返回。" + }, + "503": { + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "description": "数据源所在集群中没有支持数据源资源代理的 monit-edge。以 `text/plain` 返回,请升级 monit-edge。" + } + }, + "summary": "查询 Prometheus 标签值列表", + "tags": [ + "Monitors/告警数据源" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 任意有效的 `app_key`(只读,不受特定权限分类限制) |\n| Edge 版本要求 | 受支持的部署要求 **monit-edge v0.35.0 或更高版本** |\n\n## 使用说明\n\n- 通过 `X-DSID` 请求头指定目标数据源,必须是当前账户下 Prometheus 兼容类型的数据源;可用 `/monit/datasource/list` 获取 ID。\n- 200 响应体是数据源原生的 Prometheus HTTP API 结构,**不是**统一的 `{ request_id, data }` envelope。未到达数据源前发生的失败以 `text/plain` 返回,并携带对应的 4xx/5xx 状态码。\n- 省略 `X-DSID` 时会回退到平台自有的 Prometheus 代理;需要查询指定数据源时必须携带该请求头。", + "href": "/zh/api-reference/monitors/data-sources/monit-prometheus-read-label-values", + "metadata": { + "sidebarTitle": "查询 Prometheus 标签值列表" + } + } + } + }, "/monit/query/data": { "post": { "description": "对已配置的数据源执行同步即席查询,并返回稳定的 `query_result.v1` 结果;结果会按自然语义呈现为 frames、records 或 samples。此公开接口要求 monit-edge v0.65.0 或更高版本。", @@ -42008,6 +42401,201 @@ } } }, + "/monit/query/explore": { + "post": { + "description": "对已配置的数据源执行探索查询,返回 frames、samples 或 logs 形态的结果。", + "operationId": "monit-read-query-explore", + "requestBody": { + "content": { + "application/json": { + "example": { + "args": {}, + "datasource_id": 101, + "execution": { + "from_ms": 1787187600000, + "kind": "range", + "max_data_points": 1200, + "min_step_seconds": 15, + "to_ms": 1787191200000 + }, + "expr": "rate(http_requests_total[5m])" + }, + "schema": { + "$ref": "#/components/schemas/QueryExploreRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "execution": { + "effective_step_seconds": 60, + "kind": "range" + }, + "format": "explore_result.v1", + "result": { + "frames": [ + { + "fields": [ + { + "name": "time", + "type": "time", + "values": [ + "2026-08-20T10:00:00Z", + "2026-08-20T10:01:00Z" + ] + }, + { + "labels": { + "job": "api" + }, + "name": "value", + "type": "float", + "values": [ + 1.25, + null + ] + } + ], + "kind": "time_series" + } + ], + "kind": "frames" + } + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/ExploreData" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "成功" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:invalid_request。" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:access_denied。" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:datasource_not_found。" + }, + "413": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:source_too_large、result_too_large。" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:overloaded。" + }, + "499": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:canceled。" + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:internal。" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:no_active_edge、edge_upgrade_required、mixed_edge_versions、edge_unavailable。" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "标准 HTTP 错误;error.reason:timeout。" + } + }, + "summary": "执行探索查询", + "tags": [ + "Monitors/诊断分析" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **100 次/分钟**;**16 次/秒** |\n| 权限要求 | **数据源查看**(`monit`) |\n| Edge 版本要求 | 受支持的部署要求 **monit-edge v0.68.0 或更高版本** |\n\n## 使用说明\n\n- 需要数据源原生结果形态时使用本接口;`/monit/query/data` 返回稳定的 `query_result.v1` 契约。本接口根据 `data.result.kind`(`frames`、`samples` 或 `logs`)分发结果。\n- `execution.kind` 决定可接受的配套字段:`instant` 只需 `to_ms`,`range` 需要 `from_ms`、`to_ms` 和 `max_data_points`,`window` 需要 `from_ms` 和 `to_ms`。不接受 `step_seconds`,步长由 `max_data_points` 与 `min_step_seconds` 推导。\n- `args` 用于宏替换(例如 Grafana 风格变量),取值均为字符串。\n- `logs` 结果最多返回 1,000 条,并通过 `applied_limit` 与 `has_more` 说明截断情况。时序与采样结果各最多 1,000 条,成功响应整体上限 8 MiB。\n- WebAPI 跨实例转发与 Edge 执行合计可能耗时 35 秒,客户端超时建议至少 40 秒。", + "href": "/zh/api-reference/monitors/diagnostics/monit-read-query-explore", + "metadata": { + "sidebarTitle": "执行探索查询" + } + } + } + }, "/monit/rule/audit/detail": { "post": { "description": "返回审计记录(包含 `content` 字段,即该时间点规则配置的 JSON 字符串快照)。", diff --git a/docs.json b/docs.json index 289a2b1e..381d9256 100644 --- a/docs.json +++ b/docs.json @@ -2498,14 +2498,16 @@ "POST /monit/datasource/delete", "POST /monit/datasource/tools/invoke", "POST /monit/datasource/sls/projects", - "POST /monit/datasource/sls/logstores" + "POST /monit/datasource/sls/logstores", + "GET /monit/prometheus/api/v1/label/{label_name}/values" ] }, { "group": "诊断分析", "icon": "stethoscope", "pages": [ - "POST /monit/query/data" + "POST /monit/query/data", + "POST /monit/query/explore" ] } ] @@ -3874,14 +3876,16 @@ "POST /monit/datasource/delete", "POST /monit/datasource/tools/invoke", "POST /monit/datasource/sls/projects", - "POST /monit/datasource/sls/logstores" + "POST /monit/datasource/sls/logstores", + "GET /monit/prometheus/api/v1/label/{label_name}/values" ] }, { "group": "Diagnostics", "icon": "stethoscope", "pages": [ - "POST /monit/query/data" + "POST /monit/query/data", + "POST /monit/query/explore" ] } ] diff --git a/en/openapi/api-catalog.mdx b/en/openapi/api-catalog.mdx index 53a0653c..37e4429c 100644 --- a/en/openapi/api-catalog.mdx +++ b/en/openapi/api-catalog.mdx @@ -3,7 +3,7 @@ title: "API Catalog" description: "Complete list of Flashduty Open API endpoints, organized by product module with links to detailed documentation" --- -Flashduty Open API provides **339** endpoints covering five major modules: On-call, Monitors, RUM, AI SRE, and Platform. All endpoints use unified authentication and request specifications. See [Quick Start](/en/openapi/introduction) for details. +Flashduty Open API provides **341** endpoints covering five major modules: On-call, Monitors, RUM, AI SRE, and Platform. All endpoints use unified authentication and request specifications. See [Quick Start](/en/openapi/introduction) for details. All endpoint URLs use `https://api.flashcat.cloud` as the base, authenticated via APP Key through query string. @@ -271,7 +271,7 @@ All endpoint URLs use `https://api.flashcat.cloud` as the base, authenticated vi - + ### Alert rules @@ -306,18 +306,24 @@ All endpoint URLs use `https://api.flashcat.cloud` as the base, authenticated vi | POST | [`/monit/datasource/tools/invoke`](/en/api-reference/monitors/data-sources/monit-datasource-tools-invoke) | Invoke datasource tool | | POST | [`/monit/datasource/sls/projects`](/en/api-reference/monitors/data-sources/monit-datasource-read-sls-projects) | List SLS projects | | POST | [`/monit/datasource/sls/logstores`](/en/api-reference/monitors/data-sources/monit-datasource-read-sls-logstores) | List SLS logstores | +| GET | [`/monit/prometheus/api/v1/label/{label_name}/values`](/en/api-reference/monitors/data-sources/monit-prometheus-read-label-values) | List Prometheus label values | ### Diagnostics | Method | Endpoint | Description | | :--- | :--- | :--- | | POST | [`/monit/query/data`](/en/api-reference/monitors/diagnostics/monit-read-query-data) | Query structured data | +| POST | [`/monit/query/explore`](/en/api-reference/monitors/diagnostics/monit-read-query-explore) | Run Explore query | ### Monitor utilities | Method | Endpoint | Description | | :--- | :--- | :--- | + + + + ### Facets | Method | Endpoint | Description | diff --git a/zh/openapi/api-catalog.mdx b/zh/openapi/api-catalog.mdx index d18894b6..412ac6af 100644 --- a/zh/openapi/api-catalog.mdx +++ b/zh/openapi/api-catalog.mdx @@ -3,7 +3,7 @@ title: "API 目录" description: "Flashduty Open API 接口完整列表,按产品模块组织并链接到详细文档" --- -Flashduty Open API 提供 **339** 个接口,覆盖 On-call、Monitors、RUM、AI SRE 和平台五个主要模块。所有接口使用统一认证方式和请求规范。详情参见[快速开始](/zh/openapi/introduction)。 +Flashduty Open API 提供 **341** 个接口,覆盖 On-call、Monitors、RUM、AI SRE 和平台五个主要模块。所有接口使用统一认证方式和请求规范。详情参见[快速开始](/zh/openapi/introduction)。 所有接口 URL 均以 `https://api.flashcat.cloud` 为 base,通过 query string 中的 APP Key 认证。 @@ -271,7 +271,7 @@ Flashduty Open API 提供 **339** 个接口,覆盖 On-call、Monitors、RUM、 - + ### 告警规则 @@ -306,18 +306,24 @@ Flashduty Open API 提供 **339** 个接口,覆盖 On-call、Monitors、RUM、 | POST | [`/monit/datasource/tools/invoke`](/zh/api-reference/monitors/data-sources/monit-datasource-tools-invoke) | 调用数据源工具 | | POST | [`/monit/datasource/sls/projects`](/zh/api-reference/monitors/data-sources/monit-datasource-read-sls-projects) | 查询 SLS 项目列表 | | POST | [`/monit/datasource/sls/logstores`](/zh/api-reference/monitors/data-sources/monit-datasource-read-sls-logstores) | 查询 SLS 日志库列表 | +| GET | [`/monit/prometheus/api/v1/label/{label_name}/values`](/zh/api-reference/monitors/data-sources/monit-prometheus-read-label-values) | 查询 Prometheus 标签值列表 | ### 诊断分析 | 方法 | 接口 | 描述 | | :--- | :--- | :--- | | POST | [`/monit/query/data`](/zh/api-reference/monitors/diagnostics/monit-read-query-data) | 查询结构化数据 | +| POST | [`/monit/query/explore`](/zh/api-reference/monitors/diagnostics/monit-read-query-explore) | 执行探索查询 | ### 通用工具 | 方法 | 接口 | 描述 | | :--- | :--- | :--- | + + + + ### RUM 自定义字段 | 方法 | 接口 | 描述 |