关于 metrics-analysis
metrics-analysis 是面向 ServiceNow SOC 经理和分析师的安全运营指标分析技能,用于评估检测与响应成效、追踪趋势并支持资源规划。它涵盖 MTTD、MTTR、误报率和分析师工作量等指标。
主要功能
- 01计算 MTTD 和 MTTR
- 02按类别与优先级追踪事件量
- 03衡量误报率及其影响
- 04分析分析师工作量分布
- 05对比历史基线与目标
- 06生成管理报告和仪表板
适用场景
- 01开展每周或每月 SOC 绩效评审
- 02编制管理层安全运营报告
- 03规划人员容量与资源分配
- 04优化检测和响应流程
MCP 相关
文档展示了通过 MCP 工具查询 ServiceNow 事件与任务记录,并运行后台脚本计算指标的流程。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill metrics-analysis安装后在 Claude Code 中输入/metrics-analysis确认已加载。
详细介绍
安全运营指标分析
概述
此技能提供了一套结构化方法,用于分析 ServiceNow 中的关键安全运营指标。它可帮助 SOC 管理人员和分析师衡量检测与响应效果、发现趋势并优化资源分配。
主要功能:
- 计算各类事件的平均检测时间(MTTD)和平均响应时间(MTTR)
- 按类别、优先级和时间段跟踪事件量趋势
- 衡量误报率及其对分析师工作效率的影响
- 分析分析师的工作量分布并找出瓶颈
- 将当前表现与历史基线和行业目标进行比较
- 生成指标仪表板和报告,供管理层审阅
适用场景: 定期进行 SOC 绩效评审(每周、每月、每季度)、管理报告、容量规划,或优化检测与响应流程时。
前提条件
- 角色:
sn_si.manager、sn_si.admin、report_admin - 访问权限: 对
sn_si_incident、sn_si_task、sn_ti_observable、sys_audit表具有读取权限;可访问 Aggregate API - 插件: Security Incident Response (sn_si)、Performance Analytics(可选,但推荐)
- 数据: 有足够的事件历史记录(建议至少 30 天,用于趋势分析)
操作步骤
步骤 1:按时间段计算事件量
按时间段查询事件数量,以确定事件量趋势。
使用 MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_si_incident
query: opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)
fields: sys_id,number,category,subcategory,priority,state,opened_at,resolved_at,closed_at,close_code,assignment_group
limit: 1000
使用 REST(使用 Aggregate API 统计数量):
GET /api/now/stats/sn_si_incident?sysparm_query=opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)&sysparm_count=true&sysparm_group_by=category
GET /api/now/stats/sn_si_incident?sysparm_query=opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)&sysparm_count=true&sysparm_group_by=priority
步骤 2:计算平均检测时间(MTTD)
MTTD 衡量威胁首次出现到被检测到之间的经过时间。将可观察对象的 first_seen 时间戳与事件的 opened_at 进行比较。
使用 MCP:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var gr = new GlideRecord('sn_si_incident');
gr.addQuery('opened_at', '>=', gs.daysAgo(30));
gr.addQuery('state', 'IN', '6,7'); // resolved or closed
gr.query();
var totalDetectTime = 0;
var count = 0;
while (gr.next()) {
var obs = new GlideRecord('sn_ti_observable');
obs.addQuery('security_incident', gr.sys_id);
obs.orderBy('first_seen');
obs.setLimit(1);
obs.query();
if (obs.next() && obs.first_seen) {
var firstSeen = new GlideDateTime(obs.first_seen);
var opened = new GlideDateTime(gr.opened_at);
var diff = GlideDateTime.subtract(firstSeen, opened);
totalDetectTime += diff.getNumericValue();
count++;
}
}
var avgMs = count > 0 ? totalDetectTime / count : 0;
var avgHours = (avgMs / 3600000).toFixed(2);
gs.info('MTTD: ' + avgHours + ' hours (based on ' + count + ' incidents)');
使用 REST(手动计算):
GET /api/now/table/sn_si_incident?sysparm_query=opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)^stateIN6,7&sysparm_fields=sys_id,number,opened_at,resolved_at&sysparm_limit=500
# For each incident, query earliest observable:
GET /api/now/table/sn_ti_observable?sysparm_query=security_incident=[SYS_ID]^ORDERBYfirst_seen&sysparm_fields=first_seen&sysparm_limit=1
步骤 3:计算平均响应时间(MTTR)
MTTR 衡量从事件创建到解决所经过的时间。
使用 MCP:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var gr = new GlideRecord('sn_si_incident');
gr.addQuery('opened_at', '>=', gs.daysAgo(30));
gr.addQuery('resolved_at', '!=', '');
gr.query();
var totalResponseTime = 0;
var count = 0;
while (gr.next()) {
var opened = new GlideDateTime(gr.opened_at);
var resolved = new GlideDateTime(gr.resolved_at);
var diff = GlideDateTime.subtract(opened, resolved);
totalResponseTime += diff.getNumericValue();
count++;
}
var avgMs = count > 0 ? totalResponseTime / count : 0;
var avgHours = (avgMs / 3600000).toFixed(2);
gs.info('MTTR: ' + avgHours + ' hours (based on ' + count + ' incidents)');
使用 REST(Aggregate API):
GET /api/now/stats/sn_si_incident?sysparm_query=opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)^resolved_atISNOTEMPTY&sysparm_avg_fields=business_duration&sysparm_count=true
步骤 4:衡量误报率
计算被关闭为误报或非事件的事件所占百分比。
使用 MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_si_incident
query: closed_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)^close_code=false_positive
fields: sys_id,number,category,subcategory,assignment_group,closed_at
limit: 500
Tool: SN-Query-Table
Parameters:
table_name: sn_si_incident
query: closed_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)
fields: sys_id
limit: 1
使用 REST:
# Total closed incidents
GET /api/now/stats/sn_si_incident?sysparm_query=closed_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)&sysparm_count=true
# False positives
GET /api/now/stats/sn_si_incident?sysparm_query=closed_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)^close_code=false_positive&sysparm_count=true
步骤 5:分析分析师工作量分布
衡量事件在分析师和分配组之间的分布情况。
使用 MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_si_incident
query: opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)^assigned_toISNOTEMPTY
fields: assigned_to,assignment_group,priority,state
limit: 1000
使用 REST(Aggregate API):
GET /api/now/stats/sn_si_incident?sysparm_query=opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)^assigned_toISNOTEMPTY&sysparm_count=true&sysparm_group_by=assigned_to
GET /api/now/stats/sn_si_incident?sysparm_query=opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)&sysparm_count=true&sysparm_group_by=assignment_group
步骤 6:跟踪事件类别趋势
通过比较类别分布,识别攻击类型随时间发生的变化。
使用 MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_si_incident
query: opened_atONLast 90 days@javascript:gs.daysAgoStart(90)@javascript:gs.daysAgoEnd(0)
fields: sys_id,category,subcategory,priority,opened_at
limit: 2000
使用 REST:
# Current month
GET /api/now/stats/sn_si_incident?sysparm_query=opened_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)&sysparm_count=true&sysparm_group_by=category
# Previous month
GET /api/now/stats/sn_si_incident?sysparm_query=opened_atBETWEENjavascript:gs.daysAgoStart(60)@javascript:gs.daysAgoEnd(30)&sysparm_count=true&sysparm_group_by=category
步骤 7:衡量任务完成效率
分析安全事件任务的完成速度。
使用 MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_si_task
query: closed_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)
fields: sys_id,number,short_description,state,priority,assigned_to,opened_at,closed_at,work_duration
limit: 500
使用 REST:
GET /api/now/stats/sn_si_task?sysparm_query=closed_atONLast 30 days@javascript:gs.daysAgoStart(30)@javascript:gs.daysAgoEnd(0)&sysparm_avg_fields=work_duration&sysparm_count=true&sysparm_group_by=priority
步骤 8:汇总指标报告
生成全面的指标摘要。
=== SECURITY OPERATIONS METRICS REPORT ===
Period: 2026-02-19 to 2026-03-19 (30 days)
Generated: 2026-03-19
VOLUME METRICS:
Total Incidents: 156 (prev period: 142, +9.8%)
- Critical/P1: 4 (2.6%)
- High/P2: 18 (11.5%)
- Medium/P3: 67 (42.9%)
- Low/P4: 67 (42.9%)
By Category:
- Phishing: 52 (33.3%) ↑ from 28.2%
- Malware: 28 (17.9%) ↓ from 22.5%
- Unauthorized Access: 24 (15.4%) → stable
- Data Loss: 12 (7.7%) → stable
- Vulnerability Exploit: 18 (11.5%) ↑ from 8.5%
- Other: 22 (14.1%)
RESPONSE METRICS:
Mean Time to Detect (MTTD): 4.2 hours (target: <2h, prev: 5.1h)
Mean Time to Respond (MTTR): 18.6 hours (target: <24h, prev: 22.3h)
Mean Time to Contain (MTTC): 2.8 hours (target: <4h, prev: 3.5h)
QUALITY METRICS:
False Positive Rate: 23.1% (target: <20%, prev: 25.6%)
Reopened Incidents: 3 (1.9%)
Escalation Rate: 14.1%
WORKLOAD DISTRIBUTION:
| Analyst | Incidents | Avg Resolution | Utilization |
|---------|-----------|----------------|-------------|
| T. Williams | 32 | 14.2h | 85% |
| K. Chen | 28 | 16.8h | 78% |
| A. Johnson | 31 | 19.1h | 82% |
| M. Davis | 25 | 21.5h | 70% |
| L. Park | 22 | 15.3h | 65% |
| Unassigned | 18 | N/A | - |
KEY OBSERVATIONS:
1. MTTD improved 18% but still above 2-hour target
2. Phishing volume increasing - consider enhanced email filtering
3. False positive rate improving but above 20% threshold
4. Workload imbalance: T. Williams carrying 20% of all incidents
5. 18 unassigned incidents need immediate attention
RECOMMENDATIONS:
1. Tune phishing detection rules to reduce false positives
2. Rebalance workload: redistribute from T. Williams to L. Park
3. Investigate MTTD gap: review SIEM alert correlation rules
4. Staff augmentation may be needed if volume trend continues
工具用法
| 工具 | 用途 |
|---|---|
| SN-Query-Table | 检索事件和任务记录,以计算指标 |
| SN-Execute-Background-Script | 运行服务器端脚本,进行复杂的指标计算 |
| SN-Add-Work-Notes | 在相关记录上记录指标分析结果 |
最佳实践
- 先建立基线,再设定目标;至少使用 90 天的历史数据
- 按优先级细分指标,因为 P1 和 P4 事件可接受的响应时间差异很大
- 跟踪长期趋势,而不是只关注单个时间段的快照
- 自动化数据收集,使用计划运行的后台脚本或 Performance Analytics 指标
- 排除异常值,再计算平均值;单个持续一个月的事件就可能显著拉高 MTTR
- 按来源报告误报率,以确定哪些检测规则需要调整
- 将指标与业务成果对齐,将 MTTD/MTTR 与业务影响持续时间关联起来
- 每月审查工作量分布,以防止分析师倦怠并确保任务分配公平
故障排除
MTTD 计算结果为零
原因: 没有带有 first_seen 时间戳并关联到事件的可观测对象,或者该时间戳早于事件时间。
解决方案: 确认威胁情报集成是否为可观测对象填充了 first_seen。如果 first_seen 晚于 opened_at,MTTD 可能为负数;在这种情况下,请使用事件的 opened_at 作为检测时间。
聚合 API 返回的计数不符合预期
原因: 编码查询可能与预期的日期范围不匹配,或者显示值与存储值不同。 解决方案: 先在 ServiceNow UI 列表筛选器中测试查询。确保日期格式与实例时区一致。
工作量指标显示所有事件均未分配
原因: 事件解决或关闭时,assigned_to 字段可能会被清空。
解决方案: 使用 sys_audit 查找关闭前最后一位被分配的分析师,或者通过 sysparm_display_value=true 查询 assigned_to 字段以获取显示名称。
指标与 Performance Analytics 不一致
原因: PA 指标可能使用不同的数据收集计划、筛选条件或计算方法。 解决方案: 将查询筛选条件与 PA 指标定义保持一致。检查 PA 数据收集作业的计划,并确保近期已运行。
示例
示例 1:月度 SOC 绩效报告
- 计算近 30 天的事件量:所有类别共 156 起
- 计算 MTTD(4.2 小时)、MTTR(18.6 小时)和 MTTC(2.8 小时)
- 计算误报率:156 起事件中有 36 起误报(23.1%)
- 分析 5 位分析师的工作量并找出分配不均的情况
- 将所有指标与上一周期及目标值进行比较
- 生成带有趋势箭头和建议的报告
示例 2:季度高管仪表板
- 提取近 90 天按月细分的事件数据,用于趋势图表
- 计算 MTTD 的环比改善情况:6.3 小时 → 5.1 小时 → 4.2 小时
- 找出导致事件量上升的前三大类别
- 将 MTTR 与行业平均水平进行比较(中型组织为 24 小时)
- 根据事件量趋势预测人员需求(每月增长 9.8%)
- 展示分析结果,并提出增加分析师编制的预算建议
相关技能
secops/correlation-insights- 将关联效果作为检测指标进行衡量secops/incident-summarization- 在事件摘要中加入指标背景信息secops/post-incident-analysis- 使用 PIR 数据改进检测指标secops/shift-handover- 在交接报告中加入班次级指标reporting/trend-analysis- 通用 ServiceNow 趋势分析技巧