OneUptime CLI 脚本化与 CI/CD 集成指南:环境变量、退出码与 JSON 自动化实战
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
OneUptime 是一个开源的监控与可观测性平台,其官方 CLI(@oneuptime/cli)在设计之初就面向自动化场景:支持基于环境变量的免登录认证、面向程序化分析的 JSON 输出,以及可直接在流水线中使用的退出码。本文以 CLI 脚本化与 CI/CD 官方文档 为骨架,结合仓库内 CLI 的源码实现,完整讲解如何把 OneUptime CLI 接入 GitHub Actions、通用 CI 脚本与 Docker 容器,实现监控资源(Monitors)、事件(Incidents)等对象创建、查询、统计的端到端自动化。读完本文,你将掌握一套可直接复制运行的无状态脚本方案,理解 CLI 凭据解析、退出码映射与输出格式背后的底层原理。
一、面向自动化的 CLI 设计:无状态、可解析、可判断
与交互式终端使用不同,脚本与流水线对 CLI 有三大硬性要求:无需人工保存会话即可认证、输出能被机器解析、失败能被程序捕获。OneUptime CLI 正是围绕这三点设计的:
- 认证:通过环境变量注入 API Key 与实例地址,不依赖保存在本机的交互上下文;
- 输出:通过
-o json产出合法的 JSON,可直接交给jq等工具处理; - 退出码:通过规范化的退出码区分「成功」「一般错误」「认证失败」「资源不存在」等状态,供
if、set -e等脚本逻辑判断。
从源码看,CLI 的入口 CLI/Index.ts 注册了--api-key、--url、--context、-o/--output、--no-color等全局选项;资源类命令则在 CLI/Commands/ResourceCommands.ts 中根据 OneUptime 数据库模型(model.enableMCP)自动发现并注册,每个资源统一支持list、get、create、update、delete、count子命令——这意味着本文的所有自动化技巧适用于 Incident、Monitor、Alert、Status Page、Team 等所有 MCP 启用的资源类型。
二、环境变量认证:让凭据与代码分离
脚本中不应硬编码 API Key。OneUptime CLI 支持通过两个环境变量完成认证,无需执行oneuptime login或保存任何上下文文件:
export ONEUPTIME_API_KEY=sk-your-api-key export ONEUPTIME_URL=https://oneuptime.com需要说明的是,CLI 的凭据解析遵循一套明确的优先级顺序,这一点在 CLI/Core/ConfigManager.ts 的getResolvedCredentials函数中有完整实现,从高到低依次为:
- CLI 标志:
--api-key <key>与--url <url>(同时提供时优先级最高); - 环境变量:
ONEUPTIME_API_KEY与ONEUPTIME_URL(两者同时存在时生效); --context <name>指定的命名上下文(指向~/.oneuptime/config.json中的某个上下文);- 配置文件中的当前上下文(
oneuptime login保存的默认上下文)。
官方文档的表述与源码完全一致:环境变量「优先于已保存的上下文(contexts),但会被 CLI 标志覆盖」。对应行为已被 CLI/Tests/ConfigManager.test.ts 中的多个测试用例锁定,例如should resolve from env vars when CLI options are missing验证环境变量生效,should prefer CLI flags over env vars验证 CLI 标志覆盖环境变量。
两点实战提示:
- 环境变量同时缺失 API Key 与 URL 时,CLI 会抛出
No credentials found. Run oneuptime login or set ONEUPTIME_API_KEY and ONEUPTIME_URL environment variables.(ConfigManager.ts),并最终以认证错误退出码2结束; - 配置文件的 API Key 以
0600权限写入~/.oneuptime/config.json(ConfigManager.ts),而环境变量方案在 CI 中通常由 Secrets 管理,二者场景不同但可互补。
三、退出码:让流水线能「听懂」失败
CLI 的所有退出码定义集中在 CLI/Core/ErrorHandler.ts,与文档表格完全对应:
| 退出码 | 含义 | 触发场景(源码依据) |
|---|---|---|
0 | 成功 | 命令正常完成 |
1 | 一般错误 | 非认证、非 404 的其他异常(ErrorHandler.ts) |
2 | 认证错误(凭据缺失或无效) | 错误消息包含API key、credentials、Unauthorized或401(ErrorHandler.ts) |
3 | 未找到(404) | 错误消息包含404或not found(ErrorHandler.ts) |
值得注意:即使没有显式使用
--query,count子命令输出的就是纯数字(ResourceCommands.ts),这使它天然适合直接参与脚本中的数值比较。
在脚本中用退出码做错误处理是文档给出的标准姿势:
if ! oneuptime monitor list > /dev/null 2>&1; then echo "Failed to list monitors" exit 1 fi> /dev/null 2>&1丢弃了正常输出与错误输出,只保留退出码作为判断依据。若要更精细地区分失败原因,可以单独检查$?:
oneuptime monitor get 550e8400-e29b-41d4-a716-446655440000 > /dev/null 2>&1 code=$? if [ "$code" -eq 3 ]; then echo "Monitor not found, creating it now..." fi四、JSON 输出与 jq:机器可读的二次加工
-o json让所有资源命令返回结构化 JSON。官方文档给出了三个高频用法,此处完整保留并补充说明:
# 提取所有 incident 的标题 oneuptime incident list -o json | jq '.[].title' # 获取刚创建的 monitor 的 _id,供后续命令引用 NEW_ID=$(oneuptime monitor create --data '{"name":"API Health"}' -o json | jq -r '._id') echo "Created monitor: $NEW_ID" # 按 severity 统计 incident 数量 oneuptime incident count --query '{"incidentSeverityId":"<severity-id>"}'源码层面,CLI/Core/OutputFormatter.ts 的detectOutputFormat有一个容易被忽略的细节:当 stdout 不是 TTY(即被管道或重定向)时,即使不写-o json也会自动默认输出 JSON。也就是说,oneuptime incident list | jq '.[].title'与显式加-o json效果相同(这一点在 CLI/README.md 中也有说明)。不过为了脚本可读性,建议始终显式声明-o json。
输出格式还包括table(默认表格,适合 TTY 终端)与wide(展示全部列),由 OutputFormatter.ts 实现;非 wide 模式下表格会优先展示_id、name、title、status、createdAt、updatedAt等核心列,并做 60 字符截断以保持可读性。
关于--query的补充:list与count的查询条件以 JSON 字符串传入,底层在 ResourceCommands.ts 中通过JSON.parse解析后,与select、skip、limit、sort一起打包进 API 请求(buildRequestData,见 CLI/Core/ApiClient.ts)。list默认limit=10、skip=0,需要更多数据时请显式指定--limit。
五、从文件创建资源:让基础设施可版本化
把资源定义写进 JSON 文件并纳入 Git 管理,是实现「基础设施即代码」的基础做法。CLI 的create子命令同时支持--data(内联 JSON)与--file(从文件读取)两种方式(ResourceCommands.ts):
# monitor.json # { # "name": "API Health Check", # "projectId": "your-project-id" # } oneuptime monitor create --file monitor.json源码逻辑(ResourceCommands.ts)表明:当传入--file时,CLI 用fs.readFileSync读取文件内容并JSON.parse;若既无--file也无--data,则抛出Either --data or --file is required for create.。因此这两者必须二选一。同理,update子命令使用--data传入要修改的字段:
oneuptime monitor update "$MONITOR_ID" --data '{"name":"API Health (v2)"}'六、批量操作:循环处理多个资源
文档给出的批量创建模式是「数组文件 + jq 逐条展开 + while 循环」:
# 从 JSON 数组文件批量创建 monitor cat monitors.json | jq -r '.[] | @json' | while read monitor; do oneuptime monitor create --data "$monitor" donejq -r '.[] | @json'的作用是将数组中的每个对象序列化为一行紧凑 JSON,while read逐行消费。需要注意:默认循环内某条创建失败不会中断整体(while不会因内部命令非零而停止),如果需要「失败即停止」,可改为while read monitor; do ... || exit 1; done或给整个管道加上set -o pipefail(详见第七节的通用脚本示例)。
批量操作同样适用于查询场景,例如批量提取所有 monitor 名称并逐一检查状态:
oneuptime monitor list -o json --limit 100 | jq -r '.[]._id' | while read id; do oneuptime monitor get "$id" -o json | jq -r '.name + " -> " + (.status // "unknown")' done七、CI/CD 流水线实战
7.1 GitHub Actions:定时巡检活跃 Incident
官方文档给出的示例是一个每 5 分钟触发一次的定时任务,将环境变量交给 Secrets 管理,用incident count判断是否存在活跃事件:
name: Check Active Incidents on: schedule: - cron: "*/5 * * * *" jobs: health-check: runs-on: ubuntu-latest steps: - name: Install OneUptime CLI run: npm install -g @oneuptime/cli - name: Check for active incidents env: ONEUPTIME_API_KEY: ${{ secrets.ONEUPTIME_API_KEY }} ONEUPTIME_URL: https://oneuptime.com run: | INCIDENT_COUNT=$(oneuptime incident count) if [ "$INCIDENT_COUNT" -gt 0 ]; then echo "WARNING: $INCIDENT_COUNT incidents found" exit 1 fi要点拆解:
ONEUPTIME_API_KEY与ONEUPTIME_URL通过env:注入,配合文档第二节的优先级规则,无需任何login步骤即可完成认证;oneuptime incident count默认统计全部 incident,如需限定范围可追加--query(例如--query '{"currentIncidentStateId":"<investigating-id>"}');- 计数大于 0 时显式
exit 1,让整个 Job 失败,从而触发 GitHub Actions 的通知/告警机制。
7.2 通用 CI 脚本:部署期间创建并关闭 Incident
官方文档提供的 bash 示例展示了「部署开始 → 记录事件 → 部署成功 → 解决事件」的完整生命周期,这是把 OneUptime 与发布流水线打通的典型模式:
#!/bin/bash set -e export ONEUPTIME_API_KEY="$CI_ONEUPTIME_API_KEY" export ONEUPTIME_URL="$CI_ONEUPTIME_URL" # 创建 deployment incident 并捕获其 ID # 注意:currentIncidentStateId 与 incidentSeverityId 必须引用你项目中已存在的状态/严重级别 ID INCIDENT_ID=$(oneuptime incident create --data '{ "title": "Deployment Started", "currentIncidentStateId": "'"$INVESTIGATING_STATE_ID"'", "incidentSeverityId": "'"$SEVERITY_ID"'", "declaredAt": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'" }' -o json | jq -r '._id') # 在此执行部署步骤... # 部署成功后解决该 incident oneuptime incident update "$INCIDENT_ID" --data '{"currentIncidentStateId":"'"$RESOLVED_STATE_ID"'"}'三个技术细节值得展开:
set -e:任一命令失败立即退出脚本,防止部署流程在告警未记录的情况下继续;declareAt时间戳:$(date -u +%Y-%m-%dT%H:%M:%SZ)生成 UTC 的 ISO 8601 时间;由于外层用单引号包裹 JSON、内层用"'"$VAR"'"把 shell 变量插入到 JSON 字符串中,注意$INCIDENT_ID等变量在引号内会被正确展开;-o json | jq -r '._id':create返回的新资源对象通过jq提取_id供后续update复用,这与第四节中「创建后立即捕获 ID」的思路一脉相承。
7.3 Docker:把 CLI 打包成一次性任务镜像
将 CLI 打包进镜像,可以让监控检查作为 Kubernetes Job、CronJob 或 docker run 一次性容器运行。官方 Dockerfile 如下:
FROM node:26-slim RUN npm install -g @oneuptime/cli ENV ONEUPTIME_API_KEY="" ENV ONEUPTIME_URL="" ENTRYPOINT ["oneuptime"]运行方式(--rm表示容器执行完即删除,凭据通过-e注入而非写入镜像):
docker run --rm \ -e ONEUPTIME_API_KEY=sk-abc123 \ -e ONEUPTIME_URL=https://oneuptime.com \ oneuptime-cli incident list安全提示:不要把真实 Key 写进ENV指令(镜像会被固化),运行时通过-e、--env-file或容器编排系统的 Secret 机制注入才是正确做法。若需要向镜像内传入其他参数,可在镜像名后追加子命令,例如oneuptime-cli monitor count。
八、脚本中指定上下文:多环境并存时的精确控制
当本机通过oneuptime login保存了多个上下文(例如production与staging)时,可以通过--context全局选项在单条命令中精确指向某个环境,而不必先执行context use切换:
oneuptime --context production incident list oneuptime --context staging monitor count源码中--context的优先级位于 CLI 标志、环境变量之后(ConfigManager.ts):即显式的--api-key/--url或环境变量存在时优先采用,否则才按--context查找~/.oneuptime/config.json中对应的上下文;若引用了不存在的上下文名,CLI 会抛出Context "xxx" does not exist.。
这一特性在脚本中的典型用法是「同一套脚本、多环境巡检」:
for ctx in production staging development; do count=$(oneuptime --context "$ctx" incident count) echo "$ctx: $count active incidents" done九、小结:从脚本到平台的完整闭环
把上述能力串联起来,就得到了一条完整的「监控 + 发布 + 告警」自动化链路:
- 认证:
ONEUPTIME_API_KEY/ONEUPTIME_URL环境变量(或--context)保证脚本无状态、凭据不进代码; - 创建:
--file从版本库读取资源定义,--data支持内联 JSON,配合-o json与jq捕获新资源 ID; - 查询与统计:
list/count配合--query、--limit、--sort做过滤与分页; - 失败处理:规范化的退出码(0/1/2/3)让 GitHub Actions、bash 脚本与容器化任务都能精确区分「成功、一般错误、认证失败、资源不存在」;
- 生命周期管理:部署前创建 incident、部署后 update 状态,把每一次发布都沉淀为可审计的监控事件。
如果想深入掌握 CLI 的更多命令,可以查阅 CLI/README.md 的完整命令参考;CLI 的自动化能力建立在 OneUptime 平台统一的 CRUD API 之上,其请求构造细节可继续研读 CLI/Core/ApiClient.ts,而凭据解析与退出码的边界行为均有测试用例佐证,见 CLI/Tests/ConfigManager.test.ts 与 CLI/Tests/ErrorHandler.test.ts。
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考