mcpField
S
spl-to-apl

spl-to-apl

github.com/axiomhq数据与数据库172.6k 次安装今天更新
代码仓库

关于 spl-to-apl

SPL to APL Translator 是帮助日志分析人员将 Splunk SPL 查询改写为 Axiom APL 的参考技能,涵盖命令、函数、时间筛选及常见查询模式。

主要功能

  1. 01映射 SPL 命令与 APL 运算符
  2. 02提供统计与字段转换示例
  3. 03说明时间范围的显式写法
  4. 04列出正则、JSON 与数组转换方式
  5. 05提示类型转换和 JOIN 限制

适用场景

  1. 01迁移 Splunk 搜索到 Axiom
  2. 02将 SPL 时间图表改写为 APL 汇总
  3. 03转换正则提取、子查询或关联查询

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/axiomhq/skills --skill spl-to-apl

安装后在 Claude Code 中输入/spl-to-apl确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.meta/
2026-01-28-schema-read-findings.md
cases.ts
DESIGN-NOTES.md
spl-to-apl.eval.ts
reference/
command-mapping.md
dataset-schemas.md
examples.md
function-mapping.md
tests/
test-queries.md

详细介绍

SPL 到 APL 转换器

类型安全: status 等字段通常以字符串形式存储。进行数值比较前务必先转换类型:使用 toint(status) >= 500,而不是 status >= 500。


关键差异

  1. APL 中的时间是显式指定的: SPL 时间选择器无法直接转换 — 添加 where _time between (ago(1h) .. now())
  2. 结构: SPL index=... | command → APL ['dataset'] | operator
  3. Join 为预览功能: 限制为 50k 行,仅支持 inner/innerunique/leftouter
  4. cidrmatch 参数顺序相反: SPL cidrmatch(cidr, ip) → APL ipv4_is_in_range(ip, cidr)

核心命令映射

SPLAPL说明
search index=...['dataset']数据集替代索引
search field=valuewhere field == "value"显式使用 where
wherewhere相同
statssummarize聚合语法不同
evalextend创建或修改字段
table / fieldsproject选择列
fields -project-away移除列
rename x as yproject-rename y = x重命名
sort / sort -order by ... asc/desc排序
head Ntake N限制行数
top N fieldsummarize count() by field | top N by count_两步操作
dedup fieldsummarize arg_max(_time, *) by field保留最新记录
rexparse 或 extract()正则表达式提取
joinjoin预览功能
appendunion合并数据集
mvexpandmv-expand展开数组
timechart span=Xsummarize ... by bin(_time, X)手动分箱
rare N fieldsummarize count() by field | order by count_ asc | take N最少的 N 个
spathparse_json() 或 json['path']JSON 访问
transaction无直接对应项使用 summarize + make_list

完整映射:reference/command-mapping.md


Stats → Summarize

# SPL
| stats count by status

# APL  
| summarize count() by status
主要函数映射
SPLAPL
countcount()
count(field)countif(isnotnull(field))
dc(field)dcount(field)
avg/sum/min/max相同
median(field)percentile(field, 50)
perc95(field)percentile(field, 95)
first/lastarg_min/arg_max(_time, field)
list(field)make_list(field)
values(field)make_set(field)
条件计数模式
# SPL
| stats count(eval(status>=500)) as errors by host

# APL
| summarize errors = countif(status >= 500) by host

完整函数列表:reference/function-mapping.md


Eval → Extend

# SPL
| eval new_field = old_field * 2

# APL
| extend new_field = old_field * 2
主要函数映射
SPLAPL说明
if(c, t, f)iff(c, t, f)多一个 'f'
case(c1,v1,...)case(c1,v1,...,default)需要默认值
len(str)strlen(str)
lower/uppertolower/toupper
substrsubstringAPL 中从 0 开始计数
replacereplace_string
tonumbertoint/tolong/toreal显式指定类型
match(s,r)s matches regex "r"运算符
split(s, d)split(s, d)相同
mvjoin(mv, d)strcat_array(arr, d)合并数组
mvcount(mv)array_length(arr)数组长度
Case 语句模式
# SPL
| eval level = case(
    status >= 500, "error",
    status >= 400, "warning",
    1==1, "ok"
  )

# APL  
| extend level = case(
    status >= 500, "error",
    status >= 400, "warning",
    "ok"
  )

注意:SPL 的 1==1 兜底条件在 APL 中会变为隐式默认值。


Rex → Parse/Extract

# SPL
| rex field=message "user=(?<username>\w+)"

# APL - parse with regex
| parse kind=regex message with @"user=(?P<username>\w+)"

# APL - extract function  
| extend username = extract("user=(\\w+)", 1, message)
简单模式(非正则表达式)
# SPL
| rex field=uri "^/api/(?<version>v\d+)/(?<endpoint>\w+)"

# APL
| parse uri with "/api/" version "/" endpoint

时间处理

SPL 时间选择器无法直接转换。务必添加显式时间范围:

# SPL (time picker: Last 24 hours)
index=logs

# APL
['logs'] | where _time between (ago(24h) .. now())
Timechart 转换
# SPL
| timechart span=5m count by status

# APL
| summarize count() by bin(_time, 5m), status

常见模式

错误率计算
# SPL
| stats count(eval(status>=500)) as errors, count as total by host
| eval error_rate = errors/total*100

# APL
| summarize errors = countif(status >= 500), total = count() by host
| extend error_rate = toreal(errors) / total * 100
子查询(子搜索)
# SPL
index=logs [search index=errors | fields user_id | format]

# APL
let error_users = ['errors'] | where _time between (ago(1h) .. now()) | distinct user_id;
['logs']
| where _time between (ago(1h) .. now())
| where user_id in (error_users)
Join 数据集
# SPL
| join user_id [search index=users | fields user_id, name]

# APL
| join kind=inner (['users'] | project user_id, name) on user_id
类似 Transaction 的分组
# SPL
| transaction session_id maxspan=30m

# APL (no direct equivalent — reconstruct with summarize)
| summarize 
    start_time = min(_time),
    end_time = max(_time),
    events = make_list(pack("time", _time, "action", action)),
    duration = max(_time) - min(_time)
  by session_id
| where duration <= 30m

字符串匹配性能

SPLAPL速度
field="value"field == "value"最快
field="*value*"field contains "value"中等
field="value*"field startswith "value"快
match(field, regex)field matches regex "..."最慢

优先使用 has 而非 contains(单词边界匹配速度更快)。区分大小写时使用 _cs 变体(速度更快)。


参考

  • reference/command-mapping.md — 完整命令列表
  • reference/function-mapping.md — 完整函数列表
  • reference/examples.md — 完整查询转换示例
  • APL 文档:https://axiom.co/docs/apl/introduction

评论

支持 Markdown