跳转至

OpenAPI 跨站点数据查询

本文说明如何通过 query_data 查询当前工作空间已获授权的其它站点数据,以及如何正确处理异步接口返回的 async_id

适用接口

场景 接口 说明
同步查询(推荐) POST /api/v1/df/query_data_v1 新接入优先使用
异步查询 POST /api/v1/df/asynchronous/query_data 仅在任务仍运行时回传 async_id
旧版兼容 GET/POST /api/v1/df/query_data GET 使用 body=<URL 编码后的 JSON>;新接入不推荐
查询授权目标 GET /api/v1/wksp_share/granted_ws_list 获取目标 workspaceUUIDtargetRegion
查询站点配置 GET /api/v1/workspace/website/list 仅用于查看站点注册信息,不代表已有数据授权

External API 的 POST /api/v1/df/{workspace_uuid}/query_data 是同步入口,不接受 async_id。它底层使用同一组 DQL 查询字段,但鉴权方式为 External API 的 AK/SK 签名。

请求模型与限制

跨站点查询仍然调用当前站点的 OpenAPI Endpoint,并使用当前工作空间的 DF-API-KEY。不需要直接请求目标站点,也不应使用目标站点的 Endpoint 替换当前 Endpoint。

每个 queries[i] 的结构为:

{
  "qtype": "dql",
  "query": {
    "q": "L::re(`.*`):(`message`)",
    "workspaceUUIDs": ["wksp_target"],
    "targetRegion": "region_code"
  }
}

需要遵守以下规则:

  1. 非空 workspaceUUIDs 优先于 workspaceUUID;当 workspaceUUIDs 为空数组或 null 时会回退使用 workspaceUUID。建议不要同时传两个字段。两者都不传时查询当前工作空间。
  2. 跨站点查询应在每个 query 的 query 对象内显式传入同一个 targetRegion,不要只在请求顶层传入。
  3. 一个请求中的所有 queries[*] 只能指向一个站点。多个站点必须拆成多次请求,再由客户端合并结果。
  4. workspaceUUIDs: ["*"]workspaceUUID: "*" 表示查询指定 targetRegion 内当前工作空间可查看的全部授权空间;此时 targetRegion 必传。
  5. targetRegion 是授权方工作空间所属站点的 regionCode,不是 toRegionCode
  6. 同一个请求内的多个目标工作空间必须属于同一 targetRegion。建议按站点对目标工作空间分组后再构造请求。

获取目标工作空间与 targetRegion

调用:

curl '<Endpoint>/api/v1/wksp_share/granted_ws_list?namespace=logging&pageIndex=1&pageSize=100' \
-H 'DF-API-KEY: <DF-API-KEY>' \
--compressed

namespace 可按数据类型过滤授权,例如:

  • 日志:logging
  • 链路:tracing
  • 指标:metric
  • 用户访问监测:rum
  • 可用性监测:dialtest

响应按授权方站点分组:

{
  "code": 200,
  "content": [
    {
      "regionCode": "region_a",
      "regionName": "站点 A",
      "data": [
        {
          "workspaceUUID": "wksp_target_a",
          "workspaceName": "目标工作空间 A",
          "regionCode": "region_a",
          "toWorkspaceUUID": "wksp_current",
          "toRegionCode": "region_current",
          "type": ["logging"],
          "indexes": ["*"]
        }
      ],
      "pageInfo": {
        "pageIndex": 1,
        "pageSize": 100,
        "totalCount": 1
      }
    }
  ],
  "success": true
}

组织参数时:

  • data[*].workspaceUUID 作为 query.workspaceUUIDquery.workspaceUUIDs 的值。
  • 用该工作空间所在分组的 content[*].regionCode(或同一数据项的 regionCode)作为 query.targetRegion
  • 不要使用 toWorkspaceUUID 作为查询目标;它通常是当前 API Key 所属的被授权方工作空间。
  • 不要使用 toRegionCode 作为 targetRegion;它通常是当前站点。
  • granted_ws_list 对每个站点分组独立分页,pageInfo.count 只是当前页数量,不能直接用它和 totalCount 比较后无限递增页码。
  • 首次可不传 regionCode,用 pageIndex=1&pageSize=100 发现授权方站点;随后为每个需要查询的站点显式传入该 regionCode,并分别从第 1 页开始翻页。
  • 某站点累计取得的唯一授权数达到该组 pageInfo.totalCount,或 pageIndex * pageSize >= totalCount 时停止。合并页数据时按授权记录 uuid 去重,并用 (regionCode, workspaceUUID) 校验目标映射;同一映射出现冲突授权时不要自行扩大权限范围。

例如只翻取 region_a 的第 2 页:

curl '<Endpoint>/api/v1/wksp_share/granted_ws_list?namespace=logging&regionCode=region_a&pageIndex=2&pageSize=100' \
-H 'DF-API-KEY: <DF-API-KEY>' \
--compressed

GET /api/v1/workspace/website/list 返回的 content[*].regionCode 只能作为站点编码候选。某站点出现在站点列表中,不表示当前工作空间已经获得该站点的数据授权;最终必须以 granted_ws_list 的结果为准。

同步跨站点查询

以下示例查询 region_a 站点的 wksp_target_a

curl '<Endpoint>/api/v1/df/query_data_v1' \
-H 'Content-Type: application/json' \
-H 'DF-API-KEY: <DF-API-KEY>' \
--data-raw '{
  "queries": [
    {
      "qtype": "dql",
      "query": {
        "q": "L::re(`.*`):(`message`)",
        "timeRange": [1772516130000, 1772519730000],
        "limit": 100,
        "workspaceUUIDs": ["wksp_target_a"],
        "targetRegion": "region_a"
      }
    }
  ]
}' \
--compressed

查询某个站点内全部已授权工作空间:

{
  "queries": [
    {
      "qtype": "dql",
      "query": {
        "q": "L::re(`.*`):(`message`)",
        "timeRange": [1772516130000, 1772519730000],
        "limit": 100,
        "workspaceUUIDs": ["*"],
        "targetRegion": "region_a"
      }
    }
  ]
}

如果需要同时查询 region_aregion_b,应分别发起两次请求:

目标列表
  ├─ region_a: [wksp_a1, wksp_a2] -> 请求 1
  └─ region_b: [wksp_b1]          -> 请求 2
                                 客户端合并结果

不要在同一个 queries 数组中混用不同 targetRegion,否则接口会返回 ft.UnsupportMultiSiteQuery

异步查询与 async_id 生命周期

async_id 是单次查询任务的句柄,不是会话 ID、固定客户端 ID 或分页游标。新查询绝不能携带历史 async_id

1. 首次提交:省略 async_id

curl '<Endpoint>/api/v1/df/asynchronous/query_data' \
-H 'Content-Type: application/json' \
-H 'DF-API-KEY: <DF-API-KEY>' \
--data-raw '{
  "queries": [
    {
      "qtype": "dql",
      "query": {
        "q": "L::re(`.*`):(`message`)",
        "timeRange": [1772516130000, 1772519730000],
        "limit": 100,
        "workspaceUUIDs": ["wksp_target_a"],
        "targetRegion": "region_a"
      }
    }
  ]
}' \
--compressed

若任务仍在运行,响应示例:

{
  "code": 200,
  "content": {
    "data": [
      {
        "async_id": "async_task_001",
        "is_running": true
      }
    ]
  },
  "success": true,
  "traceId": "TRACE-XXXX"
}

2. 轮询:只回传仍在运行的任务 ID

仅当同一结果项同时满足以下条件时才轮询:

content.data[i].is_running === true
content.data[i].async_id 非空

把 ID 放回同一数组下标的 queries[i].async_id,并保持 qtypequery.q、时间范围、目标工作空间和 targetRegion 不变:

{
  "queries": [
    {
      "async_id": "async_task_001",
      "qtype": "dql",
      "query": {
        "q": "L::re(`.*`):(`message`)",
        "timeRange": [1772516130000, 1772519730000],
        "limit": 100,
        "workspaceUUIDs": ["wksp_target_a"],
        "targetRegion": "region_a"
      }
    }
  ]
}

建议使用递增退避并设置总超时,例如先等待 1 秒,再逐步增加到 2 秒、4 秒;不要无间隔连续请求。

3. 结束:停止携带 async_id

content.data[i].is_runningfalse 时,该任务已经结束。调用方应读取最终数据并立即停止轮询;无论响应对象里是否仍出现 async_id 字段,下一次新查询都必须省略旧 ID。

以下行为是错误的:

  • 将上一次任务的 async_id 固定写入所有后续请求。
  • 修改 DQL、时间范围、工作空间或 targetRegion 后继续复用旧 ID。
  • content.data[0].async_id 填入 queries[1]
  • async_id 代替 search_aftercursor_timecursor_token 翻页。

若出现 is_running=trueasync_id 为空,不要回填本地保存的历史 ID。应记录响应 traceId,按有限重试策略重新发起该逻辑查询;持续出现时联系技术支持。

批量异步查询中,content.data[i]queries[i] 按数组下标对应。为了降低 ID 与查询项错配的风险,建议异步调用每次只提交一个 query。

分页与异步任务的区别

异步任务完成后,分页仍使用最终查询结果返回的分页字段:

场景 下一次请求参数
日志深度分页 将响应 search_after 传入下一次查询的 query.search_after
分段时间查询 首次将 query.cursor_time 设为结束时间,后续传响应 next_cursor_time
同时间戳安全翻页 将响应 next_cursor_token 传入下一次查询的 query.cursor_token

翻页属于新的查询请求,不应继续携带已完成任务的 async_id。如果翻页请求再次转为异步任务,仍从“省略 async_id”开始新的生命周期。

客户端合并建议

服务端不支持在一次 query_data 请求中跨多个站点查询。客户端合并时建议:

  1. 先按 targetRegion 分组目标工作空间。
  2. 每个站点独立请求、独立分页、独立处理异步任务。
  3. 为每批结果补充客户端元数据,例如 sourceRegionqueriedWorkspaceUUIDs。多工作空间查询不会保证每条记录都带可靠的来源工作空间,因此不能把整批结果标成某一个 sourceWorkspaceUUID;只有每次只查询一个工作空间时才可这样标记。需要记录级来源时,应逐工作空间查询,或让 DQL 返回经业务确认可靠的来源维度。
  4. 日志类结果按 timedate_ns 及稳定唯一标识排序并去重;指标结果应先确认时间粒度、聚合函数和标签集合一致再合并。
  5. 任一站点失败时保留其它站点成功结果,并返回分站点错误明细,不要把部分成功包装成全部成功。

常见错误

错误码 / 现象 原因 处理方式
ft.UnsupportMultiSiteQuery 一个请求混入多个目标站点 targetRegion 拆分请求
ft.workspaceUnauthorized 目标工作空间未授权给当前工作空间 重新查询 granted_ws_list,确认授权状态和 UUID
ft.NotFoundWorkspaceAuthorizationCfg 目标站点没有可用授权配置,常见于使用 * 但站点无授权 检查 targetRegion,并确认目标站点存在有效授权
ft.NoInitOtherNodeCfg 跨外部组织站点授权存在,但目标站点 Front Endpoint / 节点配置缺失 不要盲目重试;联系站点管理员检查并补齐目标节点配置
ft.InvalidWorkspace 当前站点目标工作空间无效或已停用 刷新工作空间列表并确认状态
一直轮询旧结果 客户端长期复用已完成任务的 async_id is_running=false 后删除本地 ID;新查询不传 async_id
站点存在但查不到数据 只检查了 workspace/website/list,未确认授权 wksp_share/granted_ws_list 为准
DQLDataAccessScopeRestricted warning 数据访问规则只允许部分索引或不允许相关索引 检查 warnings[].details[].metadata.restriction 和数据访问规则

上线前检查清单

  • 使用当前工作空间的 DF-API-KEY 请求当前站点 OpenAPI Endpoint。
  • granted_ws_list 获取目标 workspaceUUID 与同组 regionCode
  • 每个跨站点 query 都显式传入同一个 targetRegion
  • 多站点目标已按 targetRegion 拆分为多次请求。
  • 新异步查询不传 async_id
  • 仅在 is_running=true 且 ID 非空时轮询,并按数组下标绑定任务。
  • is_running=false 后删除任务 ID;分页从新的异步生命周期开始。
  • 设置轮询退避、总超时、分页上限和分站点错误处理。
  • 合并结果时保留来源站点/工作空间并按业务主键去重。

文档评价

文档内容是否对您有帮助?