FEATURED · 精选文章

DataHub Incidents API 实战:通过 GraphQL 上报、查询与解决数据事故

发布时间 / 2026/9/16 19:26:25
来源 / 创域科博编辑部
栏目 / 资讯中心
DataHub Incidents API 实战:通过 GraphQL 上报、查询与解决数据事故 DataHub Incidents API 实战通过 GraphQL 上报、查询与解决数据事故【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub本篇指南基于 DataHub 官方教程 Incidents API Tutorial完整讲解如何通过 GraphQL API 对数据资产数据集、仪表盘等上报raise、检索retrieve、更新update和解决resolve数据事故Incident。读完本文你不仅能复制可运行的 GraphQL 语句完成事故的整个生命周期管理还能理解事故在 DataHub 元数据模型中的存储结构incidentInfoAspect、权限校验逻辑以及当前仓库中比教程更进一步的updateIncident/upsertIncident高级操作。为什么需要 Incidents APIIncidents API 允许你以编程方式上报、获取、更新和解决数据事故。典型场景是在 Airflow、Prefect 或 Dagster 的 DAG 中当某个任务检测到数据新鲜度异常、行数骤降或作业失败时自动向 DataHub 中对应的数据集发起事故工单同样地流水线也可以在开始之前先查询该数据集是否存在活跃事故从而实现条件式的熔断conditional Circuit Breaking避免在已知数据不可信的情况下继续下游计算。前置条件权限调用 API 的 Actor 必须对目标资产Table/资产拥有Edit Incidents权限。这一要求对应到源码所有事故写操作raise / update status在执行前都会调用 IncidentUtils 中的isAuthorizedToEditIncidentForResource(urn, context)逐一校验校验失败会抛出AuthorizationExceptionUnauthorized to perform this action. Please contact your DataHub administrator.。前端侧同样的逻辑出现在 EntityPrivilegesResolver 的canEditIncidents字段中用于控制 UI 上创建事故按钮的可见性。数据模型Incident 与 incidentInfo Aspect要理解 API 的行为先看底层存储。事故是 DataHub 中的一类实体其核心 Aspect 定义在 IncidentInfo.pdlincidentInfoschemaVersion 3关键字段包括type/customType事故类型与自定义类型标签均带Searchable注解分别映射为筛选器 Type 和 Other Type因此可在 UI 搜索页按类型过滤title/description标题用WORD_GRAM字段类型且boostScore: 10.0标题在全文搜索中权重更高描述用TEXTentitiesarray[Urn]通过Relationship注解建立名为IncidentOn的关系关联目标涵盖dataset、chart、dashboard、dataFlow、dataJob、schemaField、mlModel、mlFeature、mlFeatureTable、service、aiAgent等实体类型——也就是说一个事故可以挂在多种资产上priorityoptional int注释明确写着 0 - CRITICAL, 1 - HIGH, 2 - MED, 3 - LOW数字越小越严重这也是后文整数与枚举名差异的根源status/source/assignees/startedAt/created状态、来源手动或断言失败、负责人、实际开始时间与创建审计戳。GraphQL 层则通过 incident.graphql 暴露出一组更友好的类型Incident对象、IncidentStateACTIVE / RESOLVED、IncidentStage生命周期阶段、IncidentPriority枚举名以及各输入类型。上报事故raiseIncident对已存在的资产使用以下 mutation 上报新事故mutation raiseIncident { raiseIncident( input: { resourceUrn: urn:li:dataset:(urn:li:dataPlatform:snowflake,public.prod.purchases,PROD) type: OPERATIONAL title: Data is Delayed description: Data is delayed on May 15, 2024 because of downtime in the Spark Cluster. priority: HIGH } ) }其中resourceUrn是你想上报事故的数据资产的唯一标识符支持数据集dataset、仪表盘dashboard、图表chart、数据作业data job或数据流data flow等实体。支持的事故类型教程文档中列出的类型包括OPERATIONAL、FRESHNESS、VOLUME、COLUMN、SQL、DATA_SCHEMA、CUSTOM。需要注意的一点是当前仓库的 GraphQL schemaincident.graphql 第 251-291 行中IncidentType枚举定义的是FRESHNESS、VOLUME、FIELD、SQL、DATA_SCHEMA、OPERATIONAL、CUSTOM——即字段断言Field Assertion失败触发的事故在当前枚举中名为FIELD。实际调用请以你所连接实例的 GraphQL schema可通过 introspection 查询为准。各类型的语义为FRESHNESS/VOLUME/FIELD/SQL/DATA_SCHEMA对应各类断言Assertion失败自动触发的事故OPERATIONAL运维类事故如数据集物化失败、任务/流水线执行失败CUSTOM完全自定义类型必须同时提供customType字段。customType是一个自由文本标签用来命名你的事故类别。源码中这一约束在 RaiseIncidentResolver 中显式校验当type为CUSTOM而customType缺失或为空白时直接抛出Failed to raise incident: customType is required when type is CUSTOM。例如mutation raiseCustomIncident { raiseIncident( input: { resourceUrn: urn:li:dataset:(urn:li:dataPlatform:snowflake,public.prod.purchases,PROD) type: CUSTOM customType: ML_LEAKAGE title: Feature built from post-decision data description: days_since_last_payment reads payment events recorded after loan origination. } ) }设置优先级prioritypriority是可选字段。通过 GraphQL 传入时必须是四个枚举名之一不带引号priority含义存储值incidentInfo.aspectCRITICALP00HIGHP11MEDIUMP22LOWP33如果传入整数如2会收到形如Invalid input for enum IncidentPriority. No value found for name 2的错误。整数 vs 枚举名的方向差异底层存储的incidentInfoAspect 将优先级建模为整数且数字越小越严重CRITICAL0LOW3这些整数只在你通过 OpenAPI 或 RestLI 直接写 Aspect 时才适用。GraphQL API 只接受和返回上表的枚举名并替你完成转换。两套体系的排序方向正好相反切勿混用。这一约定在 incident.graphql 中也被逐值注释标注Stored as 0 on the incidentInfo aspect 等。教程之外的扩展输入对照 schema 中的RaiseIncidentInputincident.graphql除了教程示例用到的字段你还可以传入id调用方自提供的事故主键。不提供时由服务端生成随机 UUID提供后走 create-if-not-exists 语义——若该 id 已存在mutation 以 CONFLICT 冲突失败而不是更新或返回已有事故保证raiseIncident始终是仅创建操作适合在重试场景中避免产生重复事故。空白字符串 id 会被显式拒绝Incident id must not be blank.防止重试空白 id 每次都创建新事故的陷阱resourceUrns资产 URN 列表可与resourceUrn合并使用两者合并去重后至少为一个否则报At least 1 resource urn must be defined to raise an incident.startedAt事故实际发生的时间可以早于上报时间例如回溯性补录单位为毫秒时间戳assigneeUrns负责处理事故的用户或组 URN 列表source/status事故来源手动创建默认为MANUAL与初始状态默认为ACTIVE。如果上报成功响应中会返回新事故的唯一标识符即 Incident URN{ data: { raiseIncident: urn:li:incident:new-incident-id }, extensions: {} }底层执行链路从 RaiseIncidentResolver 的实现看一次raiseIncident的完整链路是解析输入并合并resourceUrn/resourceUrns→ 对每个资源 URN 做Edit Incidents权限校验 → 确定事故 id自提供或 UUID→mapIncidentInfo将输入映射为IncidentInfoAspect默认sourceMANUAL、status为 ACTIVE、created审计戳取当前 actor 与时间→ 构造MetadataChangeProposal自提供 id 时附带CreateIfNotExistsValidator的 If-None-Match 前置条件头→ 经EntityClient.ingestProposal写入。相关行为由单元测试 RaiseIncidentResolverTest 覆盖包括 CUSTOM 缺customType时的报错路径。查询资产的事故incidents 查询要获取某数据资产的事故列表及状态可以查询该实体下的incidents字段query getAssetIncidents { dataset( urn: urn:li:dataset:(urn:li:dataPlatform:snowflake,public.prod.purchases,PROD) ) { incidents(state: ACTIVE, start: 0, count: 20) { start count total incidents { urn incidentType title description status { state lastUpdated { time actor } } } } } }传ACTIVE过滤活跃事故传RESOLVED过滤已解决事故不传则返回全部状态。根据 incident.graphqlincidents查询完整支持以下过滤与分页参数参数说明默认值state按事故状态过滤ACTIVE / RESOLVED任意状态stage按生命周期阶段过滤任意阶段priority按优先级过滤任意优先级assigneeUrns按负责人 URN 过滤不限start起始偏移0count返回条数20并且incidents字段不只挂在Dataset上——schema 中同时扩展了DataJob、DataFlow、Dashboard、Chart、MLModel、MLFeature、SchemaFieldEntity、MLFeatureTable等实体类型参数完全一致。查询结果EntityIncidentsResult返回start/count/total用于分页判断。事故对象还可通过relationships字段追溯IncidentOn关系指向的资产。解决与重新打开事故updateIncidentStatus使用updateIncidentStatusmutation 更新事故状态mutation updateIncidentStatus { updateIncidentStatus( urn: urn:li:incident:new-incident-id input: { state: RESOLVED message: The delayed data issue was resolved at 4:55pm on May 15. } ) }注意根据 incident.graphql 的 schema 定义updateIncidentStatus要求urn: String!和input: IncidentStatusInput!两个参数均为必填原教程示例中省略了urn实际调用时必须传入目标事故的 URN即raiseIncident的返回值。input中除state外还有可选的stage生命周期阶段与message。同样地你可以把状态从RESOLVED改回ACTIVE来重新打开一个事故。成功时响应如下{ data: { updateIncidentStatus: true }, extensions: {} }从 UpdateIncidentStatusResolver 的源码可以看到其执行细节先读取事故 URN 的incidentInfoAspect若不存在则抛出NOT_FOUNDFailed to update incident. Incident does not exist.随后对事故的第一个关联资源做Edit Incidents权限校验源码注释标注了当前仅支持单实体、多实体支持为 TODO校验通过后写入新的IncidentState并把status.lastUpdated的审计戳更新为当前 actor 与当前时间可选覆盖message和stage最后通过 MCP 落库并返回true。生命周期阶段与高级编辑updateIncident / upsertIncident除了 ACTIVE / RESOLVED 两态事故状态还支持一个五阶段的生命周期模型IncidentStage见 incident.graphqlTRIAGE正在评估影响范围与优先级INVESTIGATION正在排查根因WORK_IN_PROGRESS处于修复阶段FIXED已修复完成NO_ACTION_REQUIRED无需处理即解决如误报或预期内波动。该字段可通过updateIncidentStatus的stage参数、raiseIncident的status.stage或下述 patch/upsert 操作进行设置。当前仓库的 schema 还暴露了两个教程未覆盖的编辑 mutation适合需要修改事故标题、负责人、资源范围等字段的高级场景updateIncident补丁语义省略的字段与 null 标量字段保持不变status内部仅补丁式修改所提供的子字段state / stage / message空列表的assigneeUrns会清空负责人但该 mutation 不能清空已设置的 priority 与 startedAt。upsertIncident整体覆盖语义UpsertIncidentInput是编辑器的完整字段快照可空字段省略或置 null 即被清空包括 priorityresourceUrns与assigneeUrns必填且为完整集合。事故类型type、来源source、创建审计与 startedAt 在该表单中不可编辑会被保留。选择原则只想改一部分字段用updateIncident需要把某个可空字段如优先级清掉则必须用upsertIncident。常见错误与适用边界汇总本指南涉及的关键报错便于在脚本中做防御性处理报错触发原因Failed to raise incident: customType is required when type is CUSTOMtype: CUSTOM但未提供非空customTypeInvalid input for enum IncidentPriority. No value found for name 2向 GraphQL 传入了整数而非枚举名At least 1 resource urn must be defined to raise an incident.resourceUrn与resourceUrns均为空Incident id must not be blank.提供了空白字符串的自定idIncident with id %s already exists.CONFLICT自定id已存在create-if-not-exists 语义Failed to update incident. Incident does not exist.NOT_FOUND更新的状态对应的事故 URN 不存在Unauthorized to perform this action...AuthorizationExceptionActor 缺少目标资产的Edit Incidents权限最后需要说明适用前提本指南当前仅覆盖 GraphQL API教程中的 Python SDK 各小节标注为 Python SDK support coming soon!尚未可用权限模型要求 Actor 具备资产的Edit Incidents权限updateIncidentStatus的权限校验目前按事故关联的第一个资源实体进行源码标注为待完善的 TODO。以上细节均可在 incident.graphql、IncidentInfo.pdl 及 resolvers/incident 目录下的 Resolver 源码中进一步查证。【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻