您的软件开发生命周期数据模板
您的软件开发生命周期数据模板
- 建议收集的属性
- 需要追踪的关键活动
- ServiceNow DevOps 数据提取指南
软件开发生命周期属性
| 名称 | 描述 | ||
|---|---|---|---|
| 开发项 DevelopmentItem | 在整个开发生命周期中流转的单个工作单元(如功能、缺陷或任务)的唯一标识符。 | ||
| 描述 “开发项”作为主案例标识符 (Case ID),代表一个被追踪的独立工作单元。它将该特定项从最初的构思规划到开发、测试和部署的所有活动联系起来。 在流程挖掘分析中,此属性是重构每个工作项端到端历程的基础。它支持流程流向的可视化、总周期时间的计算,以及针对单个功能或缺陷修复的流程变体识别。日志中的每个事件都必须与一个“开发项”关联,才能构建完整的流程图。 为何重要 这是将所有相关的开发活动连接成单个流程实例的核心标识符,使得分析每个工作项的完整生命周期成为可能。 获取方式 此标识符通常是管理 story、缺陷或任务的表的主键,例如 ServiceNow 中的“rm_story”、“rm_bug”或“task”表。 示例 STRY0010015BUG0034092TASK0050118 | |||
| 开始时间 EventTime | 指示特定活动或 event 发生的准确 timestamp。 | ||
| 描述 此属性提供开发生命周期中记录每个活动的日期和时间。它对于事件的时间排序和所有基于时间的分析都至关重要。 在流程挖掘中,开始时间用于计算活动之间的持续时间、识别等待时间并衡量流程的整体周期时间。它是分析性能的仪表板(如 SDLC 端到端周期时间分析)以及计算关键绩效指标(如代码评审提前期)的核心组件。 为何重要 此时间戳对于正确排列事件顺序以及计算所有性能指标(包括周期时间、持续时长和等待时间)至关重要。 获取方式 通常位于审计跟踪或任务表中的系统生成时间戳字段(如“sys_updated_on”或“sys_created_on”)。 示例 2023-10-26T10:00:00Z2023-10-27T14:35:10Z2023-11-01T09:15:00Z | |||
| 活动名称 ActivityName | 发生的特定开发生命周期事件的名称,例如“开始开发”或“执行代码评审”。 | ||
| 描述 此属性记录软件开发生命周期中完成的每个里程碑或任务的名称。这些活动构成了流程的连续步骤,从创建一直到部署。 分析这些活动的顺序和频率是流程挖掘的主要功能。它支持构建流程图,有助于识别步骤间的瓶颈,并突出显示不合规或低效的流程变体。定义的活动集包括设计、开发、测试和部署等关键阶段。 为何重要 它定义了流程图中的步骤,支持对流程流向进行分析,识别瓶颈并发现与标准软件开发生命周期 (SDLC) 的偏差。 获取方式 这通常是通过将状态变更、事件记录或审计跟踪条目映射到标准化的活动名称列表来派生的。例如,“state”字段变为“In Progress”可以映射为“开始开发”。 示例 开发开始代码已提交QA 测试已完成已部署至生产环境 | |||
| 最后数据更新 LastDataUpdate | 表示此事件日志的数据最后一次从源系统刷新的时间戳。 | ||
| 描述 此属性记录数据集最后一次从 ServiceNow DevOps 提取或更新的时间。它适用于整个数据集,而非单个事件。 此时间戳对于了解分析的新鲜度至关重要。它告知用户流程洞察的当前程度,并有助于安排数据刷新。在仪表板上显示此信息可为所有指标和可视化提供上下文,确保决策是基于及时的数据做出的。 为何重要 提供关于数据及时性的关键上下文,确保用户了解流程分析的更新程度。 获取方式 此时间戳在数据提取过程中生成并添加,记录提取执行的时间。 示例 2023-11-15T08:00:00Z | |||
| 源系统 SourceSystem | 识别数据提取自哪个系统,在本案例中为 ServiceNow DevOps。 | ||
| 描述 此属性指定事件数据的来源系统。对于此流程,它将始终为“ServiceNow DevOps”。 虽然它看起来是静态的,但明确包含源系统对于数据治理至关重要,尤其是在可能合并来自多个系统(如 Jira 或 Azure DevOps)的数据的环境中。它确保了数据出处的清晰度,并有助于诊断数据质量或提取问题。 为何重要 确保数据可追溯性,对于维护数据完整性至关重要,尤其是在集成来自多个开发工具的数据时。 获取方式 这是一个静态值,应在数据提取和转换过程中添加。 示例 ServiceNow DevOps | |||
| 优先级 DevelopmentItemPriority | 分配给开发项的优先级,例如“高”、“中”或“低”。 | ||
| 描述 此属性根据业务紧急程度对开发项进行分类。优先级有助于团队专注于最关键的任务,通常用于管理 SLA 和相关方预期。 在流程挖掘中,优先级是对比分析的关键维度。它允许筛选流程图,以观察高优先级项是否遵循了更快或不同的路径。这对于“高优先级功能交付时间”仪表板和 KPI 至关重要,有助于验证关键项是否得到了真正的加速处理。 为何重要 支持对不同优先级水平的流程进行筛选和对比,有助于验证高优先级项目是否得到了更快、更高效的处理。 获取方式 这是 ServiceNow 任务相关表中的标准字段,通常命名为“priority”。 示例 1 - 紧急2 - 高3 - 中等4 - 低 | |||
| 受影响的模块/组件 ModuleComponentAffected | 开发项所关联的特定软件模块、应用或组件。 | ||
| 描述 此属性按受影响的系统部分对开发工作进行分类。这可能是一个特定的微服务、UI 组件或后端应用程序。 按模块或组件细分流程对于识别局部瓶颈至关重要。“组件特定瓶颈洞察”仪表板和“按组件划分的平均阶段时长”KPI 依赖此属性来精准定位代码库的某些部分是否始终与较长的开发周期、较高的返工率或更频繁的部署失败相关联。这有助于将改进工作集中在最需要的地方。 为何重要 支持按应用或组件进行细分分析,有助于隔离系统特定部分所特有的瓶颈或质量问题。 获取方式 这通常是一个自定义字段或对配置管理数据库 (CMDB) 的引用,将工作项链接到“cmdb_ci”记录。请参阅 ServiceNow DevOps 文档。 示例 计费服务用户身份验证界面报表数据库API Gateway | |||
| 开发项周期时间 DevelopmentItemCycleTime | 从开发项创建到最终关闭或部署所经过的总时长。 | ||
| 描述 此属性是一个计算指标,代表单个开发项的端到端时长。它是通过计算每个案例中第一个活动与最后一个活动之间的时间戳差异得出的。 这是整个 SDLC 流程的主要关键绩效指标,直接支持“平均 SDLC 周期时间”KPI。它提供了流程速率和效率的高层衡量标准。随时间推移并跨不同维度(如优先级或团队)分析此指标,有助于追踪流程改进举措的影响。 为何重要 代表一个工作项的总端到端时长,是衡量整体流程效率和速率的关键指标。 获取方式 这不是源系统中的字段。它是在流程挖掘工具中通过为每个 CaseId 用最大 StartTime 减去最小 StartTime 计算得出的。 示例 15天4小时3天12小时32 天 8 小时 | |||
| 开发项状态 DevelopmentItemState | 事件发生时开发项的状态,例如“打开”、“进行中”或“已关闭”。 | ||
| 描述 此属性反映了开发项在 ServiceNow 中的官方状态。虽然活动是派生的流程步骤,但状态代表了系统工作流中的正式阶段。 状态通常是派生活动的来源。它可以用于数据验证以及创建更简单的高层流程视图。例如,分析在每个状态中停留的时间,可以提供与分析活动间时间不同的瓶颈视角。它对于识别停滞或已解决的项也非常有用。 为何重要 提供工作项的官方系统状态,这通常是派生活动的来源,可用于验证和高层状态分析。 获取方式 这是 ServiceNow 任务相关表中的标准字段,通常命名为“state”或“stage”。 示例 挂起正在处理准备测试已关闭(完成) | |||
| 开发项类型 DevelopmentItemType | 工作项的分类,例如“功能”、“缺陷”、“技术债”或“任务”。 | ||
| 描述 此属性区分了在 SDLC 流程中流转的不同工作类型。例如,修复关键缺陷的流程可能与开发新功能的流程不同且更快。 基于工作项类型分析流程可以实现对性能更细致的理解。它有助于回答诸如“缺陷的返工率是否高于新功能?”或“我们减少技术债的周期时间是否可以接受?”等问题。这种细分提供了比通用的流程视图更深层次的洞察。 为何重要 区分不同的工作类型(如功能和缺陷),这些类型可能具有不同的流程路径、优先级和预期持续时间。 获取方式 这可以根据记录的来源表(例如“rm_story”与“rm_bug”)或通用任务表上的“type”字段来确定。 示例 功能Bug任务Spike | |||
| 指定的开发人员 AssignedDeveloper | 在活动发生时,分配给该开发项的开发人员或用户的姓名或 ID。 | ||
| 描述 此属性标识负责执行特定任务或活动的个人。它是动态的,会随着开发项在不同阶段和团队之间的流转而改变。 此属性对于分析资源分配、工作量和交接至关重要。它直接支持“开发人员工作量与交接”仪表板和“每位开发人员的活动量”KPI。通过追踪此字段的变化,可以衡量交接时间,并识别开发人员之间或开发与 QA 团队之间的协作瓶颈。 为何重要 这对于基于资源的分析(包括工作量分布、交接效率和识别特定团队的绩效模式)至关重要。 获取方式 此信息通常存储在 ServiceNow 任务相关表中的“assigned_to”字段。 示例 David MillerAnna WilliamsJames Brown | |||
| 指派组 AssignmentGroup | 活动发生时负责该开发项的团队或小组。 | ||
| 描述 此属性标识分配给工作项的团队,例如“前端开发”、“后端服务”或“QA 团队”。随着工作项的推进,它经常在不同的分配组之间进行交接。 追踪分配组对于理解跨职能协作和交接至关重要。它有助于识别当工作从一个团队转移到另一个团队时发生的系统性延迟。此属性支持分析团队层面的绩效、工作量,并识别哪些团队是整体流程中的瓶颈。 为何重要 追踪负责工作的团队,从而分析团队绩效、工作量平衡以及团队间交接的效率。 获取方式 此信息存储在“assignment_group”字段中,这是 ServiceNow 任务相关表中的标准字段。 示例 平台工程部移动应用团队质量保证DevOps | |||
| 是否返工 IsRework | 布尔标识。如果活动属于返工循环(例如测试后返回开发阶段),则其值为 true。 | ||
| 描述 这是一个派生属性,用于标识在流程回退到早期阶段后发生的活动。例如,如果同一个项在“QA 测试已完成”活动之后又发生了“开发已开始”活动,它就会被标记为返工。 此标记对于返工的量化和可视化至关重要。它直接支持“返工与驳回流向分析”仪表板,并用于计算“测试后返工率”KPI。通过标记这些事件,分析师可以轻松筛选并分析返工的频率、原因以及对整体周期时间的影响。 为何重要 此标记便于量化和分析返工,有助于衡量流程质量并识别重复工作的根因。 获取方式 此属性是在流程挖掘工具中通过分析每个案例的活动顺序来检测流程流向中的回退动作而计算得出的。 示例 truefalse | |||
| 提交 ID CommitId | 与开发工作关联的源代码提交 (commit) 的唯一标识符。 | ||
| 描述 此属性提供了从开发项到源代码库(如 Git)中特定代码更改的直接链接。它在“代码已提交”活动发生时被捕获。 在流程挖掘中,提交 ID (Commit ID) 通过将流程数据与工程数据连接起来丰富了分析。它允许分析师将有问题的部署追溯到确切的代码更改,或将代码复杂度指标与开发周期时间关联起来。这提供了更深层次、更具技术性的根因分析。 为何重要 将流程事件链接到特定的代码更改,通过将流程指标与代码级细节关联,实现更深层次的根因分析。 获取方式 这是通过 ServiceNow DevOps 与 Git 或 SVN 等源代码管理系统的集成捕获的。数据存储在与开发项链接的相关表中。 示例 a1b2c3d4e5f6f0e9d8c7b6a59a8b7c6d5e4f | |||
| 结束时间 EventEndTime | 表示活动完成的确切时间戳。对于即时事件,此时间与“开始时间”相同。 | ||
| 描述 此属性提供开发生命周期中每个活动完成的日期和时间。对于具有可测量时长的活动(如“已执行代码评审”或“QA 测试”)特别有用。 在流程挖掘中,同时拥有开始和结束时间可以精确计算活动的执行时间,并将其与活动之间的等待时间区分开来。这有助于精准判断延迟是因为任务耗时过长,还是因为等待资源的时间过长。对于被认为是瞬时发生的事件(如“已触发构建”),结束时间可以与开始时间相同。 为何重要 能够精确计算活动的加工时间,从而帮助区分实际工作时间与等待时间。 获取方式 这可能需要派生。它可以是下一个活动的开始时间戳,或者如果源系统中有“结束日期”字段,也可以从那里获取。 示例 2023-10-26T18:05:00Z2023-10-28T11:20:15Z2023-11-02T10:00:00Z | |||
| 计划发布版本 PlannedReleaseVersion | 计划交付该开发项的目标软件发行版或版本。 | ||
| 描述 此属性将开发项连接到特定的计划发布版本,例如“版本 2.3”或“2023 年第四季度发布”。它是项目管理和发布规划的关键要素。 对于流程挖掘,此属性对于“发布计划达成监控”仪表板至关重要。通过对比实际完成日期与计划发布日期,团队可以衡量进度达成情况,识别有错过发布风险的项,并分析发布延迟的原因。它在底层开发流程与高层业务目标之间建立了直接联系。 为何重要 将开发工作与特定版本关联,从而能够分析进度遵循情况以及流程延迟对发布时间线的影响。 获取方式 此信息通常存储在“release”或“planned_release”字段中,通常引用 ServiceNow 中的发布管理表。请参阅 ServiceNow DevOps 文档。 示例 v3.4.12024 年第一季度发布Phoenix 项目上线 | |||
| 返工原因 ReworkReason | 对开发项在测试后需要返工的原因进行分类或描述。 | ||
| 描述 当某个项未能通过 QA 或 UAT 时,此属性会捕获失败的原因。这可能是一个特定的缺陷类别、对需求的误解或环境问题。 此信息为“返工与驳回流向分析”仪表板提供了关键上下文。分析师不仅能知道发生了返工,还能了解原因。这支持进行针对性的改进(如更好的需求定义、增强单元测试或更稳定的测试环境),从而降低整体返工率。 为何重要 提供关于返工原因的定性洞察,从而实现针对性的流程改进,以提高质量并减少返工循环。 获取方式 当测试失败时,这可能会记录在“close_notes”字段中,或者记录在专门的“rework_reason”自定义字段中。请参阅 ServiceNow DevOps 文档。 示例 需求理解偏差回归缺陷性能测试未通过UI/UX 问题 | |||
| 部署状态 DeploymentStatus | 表示部署活动的结果,通常为“成功 (Success)”或“失败 (Failure)”。 | ||
| 描述 此属性记录部署到特定环境的结果。它是理解发布流程可靠性和稳定性的关键信息。 此属性对于“部署成功与失败趋势”仪表板和“部署失败率”KPI 至关重要。通过分析部署失败的频率和趋势,组织可以识别测试、基础设施或发布协调中的潜在问题。它有助于集中精力提高软件交付的质量和可靠性。 为何重要 直接衡量部署活动的成功率,这对于计算部署失败率和分析发布稳定性至关重要。 获取方式 此状态通常记录在部署追踪任务或与 ServiceNow DevOps 集成的 CI/CD 流水线执行记录中。 示例 成功失败已完成,但有警告 | |||
软件开发生命周期活动
| 活动 | 描述 | ||
|---|---|---|---|
| QA 测试已完成 | 表示质量保证团队已成功完成该开发项的测试活动。这通常在开发项的状态从测试阶段转移到“Ready for UAT”或“Done”等状态时推断得出。 | ||
| 为何重要 此里程碑标志着一个主要质量关卡的完成。它是后续阶段(如用户验收测试或发布准备)的前提条件。 获取方式 通过状态从测试状态(如“In QA”)变更为测试后状态(如“Ready for UAT”或“Resolved”)的时间戳推断得出。 捕获 基于状态从“测试中 (Testing)”变更为后续状态的 timestamp。 事件类型 inferred | |||
| UAT 已批准 | 表示业务利益相关者在用户验收测试 (UAT) 后正式批准了该开发项。这是一个关键里程碑,根据状态变更(如从“UAT 中”变为“准备发布”或“已批准”)推断得出。 | ||
| 为何重要 这是项在获准进入生产部署之前的最终业务批准。它是一个关键的质量和治理检查点。 获取方式 根据开发项记录中表示 UAT 成功完成的状态转换来推断。此信息记录在项目的活动历史中。 捕获 根据状态从“UAT”变更为已批准或准备发布状态来推断。 事件类型 inferred | |||
| 代码评审已执行 | 此活动表示同行代码评审的完成,通常与 pull 或 merge 请求相关联。此事件可以通过 DevOps 集成明确捕获,也可以从相关记录的状态更改中推断得出。 | ||
| 为何重要 这是一个关键的质量关卡。分析其持续时间有助于识别评审流程中的瓶颈,这是 SDLC 延迟的常见原因。 获取方式 可从 ServiceNow Git 集成中的 Pull Request 记录的“已合并 (Merged)”或“已完成 (Completed)”事件中捕获,或根据开发项状态变更为“代码评审完成”来推断。 捕获 在与工作项链接的 Pull Request 合并时记录。 事件类型 explicit | |||
| 已部署至生产环境 | 此事件标志着向生产环境部署的成功完成。当 CI/CD 工具报告流水线成功完成时,ServiceNow DevOps 会明确捕获此事件。 | ||
| 为何重要 这是 SDLC 流程的主要成功终点。它完成了价值流,对于计算总周期时间至关重要。 获取方式 从流水线执行 [sn_devops_pipeline_execution] 记录或其关联的阶段执行运行的“完成状态 (completion_status)”中捕获。结束时的“成功 (Success)”状态即标记为此事件。 捕获 在生产环境部署流水线成功完成时记录。 事件类型 explicit | |||
| 开发开始 | 此活动标志着开发人员开始主动编写代码或实施开发项。通常通过该项的状态变更为“In Progress”、“Development”或“Coding”来推断。 | ||
| 为何重要 这是一个关键里程碑,标志着增值构建阶段的开始。它对于衡量开发人员提前期和代码评审周期至关重要。 获取方式 通过开发项记录(例如 Story [rm_story])上的“State”字段更新为“In Progress”或等效状态的时间戳推断得出。 捕获 基于状态变更为“进行中 (In Progress)”或类似值的 timestamp。 事件类型 inferred | |||
| 开发项已创建 | 此活动标志着在 ServiceNow 中创建了新的开发项(如 story、缺陷或 epic)。当向相关表(如 Story [rm_story] 表)插入新记录时,通常会明确捕获此事件。 | ||
| 为何重要 这是 SDLC 流程的主要开始事件。它支持衡量总端到端周期时间并追踪初始需求摄取。 获取方式 在 Story [rm_story]、Epic [rm_epic] 或 Defect [rm_defect] 等开发相关表中创建记录时,记录在 sys_audit 或 sys_history_line 表中。创建时间戳通常位于记录本身。 捕获 捕获自开发项记录的创建 timestamp。 事件类型 explicit | |||
| 部署失败 | 表示将开发项部署到生产环境的尝试未成功。当 CI/CD 流水线报告失败时,ServiceNow DevOps 会显式捕获此信息。 | ||
| 为何重要 这是一个关键的失败终点。分析其频率和原因是提高发布稳定性和降低部署失败率的关键。 获取方式 从流水线执行 [sn_devops_pipeline_execution] 记录的“完成状态 (completion_status)”中捕获。结束时的“失败 (Failed)”状态即标记为此事件。 捕获 在生产环境部署流水线报告失败状态时记录。 事件类型 explicit | |||
| QA 测试已开始 | 标志着正式质量保证 (QA) 测试阶段的开始。这通常通过开发项的状态变更为“In QA”、“Testing”或“Ready for Test”等值来推断。 | ||
| 为何重要 此活动标志着从开发到 QA 团队的交接。它支持测量测试阶段的时长并识别测试能力的瓶颈。 获取方式 通过开发项记录(例如 Story、Defect)上的“State”字段更新为 QA 特定状态的时间戳推断得出。 捕获 基于状态变更为“测试中 (Testing)”或同等状态的 timestamp。 事件类型 inferred | |||
| UAT 已开始 | 代表用户验收测试 (UAT) 的开始,由业务相关方验证功能。此事件通过推断状态变更为“UAT”、“In UAT”或“User Acceptance Testing”来捕获。 | ||
| 为何重要 此阶段对于确保开发的功能满足业务需求至关重要。分析其时长可以揭示用户参与度问题或需求不匹配。 获取方式 根据开发项记录的状态转换推断。这取决于客户的状态模型中是否包含明确的 UAT 状态。 捕获 根据状态变更为“UAT”状态来推断。 事件类型 inferred | |||
| 代码已提交 | 代表开发人员向与开发项关联的版本控制系统仓库提交代码。ServiceNow DevOps 会从集成的 SCM 工具(如 Git 或 GitHub)中明确捕获这些事件。 | ||
| 为何重要 追踪提交记录可以细致地了解开发进度和活动频率。它有助于将特定的代码更改与父开发项关联起来。 获取方式 作为显式事件捕获于 ServiceNow DevOps 提交表 [sn_devops_commit] 中,该表由集成源代码管理系统的 Webhook 自动填充。 捕获 在收到 SCM 工具发送的 commit webhook 时记录。 事件类型 explicit | |||
| 已准备发布 | 此活动表示开发项已通过所有质量关卡,并打包进特定的发布版本中。当该项与发布 (Release) 记录关联或其状态变更为“Ready for Deployment”时,可以推断出此活动。 | ||
| 为何重要 此步骤表示项在技术和功能上已完成。在该状态下停留的时间可以代表计划部署窗口前的排队时间。 获取方式 通过“State”字段变更为“Ready for Release”,或通过追踪开发项记录中“Release”字段的填写或更新情况来推断。 捕获 根据状态变更或与发布记录的关联来推断。 事件类型 inferred | |||
| 开发项已取消 | 代表开发项在完成前终止。这是一种备选的结束状态,通常通过该项的状态被设为“Cancelled”或“Closed Incomplete”来推断。 | ||
| 为何重要 追踪取消情况有助于识别无效工作,并理解范围变更或重新排定优先级的原因。它提供了所有可能流程结果的更完整视图。 获取方式 通过开发项记录上的“State”字段更新为“Cancelled”等终止且非完成状态的时间戳推断得出。 捕获 根据状态变更为“已取消”或同等终止状态来推断。 事件类型 inferred | |||
| 构建已触发 | 此事件表示 CI/CD 流水线构建的开始,通常由代码提交触发。ServiceNow DevOps 将其记录为流水线执行,并将其链回原始开发项。 | ||
| 为何重要 此活动是开发与自动化测试或部署之间的桥梁。分析提交到开始构建之间的时间,可以揭示 CI/CD 流程中的延迟。 获取方式 当集成的 CI/CD 工具(如 Jenkins、Azure DevOps)开始构建时,明确记录在 Pipeline Execution [sn_devops_pipeline_execution] 表中。 捕获 捕获自流水线执行表记录的开始时间。 事件类型 explicit | |||
| 生产环境部署已开始 | 此活动标志着向生产环境部署流水线的启动。当 CI/CD 流水线的生产阶段开始执行时,ServiceNow DevOps 会将其作为一个明确事件捕获。 | ||
| 为何重要 这标志着生命周期最后阶段(通常也是最关键阶段)的开始。追踪此项有助于分析部署时长并识别自动化机会。 获取方式 明确记录在 Stage Execution Run [sn_devops_stage_execution] 表中,并筛选与生产环境相关的阶段。 捕获 捕获自流水线执行中生产部署阶段的开始时间。 事件类型 explicit | |||
| 设计开始 | 代表正在为开发项创建技术设计或方案架构的阶段。这通常通过开发项记录上的状态或阶段字段变更为“Design”或“Solutioning”等值来推断。 | ||
| 为何重要 分析设计阶段的持续时间有助于在开发工作开始前,识别出需求转化和方案规划中的瓶颈。 获取方式 通过开发项记录(例如 Story [rm_story])的状态转换推断得出。通过观察“State”或自定义“Stage”字段变更为设计相关值的记录来识别。 捕获 根据状态变更为“设计”或类似状态来推断。 事件类型 inferred | |||
| 识别到返工 | 表示在测试过程中发现了问题,需要将项目发回开发阶段。该事件通过观察流程中的后退动作来推断,例如状态从“QA 中”变回“进行中”。 | ||
| 为何重要 追踪返工对于理解质量问题和流程效率低下至关重要。此活动频率过高通常指向开发或需求清晰度方面存在问题。 获取方式 通过分析 sys_audit 或 sys_history_line 表中“State”字段的历史记录推断得出。状态从后期阶段(如“Testing”)变更回前期阶段(如“In Progress”)即代表发生了返工。 捕获 根据状态回退推断,例如:“测试中” -> “进行中”。 事件类型 inferred | |||
提取指南
步骤
- 理解您的状态模型:在创建报表前,请记录开发项状态字段(例如 Story
[rm_story]或 Defect[rm_defect]表)中与所需活动对应的具体数值。例如,“进行中”状态可能映射为“开发开始”活动。 - 进入报表创建页面:登录您的 ServiceNow 实例。在过滤器导航栏中,转到
Reports > View / Run并点击Create a report按钮。 - 创建状态变更报表:创建第一个报表以捕获由状态驱动的活动。配置如下:
- 报表名称:
ProcessMind - State Change Events - 源类型:
Table - 表:
Audit [sys_audit] - 类型:
List - 配置列:添加
Document key、Created on、Table name、Field name、Old value和New value。 - 过滤器:将
Table name设置为您的某个开发项表(如Story),Field name设置为状态字段(如State)。在Created on字段上针对所需时间段添加日期过滤。
- 报表名称:
- 创建项目创建报表:为初始创建 event 创建一个新报表。
- 报表名称:
ProcessMind - Item Creation Events - 源类型:
Table - 表:
Story [rm_story](或您的主开发项表) - 类型:
List - 配置列:添加所需属性的列,如
Number、Created on、Assigned to、Priority、State等。 - 过滤器:在
Created on字段上应用日期过滤。
- 报表名称:
- 创建代码提交报表:为与代码提交相关的显式 DevOps 事件创建报表。
- 报表名称:
ProcessMind - Commit Events - 源类型:
Table - 表:
Commit [sn_devops_commit] - 类型:
List - 配置列:添加
Work item、Commit time、Author等列。 - 过滤器:在
Commit time字段上应用日期过滤。
- 报表名称:
- 创建构建与部署报表:针对
Build [sn_devops_build]和Deployment [sn_devops_deployment]表重复上述步骤。这些表包含“构建已触发”、“生产环境部署已开始”、“已部署至生产环境”以及“部署失败”等活动记录。 - 导出所有报表:逐个运行创建的报表。点击菜单图标(三个点或下拉箭头),选择
Export > CSV或Export > Excel。保存所有文件。 - 合并与转换数据:在 Excel 或数据处理工具中打开导出的文件。手动将所有文件的数据合并到一个表格中。创建所需的事件日志列(
DevelopmentItem、ActivityName、EventTime等),并从源列映射数据。例如,将审计报表中的Document key和故事报表中的Number映射到DevelopmentItem列。 - 映射活动名称:通过转换源数据来填充
ActivityName列。对于状态变更报表,参考记录的状态模型将New value条目映射到活动名称(例如,将状态“Testing”映射为“QA 测试开始”)。对于其他报表,为每行分配固定的活动名称(例如,提交导出文件中的所有行都标记为“代码已提交”)。 - 定稿并保存:为所有行添加
SourceSystem和LastDataUpdate列,并填入静态值。确保所有 timestamp 格式一致。将最终合并的文件保存为单个 CSV 文件,即可准备上传至 ProcessMind。
配置
- 所需表:提取所需的主表包括:用于推断事件的
Audit [sys_audit]表、特定的开发项表(例如Story [rm_story]、Defect [rm_defect]),以及 ServiceNow DevOps 核心表:Commit [sn_devops_commit]、Build [sn_devops_build]和Deployment [sn_devops_deployment]。 - 关键过滤器:最重要的过滤器是日期范围。应在所有报表的 timestamp 字段(如
Created on、Commit time或Start time)上统一应用此过滤。对于sys_audit报表,务必对Table name(如rm_story)和Field name(如state)进行过滤,以确保仅获取相关的状态变更数据。 - 日期范围建议:建议提取 3 到 6 个月的数据,以确保数据集具有代表性,且不会引发性能问题。对于大型系统,可以考虑按月分批提取数据。
- 状态模型定义:您必须清晰了解组织的工作项状态模型。这对于将
sys_audit表中记录的状态值准确映射到相应的业务活动(如“QA 测试开始”或“UAT 已通过”)至关重要。 - 先决条件:执行提取的用户需要具备
report_user角色或同等报表创建与运行权限。同时,他们还需要上述 DevOps 及应用开发表的读取权限。此外,必须安装 ServiceNow DevOps 插件,并与您的 SCM 和 CI/CD 工具保持活跃集成。
a 查询示例 config
/*
This extraction method uses the ServiceNow report builder UI. The following sections describe the configuration for each report that must be created and exported.
The exported data must then be manually combined and transformed into a single event log file.
*/
---
-- REPORT 1: Item Creation Events
---
Report_Name: ProcessMind - Item Creation Events
Source_Table: rm_story
Report_Type: List
Columns:
- Number (maps to DevelopmentItem)
- sys_created_on (maps to EventTime)
- 'Development Item Created' (create a formula or static column for ActivityName)
- Assigned to (maps to AssignedDeveloper)
- Priority (maps to DevelopmentItemPriority)
- State (maps to DevelopmentItemState)
- cmdb_ci (maps to ModuleComponentAffected)
- Type (maps to DevelopmentItemType)
- Assignment group (maps to AssignmentGroup)
Filters:
- sys_created_on ON Last 6 months
---
-- REPORT 2: Inferred State Change Events
---
Report_Name: ProcessMind - State Change Events
Source_Table: sys_audit
Report_Type: List
Columns:
- documentkey (maps to DevelopmentItem)
- sys_created_on (maps to EventTime)
- newvalue (maps to ActivityName, requires translation)
- user (maps to AssignedDeveloper)
ActivityName_Mapping_Logic (Example):
- WHEN newvalue IS '[Your Design State]' THEN 'Design Started'
- WHEN newvalue IS '[Your In Progress State]' THEN 'Development Started'
- WHEN newvalue IS '[Your QA State]' THEN 'QA Testing Started'
- WHEN oldvalue IS '[Your QA State]' AND newvalue IS '[Your In Progress State]' THEN 'Rework Identified'
- WHEN oldvalue IS '[Your QA State]' AND newvalue IS '[Your UAT State]' THEN 'QA Testing Completed'
- WHEN newvalue IS '[Your UAT State]' THEN 'UAT Started'
- WHEN newvalue IS '[Your UAT Approved State]' THEN 'UAT Approved'
- WHEN newvalue IS '[Your Release Ready State]' THEN 'Prepared For Release'
- WHEN newvalue IS '[Your Cancelled State]' THEN 'Development Item Cancelled'
Filters:
- tablename = 'rm_story'
- fieldname = 'state'
- sys_created_on ON Last 6 months
---
-- REPORT 3: Code Commit Events
---
Report_Name: ProcessMind - Commit Events
Source_Table: sn_devops_commit
Report_Type: List
Columns:
- work_item.number (maps to DevelopmentItem)
- commit_time (maps to EventTime)
- 'Code Committed' (create a formula or static column for ActivityName)
- author.name (maps to AssignedDeveloper)
Filters:
- commit_time ON Last 6 months
---
-- REPORT 4: Build Events
---
Report_Name: ProcessMind - Build Events
Source_Table: sn_devops_build
Report_Type: List
Columns:
- work_item.number (maps to DevelopmentItem)
- start_time (maps to EventTime)
- 'Build Triggered' (create a formula or static column for ActivityName)
Filters:
- start_time ON Last 6 months
---
-- REPORT 5: Deployment Events
---
Report_Name: ProcessMind - Deployment Events
Source_Table: sn_devops_deployment
Report_Type: List
Columns:
- work_item.number (maps to DevelopmentItem)
- start_time (maps to EventTime for 'Started' activities)
- end_time (maps to EventTime for 'Completed' or 'Failed' activities)
- state (maps to ActivityName, requires translation)
ActivityName_Mapping_Logic:
- WHEN state IS 'in_progress' THEN 'Deployment to Production Started'
- WHEN state IS 'successful' THEN 'Deployed to Production'
- WHEN state IS 'failed' THEN 'Deployment Failed'
Filters:
- start_time ON Last 6 months
- [Filter for production deployments based on your environment configuration]
---
-- Additional events like 'Code Review Performed' may require a separate report
-- on a table like `sn_devops_pull_request` if available and configured.
--- 步骤
- 先决条件:请确保您拥有 ServiceNow 实例的网络访问权限,并已获得具有读取权限的专用服务账号(建议至少具备
itil和sn_devops.viewer角色)。该用户需要访问rm_story、sys_audit和sn_devops_*架构等相关表。 - 安装 ServiceNow ODBC 驱动:从 ServiceNow 支持门户下载适用于您操作系统的 ODBC 驱动程序,并按照说明进行安装。
- 配置 DSN:在运行查询的机器上设置新的系统 DSN(数据源名称)。在 ODBC 数据源管理器中,添加 ServiceNow 驱动程序,并配置您的实例 URL(如
yourinstance.service-now.com)、用户名和密码。 - 连接 SQL 客户端:使用 DBeaver、Microsoft SQL Server Management Studio(通过链接服务器)等 SQL 客户端工具,或使用带有 ODBC 库的 Python 等脚本语言,通过配置好的 DSN 连接到 ServiceNow。
- 识别状态模型:在运行查询前,您必须确认组织在开发项表(如
rm_story、rm_defect)的state字段中使用的确切值。提供的查询示例使用了“In Progress”或“In QA”等常见值,您需要将其替换为您的实际配置值。 - 自定义 SQL 查询:将提供的 SQL 查询语句复制到您的客户端。修改查询顶部的占位符,包括提取的开始日期以及对应于您开发生命周期活动的特定状态值。
- 执行查询:通过 ODBC 连接对 ServiceNow 数据库执行完整的 SQL 查询。根据日期范围和 data 量的不同,这可能需要较长时间。
- 检查数据:查询完成后,对返回的数据集进行简要检查。确认活动类型是否多样,并确保
DevelopmentItem、ActivityName和EventTime等关键列已按预期填充。 - 导出为 CSV:将完整的查询结果导出为 CSV 文件。确保文件采用 UTF-8 编码,且列标题与 ProcessMind 要求的属性名称一致,例如
DevelopmentItem、ActivityName、EventTime。 - 准备上传:确保最终的 CSV 文件末尾没有空行,且
EventTime和LastDataUpdate的日期格式保持一致,并符合 ProcessMind 的要求(例如YYYY-MM-DD HH:MM:SS)。
配置
- 先决条件:需访问启用了 DevOps 模块的 ServiceNow 实例。需要一个拥有相关表读取权限的专用用户账号。此外,客户端机器上必须安装并配置好 ServiceNow ODBC 驱动程序。
- ODBC 驱动配置:连接时需要实例 URL、用户名以及密码或 OAuth 令牌。在运行复杂查询之前,务必先测试 DSN 连接。
- 日期范围过滤:提供的查询语句包含占位符
s.sys_created_on >= '2023-01-01',用于限制提取的 data 量。强烈建议提取特定时间段(如过去 6 到 12 个月)的数据,以确保查询执行时间在可控范围内。 - 状态模型自定义:推断事件的准确性完全取决于状态模型。您必须将查询中的占位符状态值(例如
[Your 'In Progress' State Value]、[Your 'In QA' State Value])替换为 ServiceNow 配置中使用的确切值。请注意,这些值区分大小写。 - 工作项表:本查询针对 Story 表 (
rm_story) 编写。如果您的组织还使用缺陷 (rm_defect)、增强功能 (rm_enhancement) 或其他任务类型,则必须使用UNION ALL将它们添加到初始的DevItems公用表表达式 (CTE) 中。 - 性能建议:直接对 ServiceNow 生产实例运行查询可能会影响性能。建议在非高峰时段进行大规模数据提取。对于极大规模的数据集,请考虑基于
sys_updated_on字段采取增量提取策略。
a 查询示例 sql
WITH DevItems AS (
-- This CTE selects the base set of development items to analyze.
-- Add other tables like rm_defect or rm_enhancement here using UNION ALL if needed.
SELECT
s.sys_id,
s.number,
s.sys_created_on,
s.sys_updated_on,
s.assigned_to,
s.priority,
s.state,
s.cmdb_ci, -- Module/Component Affected
s.sys_class_name, -- Development Item Type
s.assignment_group,
DATEDIFF(second, s.sys_created_on, s.closed_at) AS cycle_time_seconds
FROM rm_story s
WHERE s.sys_created_on >= '2023-01-01' -- *** Placeholder: Set your desired start date ***
),
StateChanges AS (
-- This CTE unnests the audit trail for state changes, which are used for inferred activities.
SELECT
a.documentkey AS item_sys_id,
a.sys_created_on AS change_time,
a.oldvalue,
a.newvalue,
-- *** Placeholder: Define the numeric order of your states to detect rework. Adjust values and names. ***
CASE a.oldvalue
WHEN '1' THEN 1 -- Open
WHEN '[Your 'Design' State Value]' THEN 2
WHEN '[Your 'In Progress' State Value]' THEN 3
WHEN '[Your 'In QA' State Value]' THEN 4
WHEN '[Your 'In UAT' State Value]' THEN 5
ELSE 0
END AS old_state_order,
CASE a.newvalue
WHEN '1' THEN 1 -- Open
WHEN '[Your 'Design' State Value]' THEN 2
WHEN '[Your 'In Progress' State Value]' THEN 3
WHEN '[Your 'In QA' State Value]' THEN 4
WHEN '[Your 'In UAT' State Value]' THEN 5
ELSE 0
END AS new_state_order
FROM sys_audit a
WHERE a.tablename = 'rm_story' AND a.fieldname = 'state'
)
-- 1. Development Item Created
SELECT
i.number AS DevelopmentItem,
'Development Item Created' AS ActivityName,
i.sys_created_on AS EventTime,
'ServiceNow DevOps' AS SourceSystem,
GETDATE() AS LastDataUpdate,
us.name AS AssignedDeveloper,
i.priority AS DevelopmentItemPriority,
i.state AS DevelopmentItemState,
ci.name AS ModuleComponentAffected,
i.sys_class_name AS DevelopmentItemType,
grp.name AS AssignmentGroup,
i.cycle_time_seconds AS DevelopmentItemCycleTime,
CAST(0 AS BIT) AS IsRework
FROM DevItems i
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id
LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id
LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
UNION ALL
-- 2. Design Started
SELECT i.number, 'Design Started', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.newvalue = '[Your ''Design'' State Value]' -- *** Placeholder: Adjust state value ***
UNION ALL
-- 3. Development Started
SELECT i.number, 'Development Started', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.newvalue = '[Your ''In Progress'' State Value]' AND sc.old_state_order < 3 -- *** Placeholder: Adjust state value and order ***
UNION ALL
-- 4. Code Committed
SELECT i.number, 'Code Committed', c.committed_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, i.state, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM sn_devops_commit c JOIN DevItems i ON c.work_item = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
UNION ALL
-- 5. Build Triggered
SELECT i.number, 'Build Triggered', b.start_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, i.state, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM sn_devops_build b JOIN sn_devops_commit_build cb ON b.sys_id = cb.build JOIN sn_devops_commit c ON cb.commit = c.sys_id JOIN DevItems i ON c.work_item = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
UNION ALL
-- 6. Code Review Performed
SELECT i.number, 'Code Review Performed', pr.closed_at, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, i.state, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM sn_devops_pull_request pr JOIN DevItems i ON pr.work_item = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE pr.state = 'merged' -- Or 'closed', depending on process
UNION ALL
-- 7. QA Testing Started
SELECT i.number, 'QA Testing Started', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.newvalue = '[Your ''In QA'' State Value]' -- *** Placeholder: Adjust state value ***
UNION ALL
-- 8. Rework Identified
SELECT i.number, 'Rework Identified', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(1 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.new_state_order < sc.old_state_order AND sc.new_state_order > 1 -- Moved to an earlier state
UNION ALL
-- 9. QA Testing Completed
SELECT i.number, 'QA Testing Completed', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.oldvalue = '[Your ''In QA'' State Value]' AND sc.new_state_order > sc.old_state_order -- *** Placeholder: Adjust state value ***
UNION ALL
-- 10. UAT Started
SELECT i.number, 'UAT Started', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.newvalue = '[Your ''In UAT'' State Value]' -- *** Placeholder: Adjust state value ***
UNION ALL
-- 11. UAT Approved
SELECT i.number, 'UAT Approved', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.oldvalue = '[Your ''In UAT'' State Value]' AND sc.new_state_order > sc.old_state_order -- *** Placeholder: Adjust state value ***
UNION ALL
-- 12. Prepared For Release
SELECT i.number, 'Prepared For Release', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.newvalue = '[Your ''Ready for Release'' State Value]' -- *** Placeholder: Adjust state value ***
UNION ALL
-- 13. Deployment to Production Started
SELECT i.number, 'Deployment to Production Started', se.start_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, i.state, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM sn_devops_step_execution se JOIN sn_devops_artifact_build sab ON se.deployable = sab.sys_id JOIN sn_devops_commit_build cb ON sab.build = cb.build JOIN sn_devops_commit c ON cb.commit = c.sys_id JOIN DevItems i ON c.work_item = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE se.stage_name = 'Production' -- *** Placeholder: Adjust stage name ***
UNION ALL
-- 14. Deployed to Production
SELECT i.number, 'Deployed to Production', se.end_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, i.state, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM sn_devops_step_execution se JOIN sn_devops_artifact_build sab ON se.deployable = sab.sys_id JOIN sn_devops_commit_build cb ON sab.build = cb.build JOIN sn_devops_commit c ON cb.commit = c.sys_id JOIN DevItems i ON c.work_item = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE se.stage_name = 'Production' AND se.result = 'SUCCESS' -- *** Placeholder: Adjust stage name and result value ***
UNION ALL
-- 15. Deployment Failed
SELECT i.number, 'Deployment Failed', se.end_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, i.state, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM sn_devops_step_execution se JOIN sn_devops_artifact_build sab ON se.deployable = sab.sys_id JOIN sn_devops_commit_build cb ON sab.build = cb.build JOIN sn_devops_commit c ON cb.commit = c.sys_id JOIN DevItems i ON c.work_item = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE se.stage_name = 'Production' AND se.result = 'FAILURE' -- *** Placeholder: Adjust stage name and result value ***
UNION ALL
-- 16. Development Item Cancelled
SELECT i.number, 'Development Item Cancelled', sc.change_time, 'ServiceNow DevOps', GETDATE(), us.name, i.priority, sc.newvalue, ci.name, i.sys_class_name, grp.name, i.cycle_time_seconds, CAST(0 AS BIT)
FROM StateChanges sc JOIN DevItems i ON sc.item_sys_id = i.sys_id
LEFT JOIN sys_user us ON i.assigned_to = us.sys_id LEFT JOIN cmdb_ci ci ON i.cmdb_ci = ci.sys_id LEFT JOIN sys_user_group grp ON i.assignment_group = grp.sys_id
WHERE sc.newvalue = '[Your ''Cancelled'' State Value]'; -- *** Placeholder: Adjust state value ***