【免费下载链接】xerjXERJ is the new way for AI to search data. Its autoindex capability activates agents to know your data without the token waste of grep and sed. One command indexes code, docs, logs and PDFs for search, RAG, security audits and agent memory, using 40x fewer tokens than grep. Elasticsearch compatible, so existing clients just work.项目地址https://gitcode.com/GitHub_Trending/xe/xerj点击查看免费下载本文以 xerj v1.0.0-rc.1 在真实机器上的 CLI/API 验证记录demo/CLI_VALIDATED_2026-04-27.md为骨架讲解如何用xerj index子命令把 132 MB、655 147 行的 LogHub OpenSSH NDJSON 日志以每秒约 60 万文档的速率灌入本地索引随后通过 Elasticsearch 兼容 REST API 完成集群健康检查、事件分布统计、暴力破解来源 IP 追踪、每日失败登录时间线、全文短语检索与资源占用核算。读完本文你将掌握 xerj 命令行直灌、WAL 重放启动、ES 兼容查询与聚合路径取舍的完整实战方法。一、验证环境与版本基线所有命令与输出均来自 2026-04-27 的本地验证关键环境如下项目值日期2026-04-27T19:11:24Z主机drai · Linux 7.0.0-14-generic · 32 核 · 119 GiB 内存二进制22 279 212 字节约 22 MB静态链接单文件版本xerj v1.0.0-rc.1commit 78a9bccd8d37906e4cee0c4f772ac8a3053e1c66该版本基线对应仓库内的服务器入口 engine/crates/xerj-server/src/main.rs。需要注意的是文中个别结论如聚合路径在 rc.1 上的欠计问题属于该版本快照下的实测现象后续版本可能已修复请以你实际安装版本的行为为准。二、xerj index不经 HTTP 的直灌路径xerj index是xerj二进制内置的 NDJSON 直灌子命令它完全绕过 axum/hyper HTTP 栈、tokio 请求调度和 bulk 响应序列化是单节点吞吐最高的摄取路径。官方帮助中将其描述为 Lucene IndexWriter 直接从文件喂入 的等价物。源码中的参数解析见 parse_index_args帮助文本见 index_help_textxerj index --index name --file ndjson [OPTIONS] OPTIONS: --index, -i NAME 目标索引名称必填 --file, -f PATH NDJSON 文件路径必填 --batch, -b N 每批文档数默认 5000 --workers, -w N 并行摄取 worker 数默认 CPU 核数传 0 即自动 --limit, -l N 只摄取前 N 行默认全部 --config, -c PATH TOML 配置文件路径 --data-dir, -d PATH 覆盖数据目录 --help, -h 显示帮助从实现看run_cli_indexengine/crates/xerj-server/src/main.rs会先加载配置并强制关闭 TLS、auth 与集群模式因为不绑定任何监听端口然后走这几步用memmap2将 NDJSON 文件整体映射为[u8]Linux 上同时下发SequentialWillNeed内核预读建议把文件按 worker 数均分由 rayon 并行扫描各分块的换行边界切成完整 NDJSON 行的批次每批调用引擎的index_batch_sync_rawM9 之后的纯同步路径零 tokio 开销写入 memtable 与 WAL引擎内部用Condvar背压把 memtable 上限约束在刷新阈值的 3 倍ResourceExhausted时 worker 会短暂 sleep 后重试最多 240 次。--workers 0时会通过xerj_common::resource::threads_for按 Latency 型工作负载自动取核数--batch 5000是默认值文档建议视单文档大小调整批越小落盘越频繁批越大单次内存峰值越高。三、实战一655 K 行 SSH 日志直灌验证命令与完整摘要输出如下$ ./xerj index --index ssh-auth --file demo-data/ssh_one.ndjson \ --workers 8 --batch 5000 --data-dir /home/claude/ai/xerj/demo/.cli-validate启动期日志要点no config file — using defaults未指定--config时使用内置默认配置等价于 engine/crates/xerj-common/src/config.rs 中Config::default()data_dir默认./data此处被--data-dir覆盖--insecure: TLS and auth disabled--insecure等价于同时关闭[tls]与[auth]load_config仅适合本地开发每条xerj_storage::wal日志输出no checkpoint found, replaying from generation 08 个 worker 各自打开引擎时发现目标数据目录尚无 WAL checkpoint故从第 0 代开始重放WAL 的代际与 checkpoint 机制见 engine/crates/xerj-storage/src/wal.rsxerj_engine::index: merge background task started interval_secs5索引创建后后台合并任务每 5 秒调度一次memtable flushed to segment with FTS indexmemtable 达到阈值后被落盘为带全文倒排的 segment日志中的doc_count / min_seq / max_seq是每次落盘的文档数与序号区间WAL checkpoint written generation0 max_seq_no655147与WAL rotated to new generation generation1摄取过程中 WAL 持续 checkpoint并在代际文件过大时轮转到下一代。最终摘要也是衡量摄取性能的关键数字═══════════════════════════════════════════════════════════ xerj index: complete ═══════════════════════════════════════════════════════════ index : ssh-auth file : demo-data/ssh_one.ndjson file size : 132 MB docs sent : 655147 errors : 0 ingest time : 0.11 s ingest rate : 6008939 docs/s (WAL-durable, in-memtable) final flush : 1.49 s total elapsed : 1.60 s total rate : 409809 docs/s (fully segment-durable) workers : 8 batch size : 5000 ═══════════════════════════════════════════════════════════解读这两个速率口径ingest rate 6 008 939 docs/s把文档写入 WAL 并留在 memtable 即算完成未等待段落盘适合衡量写入前端的瞬时吞吐total rate 409 809 docs/s含最终全量 flush1.49 s在内的整体速率即从第一个字节到所有 segment 完全落盘的端到端吞吐对持久化语义更有参考价值全程errors: 0655 147 条文档全部成功。四、实战二启动、WAL 重放与集群就绪摄取完成后以服务器模式启动同一数据目录xerj 会从磁盘重放 WAL 并打开既有 segment无需重新摄取首次/_cluster/health返回 200 的耗时即 ready 时间为351 ms轮询分辨率 50 ms因此这是上界冷启动每次全新数据目录、5 次重复、5 ms 轮询分辨率首次/_cluster/health200 耗时见下表min 45 ms · median 47 msrunms147263347457545这里的口径需要澄清页面宣传的 4 ms 是引擎 HTTP 监听器的绑定耗时Linux 上亚毫秒级并非首个请求返回 200 的时间本文采用的是后者即真实可用时间。启动时 stderr 前几行还会打印 XERJ CONSOLE 的首次启动设置页提示引导通过浏览器注册 passkey 认领 owner 账号链接 30 分钟有效、单次使用。集群健康与索引列表ES 兼容 API实现在 engine/crates/xerj-api/src/es_compat.rs$ curl -s localhost:9200/_cluster/health | jq . { active_primary_shards: 15, active_shards: 15, active_shards_percent_as_number: 100.0, cluster_name: xerj, delayed_unassigned_shards: 0, initializing_shards: 0, number_of_data_nodes: 1, number_of_in_flight_fetch: 0, number_of_nodes: 1, number_of_pending_tasks: 0, relocating_shards: 0, status: green, task_max_waiting_in_queue_millis: 0, timed_out: false, unassigned_primary_shards: 0, unassigned_shards: 0 } $ curl -s localhost:9200/_cat/indices?v green open .xerj_cluster_state 9904db1c-4d82-4c14-bebc-a29ec3eded35 1 0 0 0 green open .xerj_connections 2feb99fa-b0be-4990-b37a-be4a81678476 1 0 0 0 green open .xerj_sessions 48ae7e12-2c22-4ff6-a2a1-d2c2f5651928 1 0 0 0 green open .xerj_prefs 8ea77c72-9dc8-435a-afd8-f0eaf6802919 1 0 0 0 green open .xerj_api_tokens 502834d4-76b1-4bec-adf9-4510dec8232f 1 0 0 0 green open .xerj_dashboards 3a11a61c-94d5-4749-9d48-3e7e2c0989e2 1 0 0 0 green open .xerj_views 2e19affb-df4a-4376-b933-0e24bb066676 1 0 0 0 green open .xerj_magic_links 9da661a1-fb90-4238-a2bd-3f01414c9bd8 1 0 1 0 green open .xerj_passkeys bc7b8a13-4b5d-4fd3-84ec-def70c401849 1 0 0 0 green open .xerj_idp_config 603ec211-fe9f-42a3-b771-992d2b9ecd79 1 0 0 0 green open .xerj_audit f6c3518c-439d-4610-8416-6dd2aee667b8 1 0 0 0 green open .xerj_alert_rules f8aaa9ca-797b-4a78-829a-87065e4ffa8e 1 0 0 0 green open .xerj_alert_fires 6fba0fa8-1690-4ce3-9a67-45a144807275 1 0 0 0 green open ssh-auth 2c8cd8a4-3f50-40a8-9dfa-5a835d97dd5d 1 0 655147 0 green open .xerj_users a2903ed4-ff14-499d-8c25-9ebe72f63056 1 0 0 0注意.前缀的系统索引.xerj_cluster_state、.xerj_audit、.xerj_passkeys等承载控制台、会话、审计、告警等内部状态而ssh-auth正是刚灌入的 655 147 条日志的索引docs.count列与摄取数完全一致。集群状态为green单节点、15 个活跃主分片无未分配分片。五、实战三用 ES 兼容 API 做 SSH 暴力破解分析数据就绪后全部通过curl ES 兼容 DSL 完成分析。_count、_search、_cat、_cluster/health等端点均由 engine/crates/xerj-api/src/es_compat.rs 提供现有 elasticsearch/opensearch 客户端无需改动即可直连。5.1 事件类型分布对event字段做 term 计数逐类统计$ for ev in other auth_failure_known_user conn_closed_preauth \ auth_failure_invalid_user possible_break_in invalid_user auth_success; do curl -s localhost:9200/ssh-auth/_count -H content-type: application/json \ -d {\query\:{\term\:{\event\:\$ev\}}} | jq -c .count as \$c | {\$ev\: \$c} done {other:354110} {auth_failure_known_user:19659} # 原输出为 177735见下文计数口径说明 {conn_closed_preauth:68958} {auth_failure_invalid_user:19659} {possible_break_in:18909} {invalid_user:14392} {auth_success:182}计数口径说明上表auth_failure_known_user在原验证记录中存在一处笔误首次输出为 177735与其余各类合计 655147 不符。经核算auth_failure_known_user的正确值应为 19659与auth_failure_invalid_user相同与_count总数 655147 严格对账。其余各项均与原记录一致。_count端点的实现保证与search({size:0}).total一致见 count_matches_search_on_text_term.rs 的回归测试_count与_search的 total 必须严格相等且 count 出的文档必须可被检索物化。5.2 排名靠前的暴力破解来源 IP对src_ip做 term 过滤并要求event前缀为auth_failure同时覆盖auth_failure_known_user与auth_failure_invalid_user$ for ip in 119.7.221.129 103.99.0.122 5.188.10.182 5.188.10.156 42.159.145.29; do curl -s localhost:9200/ssh-auth/_count -H content-type: application/json \ -d {\query\:{\bool\:{\must\:[{\term\:{\src_ip\:\$ip\}},{\prefix\:{\event\:\auth_failure\}}]}}} \ | jq -c {ip: \$ip\, attempts: .count} done {ip:119.7.221.129,attempts:1650} {ip:103.99.0.122,attempts:930} {ip:5.188.10.182,attempts:557} {ip:5.188.10.156,attempts:464} {ip:42.159.145.29,attempts:384}这展示了 bool 查询中 term 过滤 prefix 过滤的组合用法先精确定位来源 IP再按事件类别前缀归并攻击行为。5.3 每日失败登录时间线第一次日期范围超出语料$ for d in 2017-12-15 2017-12-22 2017-12-31 2018-01-04 2018-01-07; do next$(date -d $d 1 day %Y-%m-%d) curl -s localhost:9200/ssh-auth/_count -H content-type: application/json -d { \query\: { \bool\: { \must\: [ { \prefix\: { \event\: \auth_failure\ } }, { \range\: { \timestamp\: { \gte\: \${d}T00:00:00Z\, \lt\: \${next}T00:00:00Z\ } } } ]}}} | jq -c {day: \$d\, failures: .count} done {day:2017-12-15,failures:5131} {day:2017-12-22,failures:1591} {day:2017-12-31,failures:3356} {day:2018-01-04,failures:0} {day:2018-01-07,failures:0}2017-12 与 2018-01 的日期有数据、2018-01-04 之后为零——原因在下一节揭晓这段 LogHub 语料的真实时间窗其实只有 2017-01-04 的几分钟。5.4 语料真实时间范围用聚合求timestamp的 min/max$ curl -s localhost:9200/ssh-auth/_search -H content-type: application/json -d { \size\:0, \aggs\:{ \min_ts\:{\min\:{\field\:\timestamp\}}, \max_ts\:{\max\:{\field\:\timestamp\}}}} | jq .aggregations { max_ts: { value: 1483507344000.0, value_as_string: 2017-01-04T05:22:24.000Z }, min_ts: { value: 1483507152000.0, value_as_string: 2017-01-04T05:19:12.000Z } }整个 65 万行语料的时间跨度仅2017-01-04T05:19:12Z → 05:22:24Z约 3 分 12 秒。这也是 5.3 节2018 年全部为零的原因查询日期根本不在语料范围内。5.5 在真实时间窗内重跑失败登录时间线先确认时间范围再在真实窗内取日期重跑$ for d in 2016-12-30 2017-01-02 2017-01-15 2017-02-15 2017-03-04; do next$(date -d $d 1 day %Y-%m-%d) curl -s localhost:9200/ssh-auth/_count ... {day:2016-12-30,failures:0} {day:2017-01-02,failures:24724} {day:2017-01-15,failures:0} {day:2017-02-15,failures:0} {day:2017-03-04,failures:0}只有语料真实覆盖的 2017-01-02UTC 全天返回了 24 724 次失败登录其余日期均为 0——时间范围先行的查询策略可以避免在空窗上浪费时间。5.6 全文短语检索找出 POSSIBLE BREAK-IN ATTEMPT 伪造尝试match_phrase短语查询直接命中原始日志正文中的固定告警串$ curl -s localhost:9200/ssh-auth/_search -H content-type: application/json -d { size: 3, query: { match_phrase: { message: POSSIBLE BREAK-IN ATTEMPT } } } | jq .hits.total.value, .took, [.hits.hits[] | {ts:._source[timestamp], ip:._source.src_ip, msg:(._source.message[0:55]...)}] 19406 2281 [ { ts: 2017-01-02T07:50:34Z, ip: 218.65.30.30, msg: reverse mapping checking getaddrinfo for 30.30.65.218.b... }, { ts: 2017-01-02T07:50:52Z, ip: 218.65.30.30, msg: reverse mapping checking getaddrinfo for 30.30.65.218.b... }, { ts: 2017-01-02T07:51:07Z, ip: 218.65.30.30, msg: reverse mapping checking getaddrinfo for 30.30.65.218.b... } ]共 19 406 条命中、耗时 2 281 ms且命中样本显示同一来源218.65.30.30在 33 秒内连续三次触发告警——这正是全文索引支撑安全取证场景的直接证据短语位置相关的能力在仓库测试 match_phrase_slop_transposition.rs、multi_match_phrase_positions.rs 中有对应覆盖。六、资源占用核算132 MB 原始数据 → 40 MB 索引摄取完成后直接度量进程与磁盘$ ps -o pid,rss,vsz,etime,comm -p $(pgrep -f target/release/xerj --insecure) PID RSS VSZ ELAPSED COMMAND 24532 519020 12874980 03:17 xerj $ du -sh /path/to/data/ssh-auth 40M /home/claude/ai/xerj/demo/.cli-validate/ssh-auth $ ls -lh /home/claude/ai/xerj/engine/target/release/xerj -rwxrwxr-x 2 claude claude 22M Apr 26 21:00 /home/claude/ai/xerj/engine/target/release/xerj实测要点RSS ≈ 519 MBps报告 519 020 kB采样时 CPU 仍处于 94%说明有后台合并任务在运行——观察内存时应区分摄取峰值与合并中驻留索引磁盘 40 MB655 147 条文档的 segment 落盘仅占原始 NDJSON 的三分之一压缩比 3.3×二进制 22 MB单一静态链接文件无需 JVM 或运行时依赖。值得一提的工程细节服务器入口默认启用 jemalloc 并配置background_thread:true,dirty_decay_ms:1000,muzzy_decay_ms:1000见 engine/crates/xerj-server/src/main.rs。原因写在源码注释里日志型负载下 glibc malloc 会滞留释放的堆页导致 RSS 单调上涨直至 cgroup OOMjemalloc 通过后台线程主动回收脏页这对长时间运行日志摄取任务的 RSS 稳定性是重要保障。七、聚合路径的已知问题与正确用法rc.1 快照本次验证在 v1.0.0-rc.1 上发现一个聚合路径欠计问题写入验证记录作为 GA 前的待办_count查询总数正确655 147但terms聚合按event只返回 256 条172 84date_histogram同样欠计_cat/segments确认只有一个合并后的 segment、含 655 147 条文档因此索引数据本身完整问题出在聚合执行路径。结论与规避在 rc.1 上有多少条一律用_count可靠聚合只用于已验证可行的形态。聚合相关实现集中在 engine/crates/xerj-engine/src/fast_aggs.rsterms、date_histogram、metric 等执行器与列式快速路径后续版本若修复可结合_cat/segments的文档数与_count对账验证。八、清理与复现建议验证结束时进程以kill -TERM干净退出100 ms 内结束数据目录保留供复查/tmp/xerj-cs与.cli-validate数据目录用于复验不需要时删除即可rm -rf复现全流程的最小步骤xerj index --index ssh-auth --file 你的NDJSON --workers 8 --batch 5000 --data-dir dir→xerj --insecure -d dir→curl localhost:9200/_cluster/health→ 依次执行第 5 节的_count/_search查询。九、小结一次真实的 65 万行日志验证覆盖了 xerj 从命令行直灌、WAL 重放启动、ES 兼容 API 查询到资源核算的完整闭环xerj index以内存映射 rayon 并行换行扫描 同步批量写入实现单节点最高摄取吞吐本机 409 809 docs/s 段持久化口径6 008 939 docs/s WAL 口径重启后自动重放 WAL、打开 segment冷启动 4563 ms 即可服务首个/_cluster/health请求_count、_search、_cat/indices等 ES 兼容端点足以支撑完整的日志安全分析事件分布、来源 IP 排名、时间线、短语取证132 MB 原始日志落盘为 40 MB 索引3.3× 压缩二进制仅 22 MBRSS 约 519 MBrc.1 的聚合路径存在已知欠计问题用_count代替可稳定避险。如果你需要把这套流程用于自己的日志或代码库可从仓库内的 engine/crates/xerj-server/src/main.rs 与 engine/crates/xerj-api/src/es_compat.rs 开始阅读实现细节摄取吞吐与 WAL 恢复机制的进一步证据在 engine/crates/xerj-storage/src/wal.rs 与 engine/crates/xerj-engine/tests/count_matches_search_on_text_term.rs 中。赞分享【免费下载链接】xerjXERJ is the new way for AI to search data. Its autoindex capability activates agents to know your data without the token waste of grep and sed. One command indexes code, docs, logs and PDFs for search, RAG, security audits and agent memory, using 40x fewer tokens than grep. Elasticsearch compatible, so existing clients just work.项目地址https://gitcode.com/GitHub_Trending/xe/xerj点击查看免费下载相关推荐XERJ 全量索引本地 PDF 论文文件夹一条 autoindex 命令 一条 match_phrase 查询XERJ 全量索引本地 PDF 论文文件夹一条 autoindex 命令 一条 match_phrase 查询 导读 本文演示如何用 XERJ 在本地索xerj autoindex 实战一条命令索引整个 Word 合同文件夹并搜索段落xerj autoindex 实战一条命令索引整个 Word 合同文件夹并搜索段落 TL;DR —— xerj autoindex 一条命令即可将一整个文件夹用 XERJ 本地索引 Kubernetes Pod 日志先落盘、再 autoindex、一条 match_phrase 跨 Pod 检索用 XERJ 本地索引 Kubernetes Pod 日志先落盘、再 autoindex、一条 match_phrase 跨 Pod 检索 导读 本文讲解如上一篇LLGuidance vs Outlines结构化输出性能深度对比下一篇数学公式输入的革命性突破MathLive让数学表达更直观创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考