BLS 日志服务查询
使用示例
以下是用户可能的提问方式和对应的处理流程:
示例 1:查看日志集
用户:帮我看下我有哪些日志集 处理:询问 region/AK/SK → 调用 list-logstores → 表格展示名称、索引状态、保留天数
示例 2:统计分析
用户:查下 bls-query 日志集中请求量 top10 的用户 处理:describe-index 获取字段 → 发现有 uid 字段 → 生成
select uid, count(*) as cnt group by uid order by cnt desc limit 10→ 执行并展示
示例 3:关键词搜索
用户:帮我搜一下最近1小时有没有 error 日志 处理:计算时间范围(北京时间 -8h 转 UTC)→ 生成
match level:error→ 执行并展示 @raw 原文
示例 4:复杂分析
用户:看下各接口的错误率,按错误率从高到低排 处理:describe-index 确认 path/status 字段 → 生成
select path, count_if(status>=400) as err, count(*) as total, round(count_if(status>=400)*100.0/count(*),2) as err_rate group by path order by err_rate desc limit 20→ 执行并展示
示例 5:非索引字段查询
用户:统计下每个 method 的请求量(method 不在索引中) 处理:describe-index 发现无 method 字段 → 从 @raw 提取 → 生成
select JSON_EXTRACT_SCALAR(\@raw`, '$.method') as method, count(*) as cnt group by method order by cnt desc` → 执行并展示
前置条件
AK/SK 解析顺序(脚本自动处理):
- 命令行参数
--ak/--sk - 环境变量
BCE_BLS_ACCESS_KEY/BCE_BLS_SECRET_KEY - 配置文件
~/.bce_bls/credentials(INI 格式,[default]section 下bce_access_key_id和bce_secret_access_key)
还需要:Region (bj/gz/su/bd/fwh/hkg/nj/yq/cd) 和 Project 名称(可选)。如果用户未提供,主动询问获取。
核心工作流
1. 查询日志组(Project)列表
python3 <skill_path>/scripts/bls_query.py --region <region> list-projects [--page-size <size>]
可选参数:--name 按名称过滤,--page-no 页码(默认 1),--page-size 每页条数(默认 10)。
2. 查询日志集列表
python3 <skill_path>/scripts/bls_query.py --region <region> list-logstores --project <project> [--page-size <size>]
可选参数:--logstore-name 按名称过滤,--page-no 页码(默认 1),--page-size 每页条数(默认 100)。
3. 查询索引配置
确认目标日志集的索引和字段类型,决定查询方式:
python3 <skill_path>/scripts/bls_query.py --region <region> describe-index --project <project> --logstore <logstore>
- 全文索引开启 -> 可用 match 检索
- 字段索引配置 -> 可用字段精确查询和 SQL 分析
- 无索引(全文索引未开启且无字段索引)-> 不能使用 match。若 @raw 为 JSON 格式,可通过 SQL +
JSON_EXTRACT_SCALAR(\@raw`, '$.fieldName')` 提取字段查询;若 @raw 非 JSON 格式,则无法有效查询,应建议用户前往 BLS 控制台为该日志集开启索引
4. 生成查询语句
BLS 支持三种格式:
- match 检索:
match method:GET and status >= 400 - SQL 分析:
select level, count(*) as cnt group by level - 混合查询:
match status:500 | select host, count(*) as cnt group by host
生成规则:
- 生成查询前必须先调用 describe-index 确认索引状态
- 有全文索引或字段索引 -> 搜关键词可用 match
- 无索引 -> 禁止使用 match。若 @raw 为 JSON 格式可用 SQL +
JSON_EXTRACT_SCALAR查询;若 @raw 非 JSON 格式则无法有效查询,应提示用户去 BLS 控制台开启索引 - 统计分析 -> SQL
- 有索引时过滤后统计 -> match | SQL
- SQL 不需要 FROM 子句
- 非索引字段且 @raw 为 JSON 格式时,可通过
JSON_EXTRACT_SCALAR(\@raw`, '$.fieldName')` 从原始日志提取;若 @raw 非 JSON 格式,建议用户开启索引
5. 执行查询
python3 <skill_path>/scripts/bls_query.py --region <region> query \
--project <project> --logstore <logstore> \
--start "<startDateTime>" --end "<endDateTime>" \
--query "<query>"
时间格式 UTC ISO8601(如 2024-01-10T13:00:00Z),北京时间需 -8h 转换。
如果用户没有指定查询时间范围,--start 和 --end 可以省略,脚本默认查询最近 1 小时的数据。
6. 展示结果
- SQL:表格展示 columns + rows
- match:展示 @raw 原文
- 有 nextMarker 且
datasetScanInfo.isTruncated为true时,提示用户可以翻页查看更多
7. 翻页查询(仅检索语句)
当上一次查询返回的 datasetScanInfo.isTruncated 为 true 时,说明还有更多数据。使用 --marker 参数传入响应中的 nextMarker 值获取下一页:
python3 <skill_path>/scripts/bls_query.py --region <region> query \
--project <project> --logstore <logstore> \
--start "<startDateTime>" --end "<endDateTime>" \
--query "<query>" \
--marker "<nextMarker>"
注意事项:
--marker仅对检索语句(match)有效,SQL 分析语句不支持翻页- 翻页时
--start、--end、--query等参数需与首次查询保持一致 - 当
datasetScanInfo.isTruncated为false时,表示已到最后一页
常见查询模式
关键词搜索
match error
match status:500 and msg: "query key word"
Top N 统计
select uid, count(*) as cnt group by uid order by cnt desc limit 10
时间趋势(按小时)
select histogram(cast(@timestamp as timestamp), interval 1 hour) as hour, count(*) as cnt group by hour order by hour
慢请求分析
select path, avg(latency) as avg_latency, max(latency) as max_latency, count(*) as cnt group by path order by avg_latency desc limit 10
从原始日志提取非索引字段
select JSON_EXTRACT_SCALAR(`@raw`, '$.fieldName') as field_alias, count(*) as cnt group by field_alias order by cnt desc limit 10
混合查询(先过滤后统计)
match level:error | select caller, count(*) as cnt group by caller order by cnt desc limit 10
API Reference
详细 API 参数和响应格式见 references/api_reference.md。 详细 SQL 函数见 references/sql_syntax.md 详细 MATCH 语法见 references/match_syntax.md