- 可观测性
- 后端
- 运维
- 前端
- 云原生
- 微服务
- AI Agent
【免费下载链接】oneuptime
Complete open-source monitoring and observability platform.
在 OneUptime 中,每当你创建并触发一个工作流(Workflow),平台都会完整记录这次执行的全部经过——何时运行、是否成功、每个节点(块/组件)做了什么。这份记录被称作一次运行(Run)。运行记录既是确认工作流正常工作的依据,也是排查失败工作流、回溯历史活动的唯一入口。本文基于 OneUptime 官方文档体系中的 Runs & Logs 章节(源文档位于 packages/App/FeatureSet/Docs/Content/en/workflows/runs-and-logs.md),结合仓库内的工作流引擎源码,系统讲解运行记录在哪里找、每种状态意味着什么、如何阅读一次运行的详细日志,以及常见故障的标准排查流程。
在哪里找到运行记录
OneUptime 提供了三个查看运行记录的入口,它们展示的范围和过滤维度各不相同:
| 页面位置 | 你能看到的内容 |
|---|---|
| Workflows → Runs & Logs(项目级) | 项目中所有工作流的全部运行记录。支持按工作流名称、状态和时间进行过滤。 |
| Workflow → Runs & Logs(单工作流级) | 仅当前这一个工作流的运行记录。与项目级页面不同,这里没有工作流过滤器,取而代之的是一个Run ID过滤器。 |
| 单次运行详情 | 通过某行运行记录上的View Logs按钮打开——注意,运行记录的行本身是不可点击的,必须点击按钮才能进入详情。 |
从数据模型角度看,每条运行记录都对应数据库中的一行WorkflowLog。在 WorkflowLog 模型 中可以看到它保存了运行的核心字段:logs(原始日志文本)、workflowStatus(运行状态)、startedAt/completedAt(起止时间)、resumeAt(Sleep 节点后的恢复时间)以及stepTrace(结构化步骤追踪)。其中@Index(["workflowStatus", "createdAt"])注解表明,平台会按状态与创建时间索引这些记录,以支持后台定期扫描超时或卡住(Scheduled)的运行——这与后文将要讲到的超时与 5 分钟未领取即失败的行为直接相关。
运行状态全解读
每一次运行都会经历若干状态,理解每个状态的含义是排查问题的第一步。OneUptime 对运行状态的定义如下:
| 状态 | 含义 |
|---|---|
| Scheduled | 触发器已触发,运行已进入执行器(runner)的队列等待执行。通常只持续不到一秒。如果一次运行在5 分钟后仍处于 Scheduled 状态,说明没有任何执行器认领它,这次运行会被判定为失败。 |
| Running | 工作流正在执行中。包含长时间运行节点的块会让运行一直停留在这个状态。 |
| Waiting | 运行因遇到Sleep节点而暂时挂起,之后会自动恢复。处于等待期间它不会占用任何 worker 资源。 |
| Executed | 运行顺利执行到结束、没有发生失败。这是成功状态——状态标签上写的就是Executed而不是 "Success"。 |
| Error | 运行因某个块抛出错误而中止。此外,以下情况也会进入 Error 状态:排队中的运行一直未被认领、Sleep 挂起的运行丢失了恢复调度、时间表达式无法解析、或者工作流在运行中途被停用。 |
| Timeout | 运行耗时超过了允许的上限。具体超时配置与安全相关设置请参考配置与安全。 |
| Execution Exceeded Current Plan | 项目在最近 30 天内已用尽工作流运行配额,或订阅处于未付费状态。此时运行会被记录但不会真正执行。该状态仅存在于 OneUptime Cloud。 |
重要细节:如果某个块把执行流转交到了它的Error输出端口——例如一个 API 节点遇到 4xx 响应——这不会导致整次运行失败。错误分支会被正常执行,运行最终仍以Executed结束。不过该步骤本身在可视化视图上仍会用红色标出,方便你快速定位。
状态枚举的源码印证
打开 WorkflowStatus 枚举 可以看到,引擎内部对状态的建模与文档表格完全对应:
enum WorkflowStatus { Scheduled = "Scheduled", Running = "Running", Waiting = "Waiting", Success = "Success", Error = "Error", Timeout = "Timeout", WorkflowCountExceeded = "Workflow Count Exceeded", }值得注意的是,引擎枚举中的成功态写的是Success,而界面展示给用户的标签是Executed,两者指向同一个语义状态。此外,"Execution Exceeded Current Plan" 对应的枚举值是WorkflowCountExceeded。在 QueueWorkflow 队列服务 中可以找到它的判定逻辑:当workflowCount表明该项目"最近 30 天内已经运行了超过计划限额的次数"时,就会写入WorkflowCountExceeded状态,并在日志中明确写出当前计数与计划上限。
状态机如何写入日志
在 RunWorkflow 运行服务 中可以看到状态流转的实际写入点:运行入队时写入WorkflowStatus.Scheduled(第 401 行),遇到 Sleep 节点挂起时写入WorkflowStatus.Waiting并记录恢复时间(第 791 行),正常结束时写入WorkflowStatus.Success(第 694 行),超时写入WorkflowStatus.Timeout(第 720 行),出错则写入WorkflowStatus.Error(第 733 行)。每一次状态变更都会重写一次WorkflowLog行——这也是为什么一次长时间运行会留下完整的状态演进轨迹。
如何阅读一次运行
点击某次运行的View Logs按钮即可打开详情。Workflow Run视图包含两个标签页,分别对应两种粒度完全不同的信息。
Steps 标签页:结构化步骤追踪
Steps视图为每一个实际执行过的块生成一行记录,按执行顺序排列。每一行展示:块的标题、它的组件 ID(component id)、耗时,以及它最终走出的输出端口(显示为→ success、→ error或→ yes等)。展开某一行,可以看到两个详细区块:
- Received—— 块实际收到的设置参数,此时所有变量都已完成解析替换。
- Returned—— 块实际产生的输出。
执行失败的步骤会以红色显示,并且默认展开,错误消息打印在Received区块上方,让你一眼看到失败原因。
Full Log 标签页:原始执行日志
Full Log展示执行器打印的逐行原始日志,其中包含块自身输出的所有内容。当 Steps 视图不足以解释失败原因时,切换到 Full Log 查看底层日志是标准做法。
三个值得掌握的细节
组件 ID 就是变量引用键。每个步骤标题下方印出的组件 ID,正是你需要在
{{local.components.<id>.returnValues.…}}引用中填写的字符串。因此 Steps 视图也是快速获得正确引用写法的最快途径——直接照抄页面上的 ID 即可。每次运行只保留最近 100 个步骤。如果一次运行很长、或经过多次 Sleep 挂起恢复,较早的步骤会被丢弃,并在原位置显示一条琥珀色提示,而不是静默地展示不完整的运行。这一限制在 StepTrace.ts 中以常量形式定义:
MAX_TRACE_STEPS: number = 100。其实现逻辑appendTraceStep(StepTrace.ts)在步骤数超过上限时丢弃最旧的步骤并置truncated标记——因为一个失败运行的读取习惯是从末尾往前读,导致失败的那一步永远会保留。敏感值与超长值会被脱敏/截断。Steps 中展示的值是变量填充后块实际看到的内容,但有两条例外:一是密钥(secrets)以及块标记为敏感(sensitive)的字段会被移除;二是非常长的值会被截断,并以
… (truncated)结尾。截断阈值定义在同文件中的MAX_TRACE_VALUE_LENGTH: number = 4000(StepTrace.ts),truncateTraceValue函数(StepTrace.ts)对字符串直接截断,而对结构化对象先序列化成 JSON 再按长度判断——因为把序列化对象拦腰截断会产生"看似数据却无法解析"的文本。
敏感信息脱敏的源码实现
关于脱敏,RunWorkflow.ts 中的redactSensitiveComponentValuesForLogs函数会依据组件元数据(Argument/ReturnValue上的isSensitive标记)把对应字段替换为WORKFLOW_LOG_REDACTED_VALUE(即[REDACTED])。真正的值仍会在运行时传给组件,只是不落入日志。此外,SecretRedaction.ts 中的redactSecretsFromString会递归地扫描整个结构化追踪数据,把工作流变量中的密钥内容替换掉——包括 JSON 的键名也要脱敏(密钥可能被替换进 HTTP 头名称等位置),并且对重叠的密钥按"长者优先"排序替换,防止短密钥先被替换而暴露长密钥的尾巴。
另外,从 Builder 手动启动一次运行时会直接打开这个视图并自动跟随运行(following),因此你可以实时观看执行过程,而不必等它结束后再去找记录。
常见故障排查
"我的工作流没有运行。"
按以下顺序排查:
- 确认工作流在其Overview页面处于Enabled状态。新建的工作流默认是停用状态,而停用的工作流会拒绝一切运行——包括手动运行。
- 对于 OneUptime 事件触发器:确认事件确实发生了。打开对应记录并检查其历史。
- 对于 Webhook 触发器:确认外部系统向正确的 URL 发送请求。大多数工具在发送 webhook 时都会记录日志,去那里查看即可。
- 对于定时触发器:确认 cron 表达式与你期望的时间一致。
如果运行确实出现了,但状态是Execution Exceeded Current Plan,说明项目已用尽最近 30 天的工作流运行配额,或订阅未付费。该次运行的日志会写明你的执行计数和计划上限。这一状态仅适用于 OneUptime Cloud。
"后面的块一直没有执行。"
一个块没有运行通常是接线(wiring)问题。打开Builder检查:
- 前一个块的输出是否连接到了这个块的输入?
- 前一个块是否走出了与你预期不同的输出端口——比如走出了Error而不是Success,或No而不是Yes?Steps 标签页会明确显示它实际走了哪个端口。
"某个变量传过来是空的。"
打开运行详情,查看失败步骤的Received区块:
- 如果你看到的是字面文本
{{local.components.…}},说明引用没有被解析。通常是在组件 ID 或返回值 ID 上拼写错误——注意这里要用块的Identifier,而不是界面上显示的名称。同时检查local.components本身的拼写:例如{{local.componets.api-get-1.returnValues.response-body}}会以字面文本原样发送,而运行仍然会报告Executed。 - 如果你看到的是空字符串,说明前一个块确实执行了,但没有产出这个字段。
Full Log标签页中会有一条警告行,列出所有未解析的引用名称,这通常是最快的定位方式。
"手动运行正常,但从触发器触发就不行。"
打开Builder,点击Run Workflow,用与真实触发器发送内容相近的值填充触发器的字段。然后把这次运行的Received值与真实运行的 Received 值并排对比。差异通常只是某个字段名或字段类型不一致。
关于重新运行(Retry)的设计取舍
OneUptime没有提供"重试这次运行"的按钮,也不会自动重跑旧执行。原因在于工作流的副作用——Slack 消息、API 调用、工单创建——可能无法安全地重复执行。如果要重做某次任务,正确做法是:修复工作流本身,等待下一次真实触发器触发它;或者打开Builder手动点击Run Workflow,用相同参数值重新执行一次。
这一设计在 RunStep API 的注释中也能看到印证:产品中不存在"安全"或"只读"的组件概念,注册表里大约一半的组件会发送消息、调用任意 URL、或对数据行做增删改,而且这些操作事后都不会被撤销。因此"单独运行某个步骤"也不是在 API 进程里直接执行组件,而是入队一次缩小到单步的普通运行,从而完整继承工作流的所有既有保障:必须启用、订阅有效、受项目计划运行限额约束、写入 WorkflowLog 审计记录、在独立 worker 而非 API 进程中执行、日志与返回值按既有规则脱敏。
运行记录保留多长时间?
- 在OneUptime Cloud上,运行记录保留30 天后即被删除——这也是为什么两个运行列表都声称自己覆盖"最近 30 天"。
- 自托管(Self-hosted)安装会一直保留运行记录,直到你手动删除。如果某个工作流执行过于频繁、让你的历史记录变得杂乱,建议停用或删除它,避免继续产生噪音。
另外补充一点:在步骤追踪(step tracing)功能引入之前记录下来的运行没有Steps内容,只会显示Full Log。这一兼容性处理在 StepTrace.ts 的 parseTrace 函数 中有明确实现——旧行读取时绝不会抛错,无法解析的追踪会读作空追踪,视图自动回退到原始日志。
延伸阅读
- 配置与安全 —— 超时设置、递归限制、隐藏密钥。
- 变量 —— 在你的块中使用变量时的完整语法。
- 组件 —— 每个块具体能产出什么。
- 可观测性
- 后端
- 运维
- 前端
- 云原生
- 微服务
- AI Agent
【免费下载链接】oneuptime
Complete open-source monitoring and observability platform.
相关推荐
OneUptime 工作流运行与日志(Runs & Logs)完全指南:状态解析、步骤追踪与故障排查
OneUptime 工作流运行与日志(Runs & Logs)完全指南:状态解析、步骤追踪与故障排查 本文围绕 OneUptime 开源可观测平台的 Workf
可观测性后端运维前端云原生微服务AI AgentOneUptime 工作流运行与日志(Runs & Logs)完全指南:状态语义、执行追踪与故障排错
OneUptime 工作流运行与日志(Runs & Logs)完全指南:状态语义、执行追踪与故障排错 工作流的每一次执行都会在 OneUptime 中留下一份完
可观测性后端运维前端云原生微服务AI AgentOneUptime 工作流运行与日志(Runs & Logs)深度指南:状态机、步骤追踪与故障排查实战
OneUptime 工作流运行与日志(Runs & Logs)深度指南:状态机、步骤追踪与故障排查实战 每次工作流被触发后,OneUptime 都会将“何时运行
可观测性后端运维前端云原生微服务AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考