投递记录 (Pro)
注意:Rules Engine 2.0 是 DefectDojo Pro 专属功能。
规则产生的每一个对外副作用,都会在投递台账中生成一行记录。Rules Engine 2.0 > Deliveries 页面会列出这些记录。
该记录会在发生任何网络调用之前写入,其中保存的正是即将发送或已经发送的确切内容。正因如此,出站发送才是可审计的,而不是一条只能寄希望于有人保留下来的日志;这也是模拟并非另一条独立代码路径的原因:模拟发送使用的是同一条记录,只是跳过了实际派发步骤。
一条投递记录包含哪些内容
| 字段 | 含义 |
|---|---|
| 运行 和 节点 | 产生该记录的运行以及出站节点。 |
| 发现项 | 对于按发现项逐条发送的记录,指其对应的发现项;批量发送记录的则是该批次分组。 |
| 渠道 | 该发送的类型。 |
| 目标 | 解析后的目的地:JIRA 项目键、频道、URL 或地址。 |
| 标题 | 对该次发送的一行简要描述。 |
| 负载 | 即将发送或已发送的确切内容。 |
| 模式 | simulate 或 live。 |
| 状态 | 该投递记录当前所处的阶段。 |
| 尝试次数 | 已尝试发送的次数,以及允许的最大次数。 |
| 最后错误 | 上一次尝试失败的原因,或该记录被跳过的原因。 |
| 响应 | 目标返回的内容。 |
| 外部引用 和 URL | 目标返回的工单编号、消息 ID 或文件路径,以及指向它的链接(如果有)。 |
渠道
| 渠道 | 产生方式 |
|---|---|
| JIRA | 创建 JIRA 问题 |
| 下游连接器 | 创建下游工单 |
| Slack | 发送 Slack 消息,以及发送到 Slack 的报告通知 |
| Microsoft Teams | 发送 Microsoft Teams 消息 |
| 发送电子邮件,以及通过电子邮件发送的报告通知 | |
| Webhook | 调用 Webhook |
| 报告 | 生成报告 |
| 应用内提醒 | 触发应用内提醒 |
状态
| 状态 | 含义 |
|---|---|
simulated | 该规则处于模拟模式。没有发送任何内容,以后也不会发送。 |
skipped | 已有其他记录覆盖了此次发送,或该发送被门控逻辑拒绝。原因记录在“最后错误”字段中。 |
pending | 已在正式模式下记录,正在等待其投递任务执行。 |
dispatched | 已交给集成服务,正在等待确认。 |
sent | 已确认送达。 |
failed | 被永久性拒绝,例如收到 4xx 或供应商返回的错误。可以重放。 |
dead | 重试次数已耗尽,或始终未收到确认。可以重放。 |
skipped 值得多说一句。跳过操作会被记录下来,而不是悄无声息地发生,因为“规则什么都没做”和“规则什么都没做,是因为该发现项已经有工单了”是两种不同的情况,其中只有一种才是问题。
造成跳过的常见原因有三种,“最后错误”字段总会说明具体是哪一种:
- 幂等性。 已有其他记录覆盖了此次发送。
- 渠道已关闭。 如果某个实例上的 Slack 已被禁用,其中包含 Slack 节点的规则会记录一条说明该情况的跳过记录,而不是报错失败。在渠道开启时保存的规则,不应该在有人关闭该渠道后就开始出错。参见节点可用性。
- 达到了按发现项发送的上限。 按发现项逐条发送消息的节点,默认在单次运行中发送满 1,000 条后就会停止,并记录还有多少条未发送。
负载保真度
台账会如实反映所记录的负载与实际线上发送内容之间的接近程度,因为这一点会因渠道而异。
| 保真度 | 含义 |
|---|---|
exact | 与实际发送内容逐字节一致。 |
rendered | 由实际使用的渲染逻辑生成,但发送时的门控逻辑仍可能对其进行裁剪。 |
dojo request | 交给集成服务的确切请求内容。特定于供应商的负载内容是在下游组装的。 |
summary | 对该次发送的描述,而非其原样重现。生成的报告就是一个例子:该文件是在发送时根据实时数据生成的,因此一旦有任何变化,存储下来的副本就会失真。 |
防止重复发送的保护机制
每个幂等键最多只能存在一条活动中的投递记录,这一点由数据库强制保证,而不仅仅是约定。“活动中”指的是 pending、dispatched 或 sent。
如果第二次发送会与一条活动中的记录冲突,它就会变成一条 skipped 记录,并记录下具体原因。它绝不会是一次悄无声息的空操作,也绝不会产生重复的工单。
由于 simulated、skipped、failed 和 dead 状态的记录不会占用该幂等键,失败的投递记录可以原地重放,不会有第二条记录为同一个键相互冲突。
重试
正式模式下的投递记录会自动重试。每条记录都有各自独立的尝试次数和上限(默认六次),因此某个目的地的发送失败不会拖累其他记录。多次重试之间会有退避等待。
当最后一次重试用完后,该记录会被标记为 dead,而不是一直停留在 pending 状态。重试耗尽的情况是可见的,不会被悄悄隐藏。
如果某个工作进程在发送过程中被终止,消息会被重新投递。在再次发送之前,该记录会被锁定并重新检查其状态,因此重新投递不会变成重复发送。
交给集成服务的投递记录会进入 dispatched 状态,等待确认回调。如果六小时内没有收到回调,该记录会被标记为 dead,以便重放。这个等待窗口特意设置得比较宽松:下游队列积压一个小时是很正常的情况,如果过早地判定记录失败,重放就可能变成重复的工单。
重放投递记录
状态为 failed 或 dead 的投递记录,可以在“投递记录”页面重新发送。台账会记录该记录是何时、由谁重放的。
重放需要具备规则编辑权限。
重放会重新发送已记录的负载内容。对于报告而言,这意味着会根据当前数据重新生成报告,因为负载内容描述的是应生成什么,而不是文件本身。
模拟
在模拟模式下,每个出站节点都会写入一条状态为 simulated、包含完整负载内容和解析后目标的投递记录,然后停止执行。系统不会登记任何派发操作,因此无论该次运行后续如何展开,都不会有内容被发送出去。预览的行为与此相同,甚至连记录都不会插入。
这正是在正式启用一条规则之前对其进行审查的推荐方式:先以模拟模式启用它,让它针对真实的发现项运行,然后查看它所记录下的负载内容。
请注意,模拟模式只会拦截对外发送的动作。发现项节点仍然会照常修改发现项。
数据保留
投递记录默认保留 180 天,超过之后会由保留期清理任务将其清除。
这是该功能中增长最快的数据表,因为按发现项逐条发送消息的节点,无论在模拟模式还是正式模式下,都会为每个发现项写入一行记录。默认设置是一个真实存在的保留窗口,而不是“全部保留”,因此数据增长不会在不知不觉中变成你的负担。
系统会主动告知你这一点,而不是让你自己去发现。每条投递记录的详情中都会显示保留窗口以及该记录将被删除的日期,且该日期在每次读取时都会重新计算,因此更改保留窗口会立即生效。
如果你需要更长的对外发送审计追溯期,可以将该窗口设置得更长,或设为 0 以保留全部记录。参见配置。