阿里云 SLS 查询与分析
场景说明
当用户想要:
- 解释、重写、优化或执行已有查询
- 将自然语言需求转换为 SLS 索引查询、SQL 或 SPL 语句
时使用本 Skill。
前置条件
安装 Aliyun CLI
运行 aliyun version 确认版本 >= 3.3.8。若未安装或版本过低,请按文档 references/cli-installation-guide.md 安装或更新。
更新插件
aliyun plugin update
检查阿里云凭证已配置
运行 aliyun configure list 检查凭证是否已配置。
若未显示有效 profile,停止并请用户在本会话之外运行 aliyun configure。
安全规则:
- 绝不读取、回显或打印 AK/SK 值
- 绝不要求用户将 AK/SK 粘贴到对话中
- 只使用
aliyun configure list检查凭证状态
RAM 权限要求
| API | CLI | Action | 用途 |
|---|---|---|---|
| GetLogsV2 | get-logs-v2 | log:GetLogStoreLogs | 运行查询 / SQL / SPL 并读取结果 |
| GetIndex | get-index | log:GetIndex | 读取索引配置以验证前置条件 |
最小及完整 RAM 策略 JSON 见 references/ram-policies.md。
权限失败处理: 如果调用返回 Unauthorized 权限错误,停止并向用户展示 references/ram-policies.md。未经用户明确确认,不要换另一个账号重试。
可观测性(每条 aliyun api 命令都必须遵守)
加载本 Skill 时,为整个会话生成一次随机 session ID(32 字符小写十六进制字符串)。在下方用作 {session-id}。
规则: 每条调用云 API 的 aliyun CLI 命令必须包含 --user-agent 标志。本地工具命令(如 configure、plugin、version)不支持该标志,应排除。
--user-agent "AlibabaCloud-Agent-Skills/alibabacloud-sls-query/{session-id}"
示例(假设 session-id 为 a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6):
aliyun sls get-logs-v2 --project my-project --logstore my-logstore \
--from 1740000000 --to 1740003600 --query '*' \
--user-agent "AlibabaCloud-Agent-Skills/alibabacloud-sls-query/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
在任何 aliyun API 命令调用上,都不要跳过、改变格式或省略 --user-agent。
核心工作流
- 读取索引配置(GetIndex)
- 选择查询模式
- 构建语句
- 解析时间范围
- 执行查询
- 从响应中提取数据
- 呈现 CLI 命令和结果
步骤 1:读取索引配置(强制)
始终先调用 get-index —— 索引配置决定步骤 2 中哪些查询模式可用。
aliyun sls get-index \
--project <project> --logstore <logstore>
响应中有两个部分驱动后续所有决策:
| 部分 | 含义 |
|---|---|
line | 全文索引 —— 缺失表示全文搜索已禁用 |
keys | 字段索引 —— 字段 → { type, doc_value, token, caseSensitive, chn, ... } 的映射。doc_value: true 表示该字段已启用统计 |
如果调用返回 IndexConfigNotExist(HTTP 404),或响应中 line 和 keys 均未填充,则该 Logstore 完全没有索引 —— 立即停止并告知用户必须先创建索引,才能运行任何查询 / SQL / SPL。
- 响应可能很大 —— 只提取与当前查询相关的字段。按
logstore缓存并在会话内复用。
字段类型、分词,以及 get-index 如何映射到能力,见 references/related-apis.md 和 references/query-analysis.md。
步骤 2:选择查询模式(关键)
查询语句采用以下形式之一:
| 优先级 | 模式 | 语句形式 | 使用时机 | 要求 | |
|---|---|---|---|---|---|
| 1 | 索引搜索 | <index-search> | 过滤原始日志;按时间顺序和分页返回日志 | 全文(line)或任一字段索引(keys.<field>) | |
| 2 | SQL | `<index-search> \ | <SQL>` | 聚合、GROUP BY、排序、窗口、top-N、投影等分析操作 | 目标字段有 keys.<field> 且 doc_value: true |
| 3 | SQL 扫描 | `<index-search> \ | <SQL scan>` | 用户要求 | 无 |
| 4 | SPL | `<index-search> \ | <SPL>` | 用户要求 | 无 |
选择规则:
- 为最快速度,始终优先索引搜索。
- 当用户需要分析操作或字段投影而非获取全部原始日志时(如聚合、
GROUP BY、排序、窗口分析、top-N,或只返回所需字段 / 列),使用索引搜索 + SQL。 - 不要主动选择 SQL 扫描或 SPL;仅在用户明确要求时使用。
完整决策指南见 references/query-analysis.md。
步骤 3:编写语句
#### 3.1 先构建索引搜索段(| 左侧)
收集所有可用索引搜索语法表达的过滤条件,放在第一个 | 之前。若无过滤条件则用 *。
* and "payment failed" and status: "500" and not path: "/healthz"
*匹配全部;"..."是全文(需要全文索引)。key: "value"是字段过滤(需要字段索引)。- 用
and/or/not组合;用括号分组。 key: *表示字段存在。范围(>、>=、[a, b])仅对long/double有效。
如果无需聚合或行级处理即可完整回答需求,到此为止 —— 这已是一个完整的索引搜索。完整索引搜索语法见 references/query-analysis.md。
#### 3.2 追加 SQL —— 用于聚合 / 分析
status: 500 | SELECT date_trunc('minute', __time__) AS minute,
count(*) AS errors
FROM log
GROUP BY minute
ORDER BY minute
- 阅读 references/query-analysis.md 了解查询与 SQL 规则
- 表名为
log(建议省略)。 - SQL 遵循
get-index中的索引字段类型 ——long/double字段可直接比较(status >= 500)。仅当字段索引为text但需要数值语义时才转换(用try_cast抑制错误)。 - 特殊函数选择(聚合、JSON、正则、日期时间、IP 地理位置…)见 references/functions-guide.md
#### 3.3 追加 SPL —— 用于行级处理 / 灵活过滤
status: 500 and service: payment
| where try_cast(latency as BIGINT) > 1000
| extend latency_ms = try_cast(latency as BIGINT)
| project service, latency_ms, message
SPL 语法、管道命令和字段处理规则,请阅读 references/spl-guide.md。
#### 3.4 追加 SQL 扫描 —— 目标字段无索引 / 统计时的兜底
语法遵循常规 SQL(见 3.2),有一点不同:每个字段都是 varchar,因此数值比较或运算前始终先 cast() / try_cast()。扫描语义见 references/query-analysis.md。
* | set session mode=scan; SELECT api, count(1) AS pv FROM log GROUP BY api
步骤 4:解析时间范围
在构建 CLI 命令之前,将 --from / --to 生成为 Unix 秒级时间戳。--from 为闭区间,--to 为开区间。
从三种输入模式中选择一种:
- 相对时间 —— 用户说"最近 / 过去 N 分钟 | 小时 | 天"。
- 无时区的自然语言绝对时间 —— 归一化为
YYYY-MM-DD HH:MM:SS,然后按机器本地时区解析。 - 带明确时区的绝对时间 —— 按客户提供的时区或 UTC 偏移解析。
1. 相对时间
最近 15 分钟
FROM=$(($(date +%s) - 900))
TO=$(date +%s)
**2. 无时区的自然语言绝对时间**
如果用户给出日期 / 时间但无时区,使用机器本地时区。先将 `2026年3月13日12点` 这类自然语言归一化为 `2026-03-13 12:00:00`,再按本地时间解析。
示例:2026年3月13日12点 -> 2026-03-13 12:00:00
Linux(GNU date):本地时区
FROM=$(date -d "2026-03-13 12:00:00" +%s)
macOS(BSD date):本地时区
FROM=$(date -j -f "%Y-%m-%d %H:%M:%S" "2026-03-13 12:00:00" +%s)
对于"2026年3月13日12点到13点"这类时间范围,用同样方式计算两个端点。对于单个时间点请求,从用户意图推断一个实用窗口;若不清楚,执行前先询问范围。
**3. 带明确时区的绝对时间**
将本地日期 / 时间转换为 Unix 时间戳:用 `date -u` 将输入解析为 UTC,然后**减去**该时区的 UTC 偏移秒数。
公式:`unix_ts = date_utc_parse(input) − (UTC_offset_hours × 3600)`
示例:2025-01-15 10:30:00 北京时间(UTC+8)
北京为 UTC+8,因此减去 8 × 3600 = 28800
Linux(GNU date)
FROM=$(( $(date -u -d "2025-01-15 10:30:00" +%s) - 28800 ))
macOS(BSD date)
FROM=$(( $(date -u -j -f "%Y-%m-%d %H:%M:%S" "2025-01-15 10:30:00" +%s) - 28800 ))
示例:2025-01-15 10:30:00 纽约时间(UTC-5)
纽约为 UTC-5,因此减去 -5 × 3600 = 减去 -18000 = 加 18000
Linux(GNU date)
FROM=$(( $(date -u -d "2025-01-15 10:30:00" +%s) + 18000 ))
macOS(BSD date)
FROM=$(( $(date -u -j -f "%Y-%m-%d %H:%M:%S" "2025-01-15 10:30:00" +%s) + 18000 ))
常见 UTC 偏移(要减去的值):
| 时区 | UTC 偏移小时 | 要减去的秒数 |
|------------------|------------------|---------------------|
| 北京(UTC+8) | +8 | `28800` |
| 东京(UTC+9) | +9 | `32400` |
| 伦敦(UTC) | 0 | `0` |
| 纽约(UTC-5) | -5 | `-18000` |
---
### 步骤 5:通过 `get-logs-v2` 执行
使用 `aliyun sls get-logs-v2` 执行查询。运行 `aliyun help sls get-logs-v2` 查看 CLI 参数用法;详细 API 参数说明请阅读 [references/related-apis.md](references/related-apis.md)。
**必需 CLI 标志:**
- `--project`:SLS 项目名
- `--logstore`:项目内的 Logstore 名
- `--from`:时间范围起点,**Unix 秒级时间戳**(含)
- `--to`:时间范围终点,**Unix 秒级时间戳**(不含)
- `--query`:步骤 3 构建的语句
分页方式取决于语句是否含 `|`:
#### 5.1 仅索引搜索 —— 用 `--offset` / `--line` 分页
aliyun sls get-logs-v2 \
--project my-project --logstore my-logstore \
--from 1740000000 --to 1740003600 \
--query '* and "payment failed" and status: "500"' \
--line 100 --offset 0 --reverse true
- 分页:`--line` 是页大小(`1–100`,必填);`--offset` 是起始行(可选,默认 `0`)。
- 排序:`--reverse true` 返回最新在前;默认 `false` 为最旧在前。
#### 5.2 含 SQL —— 用语句内 `LIMIT` 分页
aliyun sls get-logs-v2 \
--project my-project --logstore my-logstore \
--from 1740000000 --to 1740003600 \
--query 'status: "500" | SELECT request_uri, count(*) AS cnt FROM log GROUP BY request_uri ORDER BY cnt DESC LIMIT 20'
- SQL 默认结果上限为 **100 行**。要获取更多结果或分页:
- `LIMIT count` —— 提高上限(例如 `LIMIT 500` 最多返回 500 行)
- `LIMIT offset, count` —— 分页(例如 `LIMIT 20, 20` 为第 21–40 行;`LIMIT 40, 20` 为第 41–60 行)。offset+count 最大为 1000000。
- **不要**使用 `LIMIT count OFFSET offset` 语法 —— **不支持**。始终使用 `LIMIT offset, count`。
- 排序:用 `ORDER BY <field> DESC/ASC` 排序。
**结果完整性检查:** 每个响应都包含 `meta.progress`。若为 `Incomplete`,**重新发起同一请求**直到返回 `Complete`。
---
### 步骤 6:从响应中提取数据
`get-logs-v2` 返回:
{
"meta": { "progress": "Complete", "count": 10, ... },
"data": [ { "field1": "value1", ... }, ... ]
}
| 字段 | 含义 |
|-------|---------|
| `meta.progress` | `Complete` 或 `Incomplete`(见步骤 5) |
| `meta.count` | 返回的行数 |
| `data` | 日志条目或聚合行数组;可能包含 `__time__`(Unix 秒,字符串) |
用 `jq`(首选)或 `--cli-query`(JMESPath)提取用户需要的字段:
| 提取 | `jq` | `--cli-query`(JMESPath) |
|---------|------|--------------------------|
| 数据行 | `\| jq '.data'` | `--cli-query 'data'` |
| 进度 | `\| jq '.meta.progress'` | `--cli-query 'meta.progress'` |
| 行数 | `\| jq '.meta.count'` | `--cli-query 'meta.count'` |
| 特定字段 | `\| jq '.data[] \| {LogStore, read_mb}'` | `--cli-query 'data[].{LogStore: LogStore, read_mb: read_mb}'` |
---
### 步骤 7:呈现 CLI 命令和结果
**CLI 命令** —— 始终展示完整、可直接复制粘贴的 `aliyun sls get-logs-v2 ...` 命令。脱敏任何 AK/SK。如果查询未执行(写入 / 解释场景),呈现用户应运行的命令。
**结果** —— 查询已执行时,用步骤 6 提取 `data` 并按用户要求格式化(表格、列表、摘要等)。附加一句说明查询模式选择理由。
---
全局规则
- 原始日志检索始终优先索引搜索以获最快速度;分析或字段投影使用索引搜索 + SQL。
- 当用户只需要特定字段时,用
SELECT投影它们,而非获取全部原始日志 —— 这减少网络开销。需要目标字段doc_value: true(在步骤 1 确认)。 - 不要硬编码
__time__过滤 —— 通过--from/--to传时间范围。 - 已废弃 API:绝不调用
get-logs;始终使用get-logs-v2。
故障排查
当用户报告"无数据"、"结果错误"或 CLI 错误时,严格按此顺序走查清单:
- 时间范围 ——
--from/--to错误?用了毫秒而非秒?最近的写入仍在索引中? - 索引配置 —— 字段索引缺失?全文索引关闭?目标字段不在
keys中? - 字段类型 / 统计 —— 对
text字段做范围查询?对无doc_value的字段做 SQL? - 语法 —— SQL 与 SPL 混用?模糊匹配中的前导
*?SPL 字符串转义? - 模式选择 —— 索引查询即可时却用扫描?在 SPL 中聚合而非 SQL?
- 完整性 ——
meta.progress = Incomplete,调用方未重试(见步骤 5)。 - ProjectNotExist —— 地域或端点错误。用跨地域发现自动定位项目,或请用户确认地域。调用
get-project --cross-region true前,必须先阅读 references/regions.md 中的跨地域发现章节 —— 该 API 仅通过cn-zhangjiakou.log.aliyuncs.com端点可用。 - 网络故障(超时、连接被拒绝)—— 尝试切换到内网端点。见 references/regions.md。
完整故障模式和错误码目录,见 references/troubleshooting.md 和 references/related-apis.md 中的 Common Errors 表。
参考文档
| 文档 | 说明 |
|---|---|
| references/query-analysis.md | 模式决策、索引搜索 / SQL 规则、扫描语义 |
| references/spl-guide.md | SPL 管道语法、常用命令、字段处理 |
| references/functions-guide.md | 函数分类、SQL/SPL 差异、模板 |
| references/troubleshooting.md | "无数据 / 结果错误 / 报错"手册 |
| references/related-apis.md | GetLogsV2 和 GetIndex API 与 CLI 参考 |
| references/ram-policies.md | 最小及完整 RAM 策略 |
| references/cli-installation-guide.md | Aliyun CLI 安装、鉴权模式、profile |
| references/regions.md | 地域 / 端点配置、内网端点、跨地域发现(get-project --cross-region true,仅 cn-zhangjiakou) |
| references/acceptance-criteria.md | CLI 调用验收测试 |
references/query_analysis/*.yaml · references/spl/*.yaml · references/functions/*.yaml | 本 Skill 捆绑的权威 YAML |
阿里云skills
◯ 评论 0