报告输出与查看器
基本信息
| 属性 | 值 |
|---|---|
| 查看器 | https://spark.lucko.me/(viewerUrl 默认值,SparkPlatform.java:126) |
| 上传端点 | https://spark-usercontent.lucko.me/(bytebinUrl,SparkPlatform.java:127) |
| 实时通道 | spark-usersockets.lucko.me(bytesocksHost,SparkPlatform.java:128) |
| 客户端标识 | spark-plugin(三个客户端构造时统一传入) |
| 产物类型 | sparkprofile(采样)、sparkheap(堆摘要) |
spark 没有内置 GUI:结果通过聊天框里的可点击 URL 交给外部 Web 查看器渲染。
穷举 IGuiHandler / GuiScreen / IGuiOverlay / RenderGameOverlayEvent / new GuiButton 在 spark-forge1710 与 spark-common 下的命中为 0 —— 不存在任何自绘界面、overlay 或容器 GUI。
两个端点的分工
| 端点 | 配置键 | 用途 | 典型命令 |
|---|---|---|---|
| bytebin(HTTP 上传) | bytebinUrl |
一次性 POST 完整结果,返回 key,拼成报告链接 | profiler stop、heapsummary |
| bytesocks(socket) | bytesocksHost |
长连接实时推送采样流 | profiler open |
链接构造方式统一为 platform.getViewerUrl() + key(key 由 bytebin 返回)。
客户端构造时都以字符串 "spark-plugin" 作为标识传入(new BytebinClient(bytebinUrl, "spark-plugin")、LegacyBytesocksClientFactory.newClient(bytesocksHost, "spark-plugin"))。
两条输出路径
每份报告在生成后都面临「上传还是存盘」的选择,代码结构一致(SamplerModule.handleUpload 与 HeapAnalysisModule.heapSummary):
| 命令 | 默认行为 | 带 --save-to-file |
上传失败 |
|---|---|---|---|
| /spark profiler | 上传 | 存 .sparkprofile |
自动回退存盘 |
| /spark heapsummary | 上传 | 存 .sparkheap |
自动回退存盘 |
| /spark heapdump | 存盘(不上传) | 不适用 | 不适用 |
profiler 的失败回退逻辑原文:「An error occurred whilst uploading the results. Attempting to save to disk instead.」,异常堆栈同时打到控制台。
heapdump 是唯一默认不上传的 —— 完整 .hprof 体积过大,不适合走公网。
实时查看器与信任链
/spark profiler open 走 bytesocks 建立 ViewerSocket,采样数据边采边推。
未信任的查看器客户端发起连接时,spark 会生成一个待确认的 client id。管理员需执行:
/spark profiler trust-viewer --id <client id>
该 id 经 TrustedKeyStore.trustPendingKey 校验,成功则:
- 公钥写入
config.json的trustedKeys(TrustedKeyStore.setStringList) - 向采样器上所有已连接的 socket 广播信任消息(
socket.sendClientTrustedMessage(id)) - 回复「Client connected to the viewer using id ‘<id>’ is now trusted.」
失败(id 不存在)回复「Unable to find pending client with id ‘<id>’.」;未传 --id 回复「Please provide a client id with ‘–id <client id>’.」。
trustedKeys 是 config.json 中唯一的列表型配置项(getStringList),独立于 getString 的序列化分支。
报告内嵌元数据
Sampler.ExportProps(SamplerModule.getExportProps)决定写入报告的元数据:
| 字段 | 来源 |
|---|---|
creator |
resp.sender().toData() —— 发起命令的发送者 |
comment |
--comment 参数(可多次传,取第一个) |
| 合并模式 | 默认 MergeMode.sameMethod(methodDisambiguator);--separate-parent-calls 切为 separateParentCalls |
| class 源映射 | ClassSourceLookup.create(platform) |
creator 字段让每份报告自带发起人 —— 多人服务器上这是判断「这条卡顿是谁触发的」的第一手信息,与 /spark activity 的记录互为印证。
1.7.10 的消息渲染限制
报告链接以 ClickEvent.openUrl(url) 挂可点击事件。但在 1.7.10 上,Adventure 组件含 \n 时客户端渲染异常,因此 Forge1710CommandSender.sendMessage 先整体序列化为字符串再按行拆分逐条发送(Forge1710CommandSender.java:64-80)。源码注释明确标注这是为旧客户端做的妥协,并注明会增加性能开销。
数值
| 数值名 | 值 | 来源 |
|---|---|---|
| 查看器默认地址 | https://spark.lucko.me/ |
SparkPlatform.java:126 |
| bytebin 默认地址 | https://spark-usercontent.lucko.me/ |
SparkPlatform.java:127 |
| bytesocks 默认主机 | spark-usersockets.lucko.me |
SparkPlatform.java:128 |
| 采样报告扩展名 | sparkprofile |
resolveSaveFile("profile", "sparkprofile") |
| 堆摘要扩展名 | sparkheap |
resolveSaveFile("heapsummary", "sparkheap") |
| 内置 GUI 数量 | 0 | 穷举 GuiScreen/IGuiHandler/overlay 0 命中 |
| 外部文档链接 | https://spark.lucko.me/docs/Command-Usage |
SparkPlatform.sendUsage |
相关条目
- /spark profiler - 采样与上传的主入口
- /spark activity - 报告发起人的追溯入口
- config.json 配置项 - 3 个端点键与
trustedKeys - 配置目录文件 - 存盘路径的落盘规则