阿里云 SLS 查询与分析
场景说明
当用户有以下需求时,请使用此 skill:
- 解释、重写、优化或执行现有查询
- 将自然语言需求转换为 SLS 索引查询、SQL 或 SPL 语句
---
前提条件
安装阿里云 CLI
运行 aliyun version,确认版本是否 >= 3.3.8。如果尚未安装或版本过旧,请按照文档 [references/cli-installation-guide.md](references/cli-installation-guide.md) 进行安装或更新。
更新插件
aliyun plugin update
检查是否已配置阿里云凭证
运行 aliyun configure list 检查是否已配置凭证。 如果未显示有效的配置文件,请在此处停止,并要求用户在本次会话之外运行 aliyun configure。
安全规则:
- 严禁读取、回显或打印 AK/SK 的值
- 严禁要求用户将 AK/SK 粘贴到对话中
- 只能使用
aliyun configure list检查凭证状态
---
RAM 权限要求
| API | CLI | 操作 | 用途 | |-----|-----|--------|---------| | GetLogsV2 | get-logs-v2 | log:GetLogStoreLogs | 执行查询 / SQL / SPL 并读取结果 | | GetIndex | get-index | log:GetIndex | 读取索引配置以验证前提条件 |
有关最小权限和完整权限的 RAM 策略 JSON,请参阅 [references/ram-policies.md](references/ram-policies.md)。
权限失败处理:如果调用返回 Unauthorized 权限错误,请停止操作并向用户展示 [references/ram-policies.md](references/ram-policies.md)。未经用户明确确认,不得使用其他账号重试。
---
可观测性(每条 aliyun API 命令都必须遵循)
加载此 skill 后,在整个会话中仅生成一次随机会话 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 均未填充,则该日志库完全没有索引——请立即停止,并告知用户:在运行任何查询 / SQL / SPL 之前,必须先创建索引。
- 响应可能很大——仅提取与当前查询相关的字段。按
logstore分别缓存,并在会话内复用。
有关字段类型、分词方式以及 get-index 如何映射到各项功能,请参阅 [references/related-apis.md](references/related-apis.md) 和 [references/query-analysis.md](references/query-analysis.md)。
---
步骤 2:选择查询模式(关键)
查询语句采用以下形式之一:
| 优先级 | 模式 | 语句形式 | 适用场景 | 要求 | |----------|------|----------------|----------|----------| | 1 | 索引搜索 | <index-search> | 筛选原始日志;返回按时间排序且分页的日志 | 全文索引(line)或任意字段索引(keys.<field>) | | 2 | SQL | <index-search> \| <SQL> | 聚合、GROUP BY、排序、窗口、前 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](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](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](references/query-analysis.md),了解查询与 SQL 规则
- 表名为
log(建议省略)。 - SQL 遵循
get-index返回的索引字段类型——long/double字段可直接比较(status >= 500)。仅当字段以text类型建立索引但需要数值语义时,才进行类型转换(使用try_cast抑制错误)。 - 阅读 [references/functions-guide.md](references/functions-guide.md),了解不常用的函数选择(聚合、JSON、正则表达式、日期时间、IP 地理位置……)
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](references/spl-guide.md)。
3.4 追加 SQL 扫描——目标字段没有索引/统计功能时的回退方案
语法与常规 SQL 相同(见 3.2),但有一点不同:每个字段都是 varchar,因此在进行数值比较或算术运算前,始终先使用 cast() / try_cast() 进行类型转换。有关扫描语义,请参阅 [references/query-analysis.md](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. 相对时间
# recent 15 minutes
FROM=$(($(date +%s) - 900))
TO=$(date +%s)
2. 不含时区的自然语言绝对时间
如果用户提供了日期/时间但未指定时区,请使用机器的本地时区。首先将 2026年3月13日12点 之类的自然语言规范化为 2026-03-13 12:00:00,然后按本地时间解析。
# Example: 2026年3月13日12点 -> 2026-03-13 12:00:00
# Linux (GNU date): local timezone
FROM=$(date -d "2026-03-13 12:00:00" +%s)
# macOS (BSD date): local timezone
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)
# Example: 2025-01-15 10:30:00 Beijing Time (UTC+8)
# Beijing is UTC+8, so subtract 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 ))
# Example: 2025-01-15 10:30:00 New York Time (UTC-5)
# New York is UTC-5, so subtract -5 × 3600 = subtract -18000 = add 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 参数用法;阅读 [references/related-apis.md](references/related-apis.md) 获取详细的 API 参数说明。
必须指定的 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 行)。偏移量与数量之和最大为 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](references/regions.md) 中的“跨地域发现”部分——此 API 仅可通过cn-zhangjiakou.log.aliyuncs.com端点调用。 - 网络故障(超时、连接被拒绝)— 尝试切换到内网端点。请参见 [references/regions.md](references/regions.md)。
有关完整的故障模式和错误码列表,请参见 [references/troubleshooting.md](references/troubleshooting.md),以及 [references/related-apis.md](references/related-apis.md) 中的 Common Errors 表。
---
参考文档
| 文档 | 说明 | |----------|-------------| | [references/query-analysis.md](references/query-analysis.md) | 模式选择、索引查询 / SQL 规则、扫描语义 | | [references/spl-guide.md](references/spl-guide.md) | SPL 管道语法、常用命令、字段处理 | | [references/functions-guide.md](references/functions-guide.md) | 函数类别、SQL/SPL 差异、模板 | | [references/troubleshooting.md](references/troubleshooting.md) | “无数据/结果错误/报错”排查手册 | | [references/related-apis.md](references/related-apis.md) | GetLogsV2 和 GetIndex 的 API 与 CLI 参考文档 | | [references/ram-policies.md](references/ram-policies.md) | 最小权限和完整权限的 RAM 策略 | | [references/cli-installation-guide.md](references/cli-installation-guide.md) | 阿里云 CLI 安装、认证模式、配置文件 | | [references/regions.md](references/regions.md) | 地域/端点配置、内网端点、跨地域发现(get-project --cross-region true,仅限 cn-zhangjiakou) | | [references/acceptance-criteria.md](references/acceptance-criteria.md) | CLI 调用验收测试 | | references/query_analysis/*.yaml · references/spl/*.yaml · references/functions/*.yaml | 随此 skill 提供的权威 YAML 文件 |