OneUptime 与 Jira 双向集成实战:用 Workflow 自动同步 Incident 与 Issue
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
OneUptime 的 Workflow 引擎允许你通过低代码画布把"监控与告警"和外部工单系统打通。本文以 Jira 为例,讲解完整的双向集成方案:OneUptime 每次声明 Incident 时自动在 Jira 创建 Issue,随着 Incident 推进持续更新(评论、状态流转),同时由 Jira 的自动化规则把 Issue 的状态变更回调到 OneUptime 并更新对应 Incident。读完本文,你将掌握 Basic Auth 凭据的存储与轮换、Atlassian Document Format(ADF)的构造、JQL 反查、Webhook 触发器的安全校验,以及 Jira Cloud 与 Jira Data Center 两套 API 的差异。
整个方案不需要安装任何 Jira 专用插件:OneUptime 通过 Workflow 组件中的 API 组件直接调用 Jira REST API,Jira 则通过调用 OneUptime 的 Webhook 触发器把事件推回来。双向数据流如下:
OneUptime Incident → On Create ──► API Post (POST /rest/api/3/issue) ──► Jira issue Jira issue transitioned ──► Automation rule (Send web request) ──► OneUptime Webhook trigger ──► Update One Incident注意:Atlassian 在 Jira Cloud 中持续重命名术语——project在多数界面中已改称space,issue改称work item。不同租户界面词汇并存,下文在术语关键处会同时给出两种叫法。
前置条件
- 一个 Jira Cloud 站点(
https://your-domain.atlassian.net)以及一个用于登记 Issue 的项目,记下它的project key——即OPS-1234中的OPS。 - 一个能在该项目中创建 Issue 的 Jira 账号及其API token(在
id.atlassian.com/manage-profile/security/api-tokens生成)。建议使用服务账号而非个人账号——这样创建的 Issue 会归属于 token 持有者。 - 拥有在该项目创建自动化规则的权限(用于"入站"方向)。
- 一个 OneUptime 项目,并且能创建 Workflow 和全局变量。
第一步:把 Jira 凭据保存为 Secret
Jira Cloud 的 REST API 使用Basic Auth:将 Atlassian 账号邮箱与 API token 拼成email:api_token后整体 base64 编码。
一次性完成编码:
printf '%s' 'you@example.com:your_api_token' | base64必须用
printf而不是echo。echo会附加一个换行符,换行符会连同内容一起被编码,Jira 会返回401,而从粘贴的字符串上根本看不出原因。在 OneUptime 中进入Flujos de trabajo → Variables Globales → Crear(工作流 → 全局变量 → 创建),命名为
JIRA_AUTH,把 base64 字符串粘贴为Content,并打开Secret开关。再添加一个非 Secret 变量
JIRA_URL,值为https://your-domain.atlassian.net(末尾不要带斜杠)。
此后任何组件都可以用Basic {{global.variables.JIRA_AUTH}}作为Authorization请求头,而 token 永远不会出现在 Workflow 本体或其执行日志中。全局变量的引用语法、Secret 的脱敏行为参见 variables.md(变量创建后不可编辑,只能删除重建)。
关于 Atlassian API token,有两个会"咬人"的细节:
- token 会过期。创建时可选 1 天到 1 年有效期,默认 1 年,且无法续期——过期后必须在同一页面手动更换并重新编码进
JIRA_AUTH。请把过期日期记进日历。当某个运行了数月的 Workflow 突然开始返回401,原因多半在此。 - 带 scope 的 token 需要不同的 base URL。token 页面除经典Create API token外还提供Create API token with scopes。带 scope 的 token 更安全,但它不指向你的站点,而是指向
https://api.atlassian.com/ex/jira/<cloudId>——此时JIRA_URL应改为该地址,下方所有路由不变地挂在其后。你的cloudId可从https://your-domain.atlassian.net/_edge/tenant_info返回的 JSON 中获得。把带 scope 的 token 发往your-domain.atlassian.net只会失败。
如果组织使用 Atlassian 集中式用户管理,还有第三种选择,能彻底绕开过期问题:为服务账号创建 OAuth 2.0 凭据页面的两组件结构相同:一个API Post (JSON)组件获取 token,后续所有请求携带Bearer <token>。API base URL 为https://api.atlassian.com,具体换取 token 的请求格式以 Atlassian 官方页面为准。
第二步:每个 Incident 自动创建 Jira Issue
打开Flujos de trabajo → Crear flujo de trabajo(工作流 → 创建工作流),命名为
Incidents → Jira,进入Constructor(画布编辑器)。点击虚线占位符组件,添加触发器On Create Incident。在Select Fields中声明需要向下游传递的字段:
{ "_id": true, "title": true, "description": true, "incidentNumber": true, "incidentSeverity": { "name": true } }保持其Identifier为默认值
incident-on-create-1——后续组件靠它引用这个触发器的输出。点击Añadir componente(添加组件),加入API Post (JSON)组件,从触发器的Success端口拖线连到新组件的入口。打开该组件,把Identifier设为
create-issue,填写:URL:
{{global.variables.JIRA_URL}}/rest/api/3/issueRequest Headers:
{ "Authorization": "Basic {{global.variables.JIRA_AUTH}}", "Accept": "application/json" }Request Body:
{ "fields": { "project": { "key": "OPS" }, "issuetype": { "name": "Bug" }, "summary": "OneUptime #{{local.components.incident-on-create-1.returnValues.model.incidentNumber}}: {{local.components.incident-on-create-1.returnValues.model.title}}", "labels": ["oneuptime"], "description": { "type": "doc", "version": 1, "content": [ { "type": "paragraph", "content": [ { "type": "text", "text": "{{local.components.incident-on-create-1.returnValues.model.description}}" } ] } ] } } }
把
OPS换成你的 project key,Bug换成该项目中真实存在的 issue 类型。两者也都可以用 id 指定——{"id": "10000"}——这是 Atlassian 官方示例的做法;当站点里有两个同名 issue 类型时务必用 id。下文createmeta的调用会给出这些 id。
关于 Atlassian Document Format(ADF)
描述字段看起来"很重",是因为 Jira Cloud 的 API v3 把富文本作为Atlassian Document Format接收——一个文档树,而不是字符串。上面的结构是合法文档的最小形态:一个paragraph包含一个text节点。environment以及多行文本类型的自定义字段同样适用;单行文本自定义字段则仍然接受普通字符串。
启用与验证
从Vista General → Editar flujo de trabajo → Habilitado(概览 → 编辑工作流 → 启用)打开 Workflow 开关,声明一个测试 Incident,然后打开Ejecuciones y Registros(执行与日志)。create-issue组件应显示201,响应体包含新 Issue 的id、key和self。画布上的修改是自动保存的——没有保存按钮;而禁用的 Workflow 无论如何都无法执行,包括手动执行。
新 Issue 的 key 对后续任意组件可用:
{{local.components.create-issue.returnValues.response-body.key}}这里的response-body、response-status、response-headers是 API 组件的标准返回字段。从 API/Post.ts 的实现可以看到,请求发出后组件把HTTPResponse或HTTPErrorResponse统一转换为这三个返回值,并按结果走向success或error端口(4xx/5xx 会走 error 端口,同时把状态码与响应体保留在response-body中供排查)。
填充更多字段
fields中常见的补充:
- Priority——
"priority": { "id": "20000" },使用你站点的优先级 id。要把 OneUptime 的严重级别映射到 Jira 优先级,可在触发器与 API 组件之间放一个If / Else组件,对{{local.components.incident-on-create-1.returnValues.model.incidentSeverity.name}}做分支。 - Assignee——
"assignee": { "id": "<accountId>" }。Jira Cloud 用 Atlassian account id 标识人员;username与userKey多年前已从 Cloud API 移除。 - Labels——
"labels": ["oneuptime", "sev1"],扁平字符串数组。label 不能包含空格。 - Components——
"components": [{ "id": "10000" }]。 - Custom fields——
"customfield_10034": "...",用字段自己的 id。值的形态取决于字段类型:单选 select 接受{"value": "red"},多选接受 id 数组,多行文本字段则要传 ADF 文档。
与其猜测项目到底要求什么,不如直接问 Jira。先列出项目的 issue 类型,再列出其中某个类型的字段:
curl -u 'you@example.com:your_api_token' \ 'https://your-domain.atlassian.net/rest/api/3/issue/createmeta/OPS/issuetypes' curl -u 'you@example.com:your_api_token' \ 'https://your-domain.atlassian.net/rest/api/3/issue/createmeta/OPS/issuetypes/10001'第二个调用会列出该 issue 类型接受的所有字段、哪些是必填的,以及确切的customfield_NNNNNid。对于已有的 Issue,可用?expand=names读取字段 id。
第三步:把 Incident ID 带进 Jira
双向同步的两半需要某一方保存另一方的标识符,而 Jira 是最合适的存放处:OneUptime 的customFields列是单个 JSON blob,从 Workflow 写入一个值会覆盖该 Incident 的全部自定义字段。
方案一(有 Jira 管理员配合):在项目的创建屏幕添加一个短文本自定义字段——比如叫OneUptime Incident ID——用createmeta查到它的 id,然后把它和其他字段一起提交:
"customfield_10050": "{{local.components.incident-on-create-1.returnValues.model._id}}"方案二(没有管理员):放进 label。label 不能有空格,而 OneUptime 的 id 是纯 UUID,所以oneuptime-<id>是合法 label:
"labels": ["oneuptime", "oneuptime-{{local.components.incident-on-create-1.returnValues.model._id}}"]入站 Workflow 需要从 label 列表中提取该 id,这在一个Run Custom JavaScript组件里只需几行。能建自定义字段的话还是它更干净。
顺带值得在 Jira Issue 里加一个回链到 Incident 的链接。在create-issue之后再加一个API Post (JSON)组件,指向{{global.variables.JIRA_URL}}/rest/api/3/issue/{{local.components.create-issue.returnValues.response-body.key}}/remotelink:
{ "globalId": "system=https://oneuptime.com&id={{local.components.incident-on-create-1.returnValues.model._id}}", "object": { "url": "https://oneuptime.com/dashboard/{{local.components.incident-on-create-1.returnValues.model.projectId}}/incidents/{{local.components.incident-on-create-1.returnValues.model._id}}", "title": "OneUptime incident #{{local.components.incident-on-create-1.returnValues.model.incidentNumber}}" } }这给 Jira 里所有人一条一键返回的路径。为此需要在触发器的Select Fields中追加projectId。globalId让该调用可安全重放:Jira 会更新已携带该 id 的链接而不是新增第二个。由于更新同样会把省略的字段置空,务必总是发送完整的object而非补丁。
第四步:随 Incident 推进评论与流转状态
把这个构建成第二个Workflow,这样它的任何故障都不会阻碍 Issue 的创建。
- Crear flujo de trabajo,命名为
Incident updates → Jira,添加触发器On Update Incident。 - 在Listen on中填
{"currentIncidentStateId": true}——这样触发器只在状态变更时触发,而不是每次编辑都触发。在Select Fields中请求{"_id": true, "currentIncidentState": {"name": true}}。 - 添加If / Else组件:Input 1为
{{local.components.incident-on-update-1.returnValues.model.currentIncidentState.name}},Operator为==,Input 2为Resolved(或你项目中实际的"已解决"状态名)。OneUptime 的状态模型见 states-and-severities.md:状态行为由isCreatedState、isAcknowledgedState、isResolvedState三个布尔标志驱动,与状态名称无关,所以重命名状态不会破坏该判断。
在Sí分支中,先找回第二步创建的 Issue——用第三步保存的 id 向 Jira 查询。添加一个API Post (JSON)组件,Identifier设为find-issue:
URL:
{{global.variables.JIRA_URL}}/rest/api/3/search/jqlRequest Body:
{ "jql": "project = OPS AND labels = \"oneuptime-{{local.components.incident-on-update-1.returnValues.model._id}}\"", "maxResults": 1 }如果第三步用的是自定义字段而非 label,则把子句改为
cf[10050] ~ "..."(用你自己的字段 id)。
Issue 的 id 随后为{{local.components.find-issue.returnValues.response-body.issues[0].id}},下方所有 endpoint 用 id 与用 key 效果相同。
关于该 endpoint 有三点要知道:JQL 放在请求体中而不是 URL——URL 查询串里包含=的值在离开 Workflow 时会被截断,而 JQL 几乎全是=;查询必须加限定条件——裸的order by key desc会被400拒绝,这正是project =子句存在的原因;/rest/api/3/search/jql才是现行 endpoint——旧的/rest/api/3/search已弃用并走向移除,不要回退使用。
留下评论:一个API Post (JSON)组件指向{{global.variables.JIRA_URL}}/rest/api/3/issue/<id>/comment,正文同样用 ADF:
{ "body": { "type": "doc", "version": 1, "content": [ { "type": "paragraph", "content": [{ "type": "text", "text": "Resolved in OneUptime." }] } ] } }流转 Issue需要两次调用,因为 transition 用 id 标识,而 id 在不同 Workflow 之间、某些看板下不同 Issue 之间都可能有差异:
一个API Get (JSON)组件访问
{{global.variables.JIRA_URL}}/rest/api/3/issue/<id>/transitions,返回从该 Issue 当前状态出发的所有可用流转,每条含id、name以及描述目标状态的to对象。一个API Post (JSON)组件向同一 URL 执行流转:
{ "transition": { "id": "31" } }
成功的流转返回204且无响应体。如果不希望运行时读取列表,可以手动对处于合适状态的 Issue 调用一次并硬编码 id——但要记住它与该 Workflow 绑定,Jira 管理员日后修改 Workflow 会静默破坏它。
入站方向:从 Jira 回调 OneUptime
现在处理另一个方向:有人把 Issue 移到 Done,OneUptime 的 Incident 应当跟随。
先构建接收端 Workflow
Crear flujo de trabajo,命名为
Jira → OneUptime,添加Webhook触发器。打开该 Workflow 的Ajustes(设置),复制Clave secreta del webhook(Webhook 密钥)。你的回调 URL 是:
https://oneuptime.com/workflow/trigger/<webhook secret key>自托管安装使用自己的主机名。请把该 URL 当作密码保管——任何拿到它的人都能触发 Workflow——若泄露则从同一页面重置密钥。
Webhook 触发器的实现位于 Webhook.ts:它注册了
GET /trigger/:secretkey与POST /trigger/:secretkey两个路由,用路径参数中的密钥查询WorkflowService找到对应 Workflow,然后把request-headers、request-params、request-body三个值注入执行上下文,并立即返回{"status": "Scheduled"}。添加一个If / Else组件,在任何其他逻辑执行前校验共享密钥。Input 1为
{{local.components.webhook-1.returnValues.request-headers.x-oneuptime-secret}},Operator为==,Input 2为{{global.variables.JIRA_WEBHOOK_SECRET}}——这是一个你自拟并保存为全局 Secret 变量的值。从Sí分支添加Update One Incident组件:
- Query:
{"_id": "{{local.components.webhook-1.returnValues.request-body.oneuptimeIncidentId}}"} - Data (JSON Object): 该 Jira 变更在 OneUptime 侧应产生的效果——通常是一次状态变更。
流转 Incident 需要目标状态的 id,可用Find One Incident State组件配合查询
{"name": "Resolved"}得到{{local.components.incident-state-find-one-1.returnValues.model._id}},把它写入currentIncidentStateId。- Query:
保持该 Workflow 为启用状态,然后给 Jira 一个可调用的目标。
用 Jira 自动化规则发送事件
在 Jira 打开项目的自动化规则:新租户在Space settings → Automation,旧租户在Project settings → Automation。跨项目的规则用Settings → System → Global automation,这需要全局Administer Jira权限。
Create rule并选择触发器Work item transitioned(旧租户为Issue transitioned),配置为状态进入Done时触发。
请用这个触发器而不是Work item updated:更新触发器刻意排除了状态变更。
添加Send web request动作并配置:
Web request URL: 上面 OneUptime 的 Webhook URL。
HTTP method:
POSTHeaders:
Content-Type/application/json,以及X-OneUptime-Secret/ 你的共享密钥。密钥值用Hide选项,其他规则编辑者将无法读取——注意隐藏对该值不可逆,且导出或复制规则时隐藏值会丢失。Web request body: 选Custom format以便完全控制形态:
{ "oneuptimeIncidentId": "{{issue.customfield_10050}}", "issueKey": "{{issue.key}}", "summary": "{{issue.summary}}", "status": "{{issue.status.name}}" }如果第三步用的是 label 而非自定义字段,则发送
"labels": "{{issue.labels}}",在 OneUptime 侧用Run Custom JavaScript组件提取 id。
启用规则,把测试 Issue 移到 Done,然后两侧核对:Jira 侧看规则自身的审计日志,OneUptime 侧看Ejecuciones y Registros。
依赖这套机制前需要知道的几件事:
- 目标端口受限。Send web request 只能访问 80、8080、443、6017、8443、8444、7990、8090、8085、8060、8900 和 9900 端口。OneUptime Cloud 在 443;自托管且端口不寻常的安装无法被这样回调。
- 请求没有签名。该动作没有 HMAC 选项,所以 HTTPS 上的共享密钥 header 是 Atlassian 文档化的机制。接收端 Workflow 第三步的If / Else校验正是让它有意义的原因。
- 规则执行计入配额。Jira Cloud 把规则成功执行计入月度配额,随套餐而异——Free 100 次、Standard 1,700 次、Premium 1,000 × 用户数、Enterprise 不限量。在高频项目上每条流转都触发的规则会很快累积。
- 值不会被 URL 编码。只有发送表单编码的 body 时才需要关心;上面的 JSON 没问题。
- Atlassian 公布出站 IP 段(
ip-ranges.atlassian.com),供 OneUptime 位于白名单之后时使用。这些段会变化,请定期查询而非固化地址。
或者改用 Jira Webhook
Jira 管理员也可以在Settings → System → Advanced → WebHooks直接注册 webhook,选择要发送的事件,并可用 JQL 查询限定触发它的 Issue。与自动化规则相比:
- 载荷是 Jira 原生的而非你自定义的:包含
webhookEvent、issue_event_type_name、完整issue,以及一个changelog,其items数组给出每个被修改字段的前后值。对状态变更,你要找field为status的条目。在 Workflow 内解析它通常需要一个Run Custom JavaScript组件。 - Webhook可以签名——给 webhook 一个 secret,Jira 会发送
X-Hub-Signatureheader(请求体字节的 HMAC)——但 Workflow 无法校验。签名覆盖的是 Jira 发送的确切字节,而 Webhook 触发器交给 Workflow 的是已被解析为 JSON 的 body,没有可哈希的原始内容。若要认证请求,用带共享密钥 header 的自动化规则。 - URL 必须是 HTTPS 且端口在 Jira 自己的端口列表内,与自动化动作的列表不同——这里不允许 80 端口。
- 投递会重试最多五次,间隔 5 到 15 分钟,因此 Workflow 必须容忍同一事件到达两次。
应用通过/rest/api/3/webhook注册的 webhook 是另一回事:除非刷新,否则注册 30 天后过期。管理员注册的(上文所述)不过期。
Jira Data Center 的差异
自托管 Jira 的机制相同,只需少量替换。Jira Server已于 2024 年 2 月停止支持且不再修复,因此把 Data Center 视为自托管目标。
| Cloud | Data Center |
|---|---|
/rest/api/3/... | /rest/api/2/...—— Data Center 没有 v3 |
description为 ADF 文档 | description为 wiki markup 普通字符串 |
Authorization: Basic base64(email:api_token) | Authorization: Bearer <personal access token> |
| API token 来自 id.atlassian.com | Profile → Personal access tokens → Create token(你自己的 Jira 账号) |
| 自动化动作Send web request | 自动化动作Send outgoing web request |
因此创建 Issue 的组件变成对/rest/api/2/issue的POST:
{ "fields": { "project": { "key": "OPS" }, "issuetype": { "name": "Bug" }, "summary": "OneUptime #123: Checkout is down", "description": "Plain text goes straight in here." } }模板化更简单——没有文档树。
其他应预判的差异:
- Personal access token自 Jira Core / Jira Software 8.14 与 Jira Service Management 4.15 起可用。默认 365 天过期,过期前 5 天界面会标记Expires soon。用户名密码的 Basic 认证在 Data Center 仍可用,但少数几次失败登录会触发 CAPTCHA,把账号完全挡在 REST API 之外直到有人用浏览器解决——这不是发现拼写错误的好方式,优先用 token。
- 自动化内置于 Jira Data Center 10.0 起;更早版本需要单独安装 Automation for Jira 应用。其出站请求默认超时 3000 ms,可通过属性
outgoing.webhook.timeout.ms调整。 - Webhook在Administration → System → Advanced → WebHooks注册,支持用 JQL 限定。请保持过滤器严格:Jira 在触发事件所在线程中评估每个已注册 webhook 的 JQL,十几个宽松过滤器会拖慢触发它们的用户操作。
- 自 Data Center 10.0 起 webhook 投递为异步,且没有同步选项,事件可能乱序到达。接收端 Workflow 要幂等。
- Jira 10 移除了 webhook URL 变量中的
$——${issue.id}变成{issue.id}——并把 webhook REST 资源从/rest/webhooks/1.0/webhook移到/rest/jira-webhook/1.0/webhooks。
用同样的方式处理告警(Alert)
以上全部围绕 Incident 编写,因为这是最常见场景,但告警的工作方式完全相同——换记录类型即可:
| Incident | Alert |
|---|---|
On Create Incident(incident-on-create-1) | On Create Alert(alert-on-create-1) |
On Update Incident(incident-on-update-1) | On Update Alert(alert-on-update-1) |
incidentNumber、currentIncidentState、incidentSeverity | alertNumber、currentAlertState、alertSeverity |
| Find One Incident State | Find One Alert State |
| Update One Incident | Update One Alert |
一个 Workflow 恰好只有一个触发器,因此 Incident 与 Alert 各需一个 Workflow。若两者要做同样的工作,就把 Jira 侧逻辑构建一次,再用Execute Workflow组件从两边调用它。从源码结构看,这些"记录型触发器"由基类工厂统一生成——ComponentMetadata.ts 遍历所有数据库模型,通过BaseModelComponentFactory为每个模型批量注册 On Create / On Update 等组件,OnCreateBaseModel.ts 即对应on-create触发类型;Workflow 执行本身在 ComponentCode.ts 中被入队调度,Webhook 与各组件代码统一从 Common/Server/Types/Workflow/Components 注册。
故障排查
先在Ejecuciones y Registros打开失败的组件。Jira 会返回一个 JSON 响应体,精确指出被拒绝的内容,API 组件把它保留在response-body中。
401 Unauthorized。用printf重新编码email:api_token并更新JIRA_AUTH;echo带入的尾部换行是常见原因。然后确认 token 所属账号能在该项目创建 Issue。在 Data Center,确认发送的是Bearer而非Basic。
400 Bad Request且点名某个字段。该 issue 类型在该项目不存在,或项目有必填字段未发送。对那个项目和 issue 类型运行上文createmeta调用并逐项比对。
400报description的问题。Cloud v3 的 description 必须是 ADF 文档而非字符串。要么发送上文展示的文档结构,要么把该组件改为/rest/api/2/issue并发送纯文本。
404 Not Found。检查 base URL 与 API 版本——Cloud 用/rest/api/3/...,Data Center 用/rest/api/2/...。
429 Too Many Requests。Jira 在限流。响应带Retry-After(秒)与RateLimit-Reason(命中的是哪个限额)。对同一 Issue 的写操作配额很紧——约 2 秒内 20 次——所以一个快速连续评论与流转的 Workflow 可能被单个 Issue 触发限流。在调用间放一个Delay组件,或把批量工作移到定时 Workflow。
流转调用返回400。该 transition id 从 Issue当前状态出发无效。重新获取/transitions并使用响应中的 id。
自动化规则显示成功但 OneUptime 什么都没收到。先查端口——对照上文受限端口列表。然后用curl自行向 webhook URL 发一次请求,看是否出现在Ejecuciones y Registros;如果你的请求到达而 Jira 的没有,问题在 Jira 侧。
Workflow 执行了但 Incident 没变。Update One Incident在查询无匹配时报告Items Updated: 0,而这算成功而非错误。确认载荷中的 id 确实是 OneUptime Incident 的 id,且查询的是_id。
一条{{...}}引用原样出现在 Jira Issue 里。未解析的引用会按原文字符传递而不是清空。执行日志会点名未解析的引用——通常是写错的组件 Identifier 或改名后的变量。
延伸阅读
- Integrations 总览 —— 入站/出站模式与快速认证指南。
- Microsoft Dynamics 365 集成 —— 针对 Dynamics 的同一套双向构建。
- Workflows 总览 与 创建工作流 —— 画布、Identifier 与如何启用 Workflow。
- 组件 —— API、If / Else 与 OneUptime 数据组件。
- 变量 —— Secret,以及如何从下一个组件读取上一个组件的输出。
- 配置与安全 —— Webhook 安全与出站网络访问。
- ServiceNow 与 PagerDuty —— 面向其他工具的同一出站模式。
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考