al-crash-report
v0.0.16
Published
AboveLand UE crash report receiver — accept direct UE CrashReportClient (DataRouter) uploads, store crash files, push Feishu cards with download buttons. (Backtrace polling archived in backup/)
Readme
al-crash-report
AboveLand 崩溃上报守护服务:定时轮询 Backtrace 中的新崩溃对象,把日志与崩溃上下文下载到本地,并向飞书群推送崩溃卡片(含日志下载按钮)。
功能
- 定时轮询:按 cron 计划(默认每 5 分钟)查询 Backtrace 时间窗口内的全部崩溃对象;
- 日志落盘:把每个崩溃对象的
AboveLand.log、CrashContext.runtime-xml等附件下载到本地fingerprints/目录; - 飞书推送:每个崩溃对象一张卡片,展示 Fingerprint、Object ID(十进制)、Classifiers、崩溃时间和错误信息,附三个下载按钮(zip 打包 / AboveLand.log / CrashContext.runtime-xml);
- 去重与补推:对象级推送标记文件保证不重复推送;单轮限量推送,积压对象在后续轮次自动补推;
- HTTP 文件服务:内置 Express 服务,供卡片按钮下载已落盘的日志文件。
安装
npm install -g al-crash-report使用
在工作目录(存放 .env 和 fingerprints/ 数据的目录)下执行:
al-crash-report run # 前台启动(Ctrl+C 停止)
al-crash-report start # 后台守护进程启动
al-crash-report stop # 停止后台进程
al-crash-report status # 查看运行状态后台模式的 PID 与日志写在当前目录:.al-crash-report.pid、.al-crash-report.log,多项目可用不同目录隔离。
配置(.env)
启动时自动读取当前目录下的 .env:
# Backtrace 访问
BACKTRACE_BASE_URL=https://your-instance.sp.backtrace.io
[email protected]
BACKTRACE_PASSWORD=your-password
BACKTRACE_PROJECT=AboveLand
# 飞书推送
FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxxx
# 卡片下载按钮指向的本服务地址(外网/内网可访问的地址)
BACKTRACE_CONSOLE_URL=http://your-host:3000
# HTTP 服务端口(默认 3000)
PORT=3000可选项:
| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| SCHEDULER_CRON | */5 * * * * | 轮询计划(node-cron 表达式) |
| SCHEDULER_INGEST_LOOKBACK | 900 | 入库延迟补偿(秒):每轮从上次截止时间再往前回看这么久,避免晚上传的崩溃被漏掉 |
| FEISHU_MAX_PUSH_PER_RUN | 10 | 单轮最多推送的卡片数,超出部分下轮补推 |
| BACKTRACE_PROXY | 空 | 访问 Backtrace 使用的 HTTP 代理 |
| BACKTRACE_LIMIT | 20 | 查询分页基准大小 |
| BACKTRACE_DOWNLOAD_CONCURRENCY | 4 | 附件下载并发数 |
| BACKTRACE_RETRIES | 0 | 附件下载失败重试次数 |
工作机制
- 时间窗口:窗口起点为上次全部推送成功的截止时间(记录在
fingerprints/.scheduler-state.json)再往前回看SCHEDULER_INGEST_LOOKBACK(默认 15 分钟),补偿崩溃对象从发生到上传入库的延迟。首次运行回看 1 小时;长时间停机后窗口最多截断到 24 小时。 - 查询:先按 fingerprint 分组列出窗口内的崩溃指纹,再逐指纹拉取全部崩溃对象。
- 推送:按崩溃时间升序逐对象推送飞书卡片,推送前先下载日志。推送成功后写入标记文件
fingerprints/<fp>/logs/<objectId>/.feishu-notified.json。 - 窗口推进:仅当本轮没有推送失败且没有限量积压时窗口才前进,否则下轮从原起点重查(标记文件负责去重)。
HTTP 接口
| 接口 | 说明 |
| --- | --- |
| GET /healthz | 健康检查 |
| POST /crash(别名 POST /api/crash/upload) | UE CrashReportClient 直传入口(DataRouter 协议) |
| POST /feedback(别名 POST /api/feedback/upload) | 启动器 Bug 反馈入口,见下 |
| GET /api/feedback/files/archive?date=&id= | 将反馈目录打包为 zip 下载 |
| GET /api/feedback/files/file?date=&id=&file= | 下载反馈目录内的单个文件;加 &inline=1 在浏览器内联打开(截图直接显示) |
| GET /api/backtrace/files/object-archive?fingerprint=&object= | 将崩溃对象目录打包为 zip 下载 |
| GET /api/backtrace/files/object-file?fingerprint=&object=&file= | 下载对象目录内的单个文件(如 AboveLand.log、CrashContext.runtime-xml);加 &inline=1 改为在浏览器内联打开 |
玩家反馈(POST /feedback)
启动器以 multipart/form-data 提交(客户端超时 120 秒):
- 文本字段:
title(必填,≤80 字符)、description(必填,≤2000 字符)、contact(可选)、meta(JSON 字符串,环境信息:launcher_version / os / account / game_id / game_name / game_version / remote_version / game_state / install_dir); - 文件字段:
logs(0 或 1 个,固定名logs.zip,完整游戏日志)、screenshot(0~3 张图片,单张 ≤20 MB,服务端统一改名screenshot-N.<ext>,原始文件名记入report.json); - 成功回 2xx;失败回非 2xx + 简短纯文本(响应体前 512 字节会显示给玩家);
- meta 解析失败不拒收(原文存入
report.json的meta._raw); - 按来源 IP 限流 10 次/分钟(
FEEDBACK_RATE_LIMIT可调),超出回 429; - 收到反馈后向飞书群推送卡片(标题、提交人、环境信息、存储路径、来源 IP + 下载/查看按钮)。
落盘结构:
feedback/
└── <YYYY-MM-DD>/
└── fb-<时间戳>-<随机>/
├── report.json # title/description/contact/meta + 提交时间 + 来源 IP
├── logs.zip
└── screenshot-1.png数据目录
fingerprints/
├── .scheduler-state.json # 调度窗口状态
└── <fingerprint>/
└── logs/
└── <objectIdHex>/
├── AboveLand.log
├── CrashContext.runtime-xml
└── .feishu-notified.json # 推送标记(不参与打包下载)License
Private / internal use.
