ops-consul-assets

SKILL.md

Consul 资产管理(监控上线 / 下线)

环境配置

后端地址: https://idsaas-o.api.leiniao.com/ops-infra-proxy 认证方式: X-User-Api-Key: TCL_SKILL_USER_KEY密钥,可以通过以下方式获取:1.Windows 读取 %USERPROFILE%\.env\skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.cmd 脚本获取密钥; 2.Linux/macOS 读取 ~/.env/skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.sh 脚本获取密钥。如果用户没配置密钥,请提示他到https://platform-eaglelab.tcl.com/skill-page/manage/keys复制命令配置密钥 代理路由前缀: /consul-assets 审批机制: POST(添加监控)和 DELETE(下线监控)均走飞书审批,返回 HTTP 202 + approval_idGET(查询)直接透传,无需审批。


接口总览

操作 接口 方法 审批
添加监控(批量) /consul-assets/apis/v1/assets/add POST
查询 IP 上的监控服务 /consul-assets/apis/v1/catalog/by-ip GET
下线监控(批量) /consul-assets/apis/v1/assets/del DELETE

核心流程

添加监控流程

用户提供 IP + module + instance:port
第一步:调用 tcloud-unify 的 search-ip 获取资源摘要
(cloud_uid、resource_id / instance_id)
第二步:调用 tcloud-unify 的 host 查询完整主机详情
(cloudType、cloudName、regionId、tags 等)
从 tags 中自动提取 projname、env、app、app_id、type 等
用户确认或补充缺失字段(ou、projname_cn 等)
组装请求体,调用 POST /consul-assets/apis/v1/assets/add
返回 202 + approval_id,等待飞书审批

下线监控流程

用户提供 IP(+ 可选 module 过滤)
调用 GET /consul-assets/apis/v1/catalog/by-ip 查询该 IP 上所有监控服务
展示服务列表,用户确认要下线的 ServiceID
(全部下线 or 只下线某个 module)
组装请求体,调用 DELETE /consul-assets/apis/v1/assets/del
返回 202 + approval_id,等待飞书审批

必须收集的信息

添加监控时必须由用户提供

信息 说明 示例
IP 地址 目标主机 IP 172.16.x.x
module 监控模块类型 redisnodenginxkafka
instance 抓取端口,格式 ip:port 172.16.x.x:9363
metrics_path 仅服务组 module 必填,指标抓取接口路径 /metrics

instance 和 metrics_path 是必须由用户明确提供的,不能猜测端口号或路径。即使有常见端口参考,也必须和用户确认。

⚠️ CMDB 自动扫描 module — 不建议手动添加

以下 4 个 module 由 CMDB 自动扫描注册,不建议通过本接口手动添加

module 说明
nginx CMDB 自动扫描
mysql CMDB 自动扫描
redis CMDB 自动扫描
mongo CMDB 自动扫描

当用户要求手动添加以上 4 个 module 的监控时,必须先提醒用户

"这个中间件(nginx/mysql/redis/mongo)通常由 CMDB 自动扫描注册,不建议手动添加。如果 CMDB 没有自动扫描到,建议先排查 CMDB 扫描问题。确定要手动添加吗?"

只有用户明确确认后才继续执行。

通过 tcloud-unify 自动获取

以下字段通过调用 tcloud-unify skill 的 search-ip + host 两步查询自动填充:

字段 来源 说明
cloud host 查询 cloudType 映射 云厂商标识:AWSqcloudaliyun
cloud_name host 查询 cloudName 云账号全称
region host 查询 regionId 云区域
uid host 查询 cloudUid 云账号 ID
projname host 查询 tags.projname 项目英文名,tags 中无则需用户提供
projname_cn 用户提供 项目中文名,tags 中通常无此字段
env host 查询 tags.env 运行环境
app host 查询 tags.app 应用分类
app_id host 查询 tags.appid 应用标识
type host 查询 tags.type 部署类型

需要用户补充或确认的字段

字段 说明 常见值
ou 组织单元 / 业务归属 按实际业务线填写
env 运行环境 onlinestaging
app_id 应用标识 redis-clusternginxkafka-broker
app 应用分类 cachemqwebinfradbother
type 部署类型 devicestandalone
mid 中间件标识(通常与 module 一致,node/process 为空) rediskafka""

module 类型与路由

module 是开放字段,不限于固定枚举。代理内部根据 module 值决定走哪条上游路径:

路由规则

路由 module 范围 额外必填字段 说明
单实例注册 nodeprocessmysqlmongoredisnginx 一条记录 = 一个 Consul 服务
服务组注册 以上 6 个之外的所有值 metrics_path + instance(抓取端口) 代理自动将扁平格式转为服务组形态

关键区别:走服务组注册的 module,metas 中必须包含 metrics_path(如 /metrics)和 instance(抓取端口,如 172.16.x.x:9363),缺少任一字段都无法注册成功。

常见 module 参考

分类 module 路由 典型 instance 端口
基础设施 nodeprocess 单实例 :9100:29256
关系型数据库 mysqlpostgres mysql→单实例;postgres→服务组 :9104:5432
NoSQL mongoredismemcached mongo/redis→单实例;memcached→服务组 :9216:6379:11211
消息队列 kafkarocketmqrabbitmqemqx 服务组 :9092:9876:15692:18083
注册/配置中心 nacosconsuletcdzookeeper 服务组 :8848:8500:2379:2181
Web/网关 nginxkong nginx→单实例;kong→服务组 :80:8001
搜索引擎 elasticsearch 服务组 :9200
Java 应用 jmxjvmjava 服务组 :9999:8080
推送网关 pushgateway 服务组 :9091

端口仅供参考,必须由用户明确提供 instance:port,不可自行假设。

常见 metrics_path 参考

服务组 module 必须提供 metrics_path。大部分 exporter 默认路径是 /metrics,但部分中间件有特殊路径。如果用户不确定,展示下表供参考:

module metrics_path 说明
大部分默认 /metrics kafka、rabbitmq、zookeeper、etcd、consul、memcached、kong、elasticsearch、clickhouse、pushgateway、jmx、jvm、postgres、flink、hbase、activemq、rocketmq 等
nacos /nacos/actuator/prometheus Nacos 内置 Prometheus 端点
emqx /metrics EMQX 非5.0 版本
emqx(5.0+) /api/v5/prometheus/stats EMQX 5.0 及以上版本
Java 应用(Spring Boot) /actuator/prometheus 需引入 micrometer-registry-prometheus
自定义 exporter 按实际配置 用户自行确认

交互规则:当用户提供了服务组 module 但未提供 metrics_path 时:

  1. 先展示上表中该 module 对应的常见路径作为参考
  2. 询问用户确认或提供实际路径
  3. 如果表中没有对应 module,提示默认通常是 /metrics,让用户确认
  4. 不可自行填入默认值直接提交,必须经用户确认

API 详细说明

1. 添加监控(批量,推荐)

接口: POST /consul-assets/apis/v1/assets/add

统一使用批量格式,即使只有一条也放在 items 里。同一批 items 可混合不同 module 类型。

请求体结构(单实例 module — node/process/mysql/mongo/redis/nginx):

{
  "batch": true,
  "items": [
    {
      "module": "<module类型>",
      "uid": "<云账号ID>",
      "metas": {
        "ou": "<组织单元>",
        "cloud": "<云厂商>",
        "cloud_name": "<云账号全称>",
        "region": "<区域>",
        "mid": "<中间件标识>",
        "env": "<环境>",
        "instance": "<ip:port>",
        "projname": "<项目英文名>",
        "projname_cn": "<项目中文名>",
        "app_id": "<应用标识>",
        "app": "<应用分类>",
        "type": "<部署类型>"
      },
      "tags": ["<module>", "<cloud_name>"]
    }
  ]
}

请求体结构(服务组 module — 除上述 6 个之外的所有 module):

服务组 module 必须额外提供 metrics_pathinstance(抓取端口),否则注册失败。

{
  "batch": true,
  "items": [
    {
      "module": "<module类型>",
      "uid": "<云账号ID>",
      "metas": {
        "ou": "<组织单元>",
        "cloud": "<云厂商>",
        "cloud_name": "<云账号全称>",
        "region": "<区域>",
        "mid": "<中间件标识>",
        "env": "<环境>",
        "instance": "<ip:port(抓取端口)>",
        "metrics_path": "/metrics",
        "projname": "<项目英文名>",
        "projname_cn": "<项目中文名>",
        "app_id": "<应用标识>",
        "app": "<应用分类>",
        "type": "<部署类型>"
      },
      "tags": ["<module>", "<cloud_name>"]
    }
  ]
}

tags 规范: 固定两个元素 — [module, cloud_name]

curl 示例:

curl -s -X POST "https://idsaas-o.api.leiniao.com/ops-infra-proxy/consul-assets/apis/v1/assets/add" \
  -H "X-User-Api-Key: TCL_SKILL_USER_KEY密钥,可以通过以下方式获取:1.Windows 读取 %USERPROFILE%\.env\skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.cmd 脚本获取密钥; 2.Linux/macOS 读取 ~/.env/skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.sh 脚本获取密钥。如果用户没配置密钥,请提示他到https://platform-eaglelab.tcl.com/skill-page/manage/keys复制命令配置密钥" \
  -H "Content-Type: application/json" \
  -d '{"batch":true,"items":[{"module":"redis","uid":"<云账号ID>","metas":{"ou":"<组织单元>","cloud":"AWS","cloud_name":"<云账号全称>","region":"ap-south-1","mid":"redis","env":"online","instance":"172.16.x.x:6379","projname":"<项目英文名>","projname_cn":"<项目中文名>","app_id":"redis-cluster","app":"cache","type":"device"},"tags":["redis","<云账号全称>"]}]}'

受理响应 (HTTP 202):

{
  "approval_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "message": "已提交审批,请在飞书中确认"
}

2. 查询 IP 上的监控服务

接口: GET /consul-assets/apis/v1/catalog/by-ip

参数: ip — 目标 IP 地址

curl 示例:

curl -s -G "https://idsaas-o.api.leiniao.com/ops-infra-proxy/consul-assets/apis/v1/catalog/by-ip" \
  -H "X-User-Api-Key: TCL_SKILL_USER_KEY密钥,可以通过以下方式获取:1.Windows 读取 %USERPROFILE%\.env\skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.cmd 脚本获取密钥; 2.Linux/macOS 读取 ~/.env/skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.sh 脚本获取密钥。如果用户没配置密钥,请提示他到https://platform-eaglelab.tcl.com/skill-page/manage/keys复制命令配置密钥" \
  --data-urlencode "ip=10.0.0.1"

响应关键字段:

字段 说明 用途
ServiceID 服务唯一 ID,格式 {cloud}_{host}:{port} 下线时必须使用此值
ServiceName 服务名,格式 {module}_exporter_{uid} 识别 exporter 类型
ServiceAddress 服务地址 ip:port 确认实例
ServiceMeta 注册时写入的元数据 确认业务归属

3. 下线监控(批量,推荐)

接口: DELETE /consul-assets/apis/v1/assets/del

操作步骤:

  1. 先通过 GET /consul-assets/apis/v1/catalog/by-ip 查询目标 IP,获取 ServiceID
  2. 将需要下线的 ServiceID 组装为批量请求

请求体结构:

{
  "batch": true,
  "items": [
    { "id": "<ServiceID>", "module": "<module类型>" }
  ]
}

curl 示例:

curl -s -X DELETE "https://idsaas-o.api.leiniao.com/ops-infra-proxy/consul-assets/apis/v1/assets/del" \
  -H "X-User-Api-Key: TCL_SKILL_USER_KEY密钥,可以通过以下方式获取:1.Windows 读取 %USERPROFILE%\.env\skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.cmd 脚本获取密钥; 2.Linux/macOS 读取 ~/.env/skill-hub-user-key 文件 或 执行 scripts/tcl-skills-hub-api-key.sh 脚本获取密钥。如果用户没配置密钥,请提示他到https://platform-eaglelab.tcl.com/skill-page/manage/keys复制命令配置密钥" \
  -H "Content-Type: application/json" \
  -d '{"batch":true,"items":[{"id":"qcloud_10.0.0.1:80","module":"nginx"},{"id":"qcloud_10.0.0.2:80","module":"nginx"}]}'

与 tcloud-unify 联动

添加监控时,用户通常只提供 IP + module + instance:port,其余云资源信息需要通过 tcloud-unify 获取。

重要search-ip 只返回资源摘要(不含 tags),必须再调一次 host 查询才能拿到完整主机详情(含 tags 标签信息)。

联动步骤

  1. 第一步:调用 search-ip 获取资源摘要:
node scripts/query.js search-ip --ip=<目标IP>

从返回结果中提取:

  • cloud_uid — 云账号 ID
  • resource_id — 实例 ID
  1. 第二步:调用 host 查询完整主机详情(含 tags):
node scripts/query.js host --cloudUid=<cloud_uid> --keyword=<resource_id>

此接口返回完整主机信息,包括 tagscloudTypecloudNameregionId 等。

  1. 从返回结果中提取字段映射:
tcloud 返回字段 映射到 metas 字段 说明
cloudType cloud 需映射:tencentqcloudaliyunaliyunawsAWSksyunksyun
cloudName cloud_name 直接使用
regionId region 直接使用
cloudUid uid(请求体顶层) 直接使用
tags.projname projname 项目英文名,如有则使用,否则需用户提供
tags.env env 运行环境,如 onlinestaging
tags.app app 应用分类,如 cacheother
tags.appid app_id 应用标识
tags.type type 部署类型,如 standalonedevice

tags 中的字段可直接用于填充 metas,减少向用户确认的次数。如果 tags 中缺少某个字段,再向用户询问。

  1. cloud_type 映射表:
tcloud cloud_type metas.cloud 说明
tencent qcloud 腾讯云
aliyun aliyun 阿里云
aws AWS AWS
ksyun ksyun 金山云
volcengine volcengine 火山引擎
gcp gcp 谷歌云
azure azure Azure

如果 tcloud search-ip 查不到该 IP,提示用户手动提供 cloud、cloud_name、region、uid 等信息。


执行规范

添加监控时必须遵守

  1. 必须收集 instance:port — 这是用户必须明确提供的,不能根据 module 猜测端口
  2. 服务组 module 必须收集 metrics_path — 非 node/process/mysql/mongo/redis/nginx 的 module,必须让用户提供 metrics_path(通常是 /metrics)和抓取端口 instance,缺一不可,否则拒绝提交
  3. CMDB 自动扫描 module 先劝阻 — 用户要手动添加 nginxmysqlredismongo 时,必须先提醒不建议手动添加(CMDB 会自动扫描),用户明确确认后才继续
  4. 必须调用 tcloud 获取云信息 — 先 search-ip 拿摘要,再 host 拿完整详情(含 tags),不要让用户手动填写 cloud、cloud_name、region、uid(除非 tcloud 查不到)。tags 中有的字段直接使用,缺失的再向用户确认
  5. 统一使用批量格式 — 即使只有一条,也用 {"batch": true, "items": [...]}
  6. tags 固定格式[module, cloud_name],不要遗漏或多加
  7. mid 字段规则 — 通常与 module 一致;nodeprocess 的 mid 为空字符串 ""
  8. 提交前展示完整请求体 — 让用户确认所有字段后再提交

下线监控时必须遵守

  1. 必须先查询 — 下线前必须先调用 GET /consul-assets/apis/v1/catalog/by-ip 获取 ServiceID
  2. 展示服务列表 — 查询结果展示给用户,让用户确认要下线哪些
  3. 全部下线 vs 部分下线 — 用户说"下线全部监控"则取所有 ServiceID;说"下线 redis 监控"则只取对应的
  4. ServiceID 不可猜测 — 必须来自查询接口返回

批量操作限制

  • 单批最多 200 条
  • 超过 200 条需分批提交,每批独立审批

审批说明

  • POST 和 DELETE 操作返回 HTTP 202 表示审批已受理
  • 告知用户去飞书确认审批
  • 审批通过后代理自动执行上游操作

错误处理

HTTP 状态码

状态码 说明 处理方式
202 审批已受理 正常,告知用户等待飞书审批
400 请求体校验失败 检查 batch/items 格式、条数、字段完整性
401 API Key 无效 检查 API Key
500 后端未配置 联系运维
502 上游不可达 检查后端服务状态

业务错误码(HTTP 200)

code 说明
20000 成功
40000 失败,具体原因见 message

常见场景

场景 1:用户说"给 172.16.x.x 加一下 redis 监控,instance 是 172.16.x.x:6379"

  1. 先劝阻 — 提醒用户 redis 由 CMDB 自动扫描,不建议手动添加
  2. 用户确认要继续 → 调用 tcloud search-ip 获取资源摘要,再调 host 获取完整详情(含 tags)
  3. 从 tags 中提取 env、app、app_id、type、projname 等,向用户确认缺失字段(ou、projname_cn 等)
  4. 组装批量请求体,展示给用户确认
  5. 提交 POST 请求
  6. 返回 approval_id,提示用户去飞书审批

场景 2:用户说"给 172.16.x.x 加一下 kafka 监控,instance 是 172.16.x.x:9363,metrics_path 是 /metrics"

  1. kafka 是服务组 module,确认用户已提供 instance 和 metrics_path ✓
  2. 调用 tcloud search-ip 获取资源摘要,再调 host 获取完整详情(含 tags)
  3. 从 tags 中提取 env、app、app_id、type、projname 等,向用户确认缺失字段(ou、projname_cn 等)
  4. 组装请求体(metas 中包含 metrics_pathinstance),展示确认
  5. 提交 POST 请求
  6. 返回 approval_id

场景 3:用户说"给 172.16.x.x 加一下 kafka 监控"(缺少 instance 和 metrics_path)

  1. kafka 是服务组 module,检测到缺少必填字段
  2. 向用户索要 instance(抓取端口,如 172.16.x.x:9363
  3. 向用户索要 metrics_path — 展示参考:"kafka 的 metrics_path 通常是 /metrics,请确认或提供实际路径"
  4. 收集齐全后才继续后续流程

场景 4:用户说"把 10.0.0.1 上的 nginx 监控下线"

  1. 调用 GET by-ip 查询该 IP 上所有服务
  2. 从结果中筛选 nginx 相关的 ServiceID
  3. 展示给用户确认
  4. 提交 DELETE 请求
  5. 返回 approval_id

场景 5:用户说"把 10.0.0.1 上的监控全部下线"

  1. 调用 GET by-ip 查询该 IP 上所有服务
  2. 展示全部服务列表
  3. 用户确认后,取所有 ServiceID 组装批量删除请求
  4. 提交 DELETE 请求

场景 6:批量给多台机器加 node 监控

  1. 对每个 IP 调用 tcloud search-ip + host 获取完整云信息和 tags
  2. 收集所有机器的云信息
  3. 用户提供每台机器的 instance:port(node 通常是 ip:9100,但仍需确认)
  4. 组装批量请求,展示确认
  5. 提交

高级说明

register_route(排障用)

注册请求中可选传 register_route 字段,强制指定上游路由:

效果
auto(默认) 由 module 自动决定
add / singleton 强制走单实例注册
group / group_add 强制走服务组注册

ServiceID 格式

上游根据 module 和 instance 解析出 host:port,生成:

  • ServiceID: {cloud}_{host}:{port}(如 qcloud_10.0.0.1:80
  • ServiceName: {module}_exporter_{uid}(如 nginx_exporter_<云账号ID>
Installs
1
First Seen
2 days ago