Apache Kibble 介绍与核心概念
全面介绍 Apache Kibble 的项目定位、发展沿革、Attic 退役状态与核心概念,剖析组织、数据源、视图与组件模型,并说明源码仓库现状与组件形态。
Apache Kibble 介绍与核心概念
一、项目是什么
1.1 一句话定位
Apache Kibble 是 Apache 软件基金会(ASF)旗下的一款软件项目活跃度分析工具,官方对其的一句话定义是:收集、聚合并可视化任意软件项目的活跃度数据(collect, aggregate and visualize data about any software project)。它面向的是"软件工程数据分析"这一细分领域:把散落在代码仓库、邮件列表、缺陷跟踪系统、持续集成服务等基础设施中的原始活动记录,统一采集、标准化存储,并最终以图表视图的形式呈现出来,帮助社区负责人、技术管理者量化地观察一个项目的健康度与发展趋势。
对于运营开源社区的组织来说,这类工具解决的是一个长期痛点:数据分散且口径不一。Git 仓库里有提交记录,邮件列表里有讨论数据,JIRA 里有缺陷流转数据,Jenkins 里有构建数据。想知道"这个项目过去一年到底活跃不活跃",就需要把多源数据拉齐到统一的时间轴与统计口径上。Kibble 正是为这个问题而生。 这个痛点在开源治理语境下尤其尖锐。一个 Apache 项目的活跃度由多种异构信号构成:提交频率反映开发节奏,邮件讨论量反映社区广度,缺陷流转反映维护投入,而它们散落在完全独立的基础设施里,计数口径互不兼容。人工拼凑的月报既费力又难以横向对比;更关键的是,社区健康度的下滑(提交变稀、讨论变冷、维护者流失)是一个渐变过程,靠肉眼很难在早期察觉,需要连续、口径稳定的时间序列才能揭示趋势。Kibble 把"采集、标准化、存储、呈现"固化为一条自动化管道,让活跃度观察从偶发的手工动作变成可持续运行的基础设施——这也是它在 2016 年进入孵化器时的立意:给 Apache 自己的数百个项目提供一个通用的社区度量平台。
1.2 退役状态:必须先说清楚的事实
在阅读任何 Kibble 相关资料之前,有一个关键事实必须先行明确:Apache Kibble 已经退役,进入了 Apache Attic(阁楼)。根据 Attic 官方页面(https://attic.apache.org/projects/kibble.html)记载的完整时间线是:
- 2017 年 10 月,Kibble 从 Apache 孵化器毕业,成为顶级项目(Top Level Project);
- 2025 年 10 月,董事会决议将其退役(board minutes 2025-10-15);
- 2025 年 11 月,迁移到 Attic 的工作全部完成(对应工单 ATTIC-250)。
进入 Attic 意味着:项目不再有活跃开发、不再发布新版本、不再提供官方支持,其官网与代码仓库以只读归档形式保留。因此本文以及本系列后续文档的所有内容,都应当以"历史资料与学习研究"的视角来对待。Kibble 的设计与架构(多源采集、Elasticsearch 存储测算、组件化扫描器)在同类项目中依然具有很高的学习价值,许多思路在后来的开源项目分析平台(如 DevLake、GrimoireLab 等)中都能找到影子,但不建议在生产环境中基于 Kibble 搭建新的分析平台。 对不熟悉 Apache 治理机制的读者,解释一下 Attic 是什么:它是 ASF 为退役项目设立的长期归档机构,进入 Attic 的项目保留完整的版本历史、邮件归档与官网快照,但社区正式解散,不再有任何发布与支持活动。退役决定通常源于社区活力枯竭——提交者减少、版本迭代停滞——而不是技术失败。对研究者的实际影响有三条:第一,文档中的版本信息永远停留在最后状态,不会有新版本修正旧文档的过时之处;第二,依赖的环境(如本例中的 Elasticsearch 8.17.9)也要跟着冻结,升级底层组件可能踩到无人修复的兼容缺陷;第三,安全漏洞不再有官方补丁,任何复活部署都必须自己承担加固责任。本系列文档采用"历史项目 + 现代环境复现"的写法,正是为了同时记录这两方面的知识:Kibble 的设计思想,以及让它跑在现代操作系统上所需的全部修补。
1.3 源码仓库现状
Kibble 的源码保存在版本仓库中,当前实际存在两个相关仓库:
| 仓库 | 内容 | 最后活动 | 可运行性 |
|---|---|---|---|
| apache/kibble(main 分支) | 2.0 重写版,版本号 2.0.0dev | 2023 年 8 月 | CLI 框架可用,API 服务与扫描器为占位实现 |
| apache/kibble-1(master 分支) | 1.x 时代完整服务端 | 2024 年 11 月(社区善后修补) | 完整可运行:API + Elasticsearch 存储层 |
| apache/kibble-scanners(master 分支) | 1.x 配套采集器集合 | 与 kibble-1 同期 | 完整可运行:十余种数据采集器 |
这里有一个值得注意的细节:apache/kibble 主仓库的 main 分支是一次未完成的重写。在该分支上执行 kibble server start 会得到一行直白的输出 "To be implemented!",kibble scanners list 列出的也只是 AbcScanner、XyzeScanner 两个占位名。也就是说,2.0 重写只完成了 CLI 骨架与部分类型定义,服务端能力从未在 main 分支落地。真正完整跑通过、被社区实际使用过的,是 kibble-1 与 kibble-scanners 这对组合。本系列文档的部署与实战篇,均以 kibble-1 + kibble-scanners 为实测对象,并在 Ubuntu 22.04 服务器上完成从零到数据可视的完整流程验证。
二、系统架构与组件
2.1 三大组件
Kibble 1.x 时代的完整系统由三部分构成,理解这三者的分工是理解整个项目的基础:
(1)Kibble Server(服务端,仓库 kibble-1)
服务端是整个系统的中枢,职责包括:存储所有采集到的统计数据、提供管理 API(账户、组织、数据源的增删改查)、对外提供统计查询 API(各类图表的数据接口),以及承载 Web 前端页面。服务端只依赖 Elasticsearch 作为存储引擎——这一点与很多同类工具不同,Kibble 没有引入传统关系型数据库,所有业务数据(包括用户账户)都存放在 Elasticsearch 的多个索引中。
(2)Kibble Scanners(采集器,仓库 kibble-scanners)
采集器是一组独立运行的 Python 程序,每一种采集器对应一类数据资源:git 仓库、邮件列表、JIRA、GitHub Issues、Jenkins、Buildbot、Travis CI、Gerrit、Bugzilla、Discourse 论坛等。采集器读取配置文件,从服务端的数据库中取出"待采集的数据源清单",逐个拉取原始数据,加工成标准化的统计文档后写回存储层。采集器与服务端之间有两种协作模式:直连 Elasticsearch 的"直连模式",或通过服务端 HTTP API 中转的"代理模式"。
(3)Kibble UI(前端,kibble-1 仓库内 ui 目录)
前端是一套基于 Vue 的单页应用,通过服务端 API 拉取统计数据并渲染成柱状图、折线图、贡献者列表等可视化组件。UI 与 API 是分离的,API 可以独立于 UI 被第三方程序调用。 三个组件之间的耦合方式是这套架构最值得品味的地方:服务端与采集器只通过 Elasticsearch 的索引 schema 约定数据格式,互相不感知对方的存在——服务端不知道采集器何时运行,采集器不依赖服务端进程存活(直连模式下)。这种"以数据 schema 为契约"的松耦合让系统的每一部分都可以独立替换:采集器可以散布在多台机器并行运行,服务端可以整体停机维护而不影响已落数据,自研程序只要按 schema 写入索引就能混入统计体系。代价是 schema 演进没有强制的版本管理,这也是 1.x 到 2.0 重写的动机之一——只可惜重写未能完成,最终以 Attic 归档收场。
2.2 存储层设计
Kibble 把数据组织成一组 Elasticsearch 索引,索引名采用"前缀 + 类型"的命名方式。以初始化数据库前缀为 kibble 为例,初始化脚本会创建三十余个索引,核心的几个如下:
| 索引名 | 存放内容 |
|---|---|
| kibble_useraccount | 用户账户(含 bcrypt 哈希后的密码、权限级别) |
| kibble_uisession | Web 会话 |
| kibble_organisation | 组织 |
| kibble_source | 数据源登记信息 |
| kibble_view | 视图定义 |
| kibble_code_commit | 每一次代码提交的标准化记录 |
| kibble_code_commit_unique | 按作者去重后的提交统计 |
| kibble_code_modification | 文件修改聚合 |
| kibble_evolution | 按时间片聚合的代码量演进数据 |
| kibble_file_history | 文件级别的历史(创建时间、最后修改时间、最后作者) |
| kibble_person | 贡献者档案(邮箱、姓名聚合) |
| kibble_email / kibble_mailstats / kibble_mailtop | 邮件列表原始记录与统计 |
| kibble_issue | 缺陷/议题记录 |
| kibble_ci_build / kibble_ci_queue | CI 构建记录 |
这种设计的直接效果是:所有统计分析都可以用 Elasticsearch 的聚合(aggregation)能力完成,服务端代码本身不需要做复杂计算,API 层更多是把"查询条件的组装 + 结果的格式化"封装成 JSON 接口。代价则是强绑定 Elasticsearch 版本——Kibble 1.x 初期依赖 Elasticsearch 5.x/6.x,后来社区在仓库归档前的最后一批提交中完成了对 Elasticsearch 8 的兼容改造,这正是本次实测部署能使用 Elasticsearch 8.17.9 的原因。 把"全部数据进 Elasticsearch"放在当年与今天两个时间点上评价,结论并不相同。在 Kibble 设计的年代,这是一个务实且超前的选择:时序聚合正是 Elasticsearch 的强项,三十余个索引的划分让每类统计有独立的映射与刷新节奏,且省去了关系库到分析库之间的同步环节。放在今天看,它的短板同样清晰:账户与会话这类强一致需求的数据放进最终一致的搜索引擎,会带来实测中真实出现过的会话校验缺陷(部署篇排障实录三);无关系模型让数据字典只能靠代码注释传承;对 Elasticsearch 的版本锁定在项目退役后变成了永久性的环境冻结。学习这套设计时,把它当作"单引擎极简架构"的样本来看最有收获——它的得失都源于同一个决定。
2.3 数据流全景
一次完整的数据流转过程如下:
- 管理员通过 API(或前端页面)创建组织(organisation),为组织添加数据源(source),例如"仓库地址 file:///srv/git/kibble-full,类型 git";
- 数据源登记信息被写入 kibble_source 索引;
- 管理员在采集器所在机器上运行
kibble-scanner.py,采集器从存储层读出该组织的全部数据源; - 采集器按数据源类型分派给对应的扫描插件:git 类源会依次经过 git-sync(克隆/更新仓库)、git-census(解析提交日志、统计增删行数)、git-sloc(统计代码行数)、git-evolution(按月切片统计代码量演进);
- 插件产出的标准化文档批量写入对应的索引(kibble_code_commit、kibble_person、kibble_evolution 等);
- 用户打开前端或调用 API,服务端按时间窗、组织、数据源过滤聚合,返回图表数据。
三、核心概念详解
3.1 组织(Organisation)
组织是 Kibble 中数据归属与权限隔离的基本单位。每个组织有一个唯一 ID、名称、描述和管理员列表。用户账户可以属于多个组织,其中一个被标记为"默认组织"(defaultOrganisation)。统计分析时,绝大多数 API 都会以当前用户的默认组织为过滤条件——也就是说,Kibble 的数据隔离粒度是组织级的:组织 A 看不到组织 B 的任何统计。
在实测环境中,通过一次 API 调用即可创建组织(管理员权限):
curl -s -H "Cookie: kibble_session=<会话ID>" -X PUT http://127.0.0.1:8080/api/org/list \
-H "Content-Type: application/json" \
-d '{"name":"Demo Org","desc":"Local demo organisation","id":"demoorg"}'
服务端返回:
{"okay": true, "message": "Organisation created!"}
3.2 数据源(Source)
数据源是采集的对象,由"类型 + 地址"唯一定义(系统内部用 SHA-224 对 "类型-地址" 拼接串哈希生成 sourceID)。1.x 支持两大类型:git(任意 Git 仓库地址,包括本地路径与远程 URL)和 github(GitHub 仓库,可附带令牌以提升 API 配额)。每一条源记录还带有 steps 字段,记录各类扫描器最近一次运行的执行状态与时间戳,采集器据此实现"增量扫描"——例如 git-census 会在上次扫描点之后约两个月的时间窗口内做增量日志解析。
添加数据源同样通过 API 完成(需要先设置默认组织):
curl -s -H "Cookie: kibble_session=<会话ID>" -X PUT http://127.0.0.1:8080/api/sources \
-H "Content-Type: application/json" \
-d '{"sources":[{"type":"git","sourceURL":"file:///opt/kibble-full"}]}'
返回:
{"message": "Sources added/updated", "added": 1, "updated": 0}
sourceID 的生成方式(SHA-224 哈希"类型-地址"拼接串)带来一个实用性质:同一仓库以相同类型重复登记会产生相同的 sourceID,系统按"已存在则更新"处理——回显中的 added: 1 与 updated: 0 就是首次登记的形态;若先登记后重复提交同一地址,则 updated 变为 1。这个机制让"重新登记"成为幂等操作,脚本化批量登记数据源时无需先查询去重。steps 字段则把每个插件的执行痕迹写在源记录上,扫描器与运维人员都可以据此判断"哪个源最近没采成功",是采集侧可观测性的落点。
3.3 视图(View)
视图是一组数据源的具名集合,作用类似"报表的取数范围"。当一个组织接入了几十上百个仓库时,通常不会把所有仓库混在一张图里看,而是按项目组、按业务线划分视图。视图保存在 kibble_view 索引中,包含一个 sourceList 字段。统计 API 接受 view 参数,命中视图后查询条件会加上 sourceID 的范围过滤。不指定视图时,统计默认覆盖当前组织的全部数据源。
3.4 组件(Widget)
组件是前端可视化的最小单元,每种组件对应一种图表与一种统计接口,例如"提交时间序列""语言代码行数分布""贡献者 TopN""邮件列表活跃度"等。服务端维护着一份组件注册表(widgets.yaml),前端根据它渲染仪表盘。理解组件的意义在于:Kibble 的统计 API 路径与组件一一对应(如 /api/code/commits、/api/code/sloc、/api/code/evolution),第三方程序完全可以绕开前端,直接组合这些 API 自建报表。
3.5 采集器插件与扫描步骤
采集器程序启动时会枚举加载全部扫描插件(实测加载了 16 个),每个插件声明自己"接受"的数据源类型。以 git 类源为例,四个插件是流水线关系:
- git-sync:负责把源仓库同步到本地暂存目录(scratchdir),首次克隆、后续拉取更新,目录名用 sourceID 哈希避免冲突;
- git-census:解析
git log --numstat输出,为每个提交生成文档(提交哈希、作者/提交者邮箱与姓名、时间戳、插入/删除行数、变更文件列表),同时维护贡献者档案与文件历史; - git-sloc:调用外部工具 cloc 统计当前代码的语言分布(各语言的代码行、注释行、空行);
- git-evolution:从当前时间回溯,按季度切片逐次执行 cloc,生成代码量随时间演进的序列数据。
这套"同步 → 明细统计 → 即时统计 → 历史回溯"的插件编排,是 Kibble 采集器设计中最值得借鉴的部分。 借鉴价值具体体现在三个模式。其一是同步与统计分离:git-sync 只管仓库在本地暂存目录的 freshness,后续插件全部基于本地副本工作,把网络故障隔离在最前置的一环,重试成本也被压到最低。其二是明细与聚合分索引:git-census 产出提交级明细(一份提交一条文档),git-evolution 产出月度聚合(一月一条),两类数据各奔各的索引,查询端按需取用,互不干扰。其三是外部工具的进程级复用:cloc 在 git-sloc 与 git-evolution 中被反复调用,插件只是它的编排者——把专业的事交给专业工具,插件层保持薄。这三个模式在今天的采集系统(如各类 DevOps 度量平台)中依然随处可见,Kibble 是它们较早的完整实现之一。
四、实测环境中的关键验证
为了让读者对"这个系统真实可用"有直观认识,以下列出在 Ubuntu 22.04 服务器上部署后取得的几组真实数据(部署细节见本系列部署篇)。
采集结果落库量(Elasticsearch 计数接口):
kibble_code_commit: {"count":648}
kibble_code_commit_unique: {"count":648}
kibble_evolution: {"count":44}
kibble_file_history: {"count":202}
kibble_person: {"count":15}
月度提交时间序列(POST /api/code/commits,取前几个数据点):
{"date": 1504224000, "commits": 117}
{"date": 1506816000, "commits": 300}
{"date": 1509494400, "commits": 4}
{"date": 1512086400, "commits": 16}
语言代码行分布(GET /api/code/sloc,节选):
javascript: code 17312, comment 400, blank 708
python: code 16720, comment 10066, blank 3260
css: code 15996, comment 332, blank 1384
coffeescript: code 10464, comment 722, blank 1280
html: code 10018, comment 450, blank 1048
这组数据来自对一个约 668 个提交的真实 Git 仓库的全量采集,证明 Kibble 1.x 的"登记数据源 → 采集 → API 出数"完整链路在今天的 Ubuntu 22.04 + Elasticsearch 8.17.9 环境下依然可以跑通(过程中需要修复少量年代久远的代码缺陷,细节见部署篇的排障实录)。
五、常见问题(FAQ)
1. Kibble 还能下载到正式的发行包吗? 不能。Kibble 从未发布过 2.0 的二进制发行版;1.x 时代主要通过源码方式部署。进 Attic 后 archive.apache.org 上的发行目录也已不再维护。当前获取源码的途径是版本仓库:apache/kibble(2.0 重写骨架)、apache/kibble-1(1.x 完整服务端)、apache/kibble-scanners(采集器)。
2. 项目退役了,源码还能正常克隆吗? 能。进 Attic 后代码仓库转为只读归档,但仍可通过公开地址克隆。本次实测即从仓库克隆了 main 分支与 kibble-1、kibble-scanners 两个历史仓库,克隆与读取均正常。
3. Kibble 与 GrimoireLab、DevLake 这类项目分析平台是什么关系? 它们属于同一赛道,都做软件项目多源数据采集与可视化。Kibble 是较早的探索者之一,设计上强调组件化采集与 Elasticsearch 聚合;GrimoireLab(Bitergia 系)与 DevLake(Apache 孵化项目)则更活跃、数据源更丰富。研究 Kibble 的架构对理解这类系统的一般模式很有帮助。
4. main 分支的 2.0.0dev 能直接用吗?
只能体验 CLI 骨架。实测 kibble version 输出 2.0.0.dev0,kibble scanners list 输出的是 AbcScanner、XyzeScanner 两个占位名,kibble server start 直接输出 "To be implemented!"。API 服务与扫描器在 main 分支从未实现。
5. 1.x 服务端为什么只用 Elasticsearch 不用关系型数据库? 因为 Kibble 的核心负载是时序统计与聚合分析,账户、组织这类实体数据量很小,统一放进 Elasticsearch 可以让全部查询走同一套聚合引擎,减少组件依赖。实测部署时也确认了账户数据(bcrypt 哈希)就存在 kibble_useraccount 索引中。
6. 支持哪些数据源类型? 1.x 的采集器覆盖:Git 仓库(同步、提交统计、代码行统计、演进分析四件套)、GitHub Issues、JIRA、Bugzilla、Gerrit、Jenkins、Buildbot、Travis CI、Discourse 论坛、GNU Mailman 邮件列表(pipermail)、Apache Pony Mail 邮件数据(含情感分析插件)、Twitter 等 16 个插件。
7. 部署一套可用的 Kibble 需要哪些硬件与软件? 实测单机部署使用:Ubuntu 22.04、Python 3.10(系统自带即可)、Elasticsearch 8.17.9(含自带 JDK,堆内存 512MB 即可稳定运行单机索引)、cloc(git-sloc 插件的外部依赖)、git 命令行工具。小规模(几个仓库、几十万文档以内)2GB 内存即可。
8. 已有的 Kibble 部署还能升级吗? 不会再有任何版本更新。 Elasticsearch 8 兼容是归档前社区做的最后一批修补(2024 年 11 月),之后冻结。若 Elasticsearch 继续升级(如 9.x),无法保证兼容性,建议将历史部署环境一并冻结。
9. 从哪里可以查到 Kibble 的历史邮件讨论与缺陷记录? Attic 页面汇总了归档链接:dev 邮件列表归档(mail-archives.apache.org 的 kibble-dev)、commits 归档、cwiki 空间(KIBBLE),以及 Whimsy 上的董事会会议纪要,均可公开访问。
10. 修复年代久远的代码缺陷算不算违背"归档冻结"? 这取决于目的。本系列实测中为让 Kibble 跑在现代环境而做的少量修补(密码哈希的编码处理、会话校验的字节串比较等),目的限于本地研究复现,不涉及再发布。归档冻结约束的是"官方渠道不再变更",个人研究副本内的改动不受此限;但若打算把修补后的版本用于生产服务,那就同时违背了第 8 条的环境冻结建议与第 1.2 节的退役忠告,不应为之。
11. Kibble 的学习价值在今天主要体现在哪里? 三点:多源采集的插件化编排(同步、明细、聚合、回溯四段式)、以搜索索引为单一存储的极简架构样本、以及组织/源/视图三层的数据组织模型。做社区度量或工程效能平台选型时,把 Kibble 当作"最小可行架构"的参照系,能更快看清现代平台多出来的每一层复杂度分别解决了什么问题。
六、参考链接
- Apache Attic - Kibble:https://attic.apache.org/projects/kibble.html
- Kibble 官网(归档):https://kibble.apache.org/
- 主仓库(2.0 重写骨架):https://github.com/apache/kibble
- 1.x 服务端仓库:https://github.com/apache/kibble-1
- 1.x 采集器仓库:https://github.com/apache/kibble-scanners
- 退役工单 ATTIC-250:https://issues.apache.org/jira/browse/ATTIC-250
- Kibble 邮件列表归档:https://mail-archives.apache.org/mod_mbox/kibble-dev/
- 在线演示站(历史快照):https://demo.kibble.apache.org/