Skip to content

Commit f9eabcc

Browse files
Merge pull request #42 from leftrightleft/mttr
Add MTTR Metric to GHAS Dashboards
2 parents 10b3b76 + 6a94df0 commit f9eabcc

File tree

3 files changed

+112
-65
lines changed

3 files changed

+112
-65
lines changed

github_app_for_splunk/default/data/ui/views/code_scanning_overview.xml

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<label>Code Scanning Alerts</label>
33
<search id="baseSearch">
44
<query>
5-
`github_webhooks` (eventtype="GitHub::CodeScanning" OR eventtype="GitHub::Push") | eval action='action', tool=if(isnotnull('alert.tool.name'),'alert.tool.name','unknown'), repository=if(isnotnull('repository.name'),'repository.name','unknown'), severity=if(isnotnull('alert.rule.security_severity_level'),'alert.rule.security_severity_level','none'), create_time=if(isnotnull('alert.created_at'),'alert.created_at','unknown'), received_time='_time', alert_url=if(isnotnull('alert.html_url'),'alert.html_url','unknown'), eventtype='eventtype', created=strptime(create_time, "%Y-%m-%dT%H:%M:%S%Z"), duration=received_time - created, duration_str=tostring(avg(duration), "duration")
5+
`github_webhooks` (eventtype="GitHub::CodeScanning" OR eventtype="GitHub::Push") | eval action='action', tool=if(isnotnull('alert.tool.name'),'alert.tool.name','unknown'), repository=if(isnotnull('repository.name'),'repository.name','unknown'), severity=if(isnotnull('alert.rule.security_severity_level'),'alert.rule.security_severity_level','none'), create_time=if(isnotnull('alert.created_at'),'alert.created_at','unknown'), received_time='_time', alert_url=if(isnotnull('alert.html_url'),'alert.html_url','unknown'), eventtype='eventtype', created=strptime(create_time, "%Y-%m-%dT%H:%M:%S%Z"), resolved_at=case('alert.dismissed_at' != "null", 'alert.dismissed_at', isnotnull('alert.fixed_at'), 'alert.fixed_at', isnotnull('alert.resolved_at'),'alert.resolved_at', 1=1, _time), duration = toString(round(strptime(resolved_at, "%Y-%m-%dT%H:%M:%S") - strptime(create_time, "%Y-%m-%dT%H:%M:%S"))), duration_str=tostring(avg(duration), "duration")
66
</query>
77
<earliest>$timeTkn.earliest$</earliest>
88
<latest>$timeTkn.latest$</latest>
@@ -46,62 +46,78 @@
4646
</fieldset>
4747
<row>
4848
<panel>
49+
<title>Mean Time to Resolution (MTTR)</title>
50+
<single>
51+
<search base="baseSearch">
52+
<query>| search eventtype="GitHub::CodeScanning" (action=fixed OR action=closed_by_user) tool=$tool_name$ repository=$repoTkn$
53+
| eval action=action, , repository=if(isnotnull('repository.name'),'repository.name','unknown')
54+
| eval age = avg(duration)
55+
| appendpipe [ stats avg(age) as totalTime ]
56+
| eval mttr = toString(round(totalTime), "duration"), clean_mttr = replace (mttr , "\+" , " days, ")
57+
| stats max(clean_mttr)
58+
59+
</query>
60+
</search>
61+
<option name="drilldown">none</option>
62+
</single>
63+
</panel>
64+
<panel>
65+
<title>Created</title>
4966
<single>
50-
<title>Created</title>
5167
<search base="baseSearch">
5268
<query>| search tool=$tool_name$ repository=$repoTkn$ action="created" | stats count</query>
5369
</search>
5470
<option name="drilldown">none</option>
55-
<option name="height">50</option>
71+
<option name="height">100</option>
5672
<option name="rangeColors">["0x53a051","0x0877a6","0xf8be34","0xf1813f","0xdc4e41"]</option>
5773
<option name="refresh.display">progressbar</option>
5874
</single>
5975
</panel>
6076
<panel>
77+
<title>Fixed</title>
6178
<single>
62-
<title>Fixed</title>
6379
<search base="baseSearch">
6480
<query>| search tool=$tool_name$ repository=$repoTkn$ action="fixed" | stats count</query>
6581
</search>
6682
<option name="drilldown">none</option>
67-
<option name="height">50</option>
83+
<option name="height">100</option>
6884
<option name="refresh.display">progressbar</option>
6985
</single>
7086
</panel>
7187
<panel>
88+
<title>Reopened</title>
7289
<single>
73-
<title>Reopened</title>
7490
<search base="baseSearch">
7591
<query>| search tool=$tool_name$ repository=$repoTkn$ action="reopened" | stats count</query>
7692
</search>
7793
<option name="drilldown">none</option>
78-
<option name="height">50</option>
94+
<option name="height">100</option>
7995
<option name="refresh.display">progressbar</option>
8096
</single>
8197
</panel>
8298
</row>
8399
<row>
84100
<panel>
101+
<title>Alert Found/Fixed Ratio</title>
85102
<chart>
86-
<title>Alert Found/Fixed Ratio</title>
87103
<search base="baseSearch">
88104
<query>| search tool=$tool_name$ repository=$repoTkn$ (action=created OR action=fixed)
89-
| timechart count(_raw) by action
105+
| timechart count(_raw) by action
90106
| accum created
91-
| accum fixed
92-
| rename created as "Found"
107+
| accum fixed
108+
| rename created as "Found"
93109
| rename fixed as "Fixed"</query>
94110
</search>
95111
<option name="charting.axisTitleX.visibility">collapsed</option>
96112
<option name="charting.chart">line</option>
97113
<option name="charting.drilldown">none</option>
98-
<option name="refresh.display">progressbar</option>
99114
<option name="height">150</option>
115+
<option name="refresh.display">progressbar</option>
100116
</chart>
101117
</panel>
102118
<panel>
119+
<title>Commit/Alert Ratio</title>
103120
<chart>
104-
<title>Commit/Alert Ratio</title>
105121
<search base="baseSearch">
106122
<query>| search (eventtype="GitHub::Push" repository=$repoTkn$) OR ((action=created OR action=reopened) tool=$tool_name$ repository=$repoTkn$ )
107123
| timechart count(_raw) by eventtype
@@ -122,8 +138,8 @@
122138
</chart>
123139
</panel>
124140
<panel>
141+
<title>New Alerts by Tool</title>
125142
<chart>
126-
<title>New Alerts by Tool</title>
127143
<search base="baseSearch">
128144
<query>| search tool=$tool_name$ repository=$repoTkn$ (action=created OR action=appeared_in_branch) | timechart count(_raw) by tool</query>
129145
</search>
@@ -141,8 +157,9 @@
141157
<title>Fixed Alerts</title>
142158
<search base="baseSearch">
143159
<query> | search (action=fixed OR action=closed_by_user) repository=$repoTkn$ tool=$tool_name$
144-
| table repository, tool, alert_url,duration_str
145-
| rename repository AS "Repository" duration_str AS "Time to Resolution",tool AS "Tool", alert_url AS "Alert URL"
160+
|eval clean_duration = replace (duration_str , "\+" , " days, ")
161+
| table repository, tool, alert_url,clean_duration
162+
| rename repository AS "Repository" clean_duration AS "Time to Resolution",tool AS "Tool", alert_url AS "Alert URL"
146163
| sort -"Time to Resolution"
147164
</query>
148165
</search>
@@ -157,11 +174,8 @@
157174
<search base="baseSearch">
158175
<query>| search (action=created OR action=reopened) repository=$repoTkn$ tool=$tool_name$ | chart usenull=f count over repository by severity</query>
159176
</search>
177+
<option name="dataOverlayMode">heatmap</option>
160178
<option name="drilldown">none</option>
161-
<format type="color" field="critical">
162-
<colorPalette type="minMidMax" maxColor="#DC4E41" minColor="#FFFFFF"></colorPalette>
163-
<scale type="minMidMax"></scale>
164-
</format>
165179
<format type="color" field="high">
166180
<colorPalette type="minMidMax" maxColor="#F8BE34" minColor="#FFFFFF"></colorPalette>
167181
<scale type="minMidMax"></scale>

github_app_for_splunk/default/data/ui/views/dependabot_alerts.xml

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
<form version="1.1">
1+
<form version="1.1" theme="dark">
22
<label>Dependabot Alerts</label>
33
<search id="baseSearch">
44
<query>
5-
`github_webhooks` (eventtype="GitHub::VulnerabilityAlert" OR eventtype="GitHub::Push") | eval action='action', repository=if(isnotnull('repository.name'),'repository.name','unknown'), severity=if(isnotnull('alert.severity'),'alert.severity','none'), create_time=if(isnotnull('alert.created_at'),'alert.created_at','unknown'), received_time='_time', alert_url=if(isnotnull('alert.external_reference'),'alert.external_reference','unknown'), eventtype='eventtype', created=strptime(create_time, "%Y-%m-%dT%H:%M:%S%Z"), duration=received_time - created, duration_str=tostring(avg(duration), "duration")
5+
`github_webhooks` eventtype="GitHub::VulnerabilityAlert" | eval action='action', repository=if(isnotnull('repository.name'),'repository.name','unknown'), severity=if(isnotnull('alert.severity'),'alert.severity','none'), create_time=if(isnotnull('alert.created_at'),'alert.created_at','unknown'), received_time='_time', alert_url=if(isnotnull('alert.external_reference'),'alert.external_reference','unknown'), eventtype='eventtype', created=strptime(create_time, "%Y-%m-%dT%H:%M:%S%Z"), resolved_at=case('alert.dismissed_at' != "null", 'alert.dismissed_at', isnotnull('alert.fixed_at'), 'alert.fixed_at', isnotnull('alert.resolved_at'),'alert.resolved_at', 1=1, _time), duration = toString(round(strptime(resolved_at, "%Y-%m-%dT%H:%M:%S") - strptime(create_time, "%Y-%m-%dT%H:%M:%S"))), duration_str=tostring(avg(duration), "duration")
66
</query>
77
<earliest>$timeTkn.earliest$</earliest>
88
<latest>$timeTkn.latest$</latest>
@@ -17,7 +17,7 @@
1717
</default>
1818
</input>
1919
<input type="multiselect" token="repoTkn" searchWhenChanged="true">
20-
<label>Repositories</label>
20+
<label>Repositories</label>
2121
<choice value="*">All</choice>
2222
<default>*</default>
2323
<initialValue>*</initialValue>
@@ -45,14 +45,31 @@
4545
</input>
4646
</fieldset>
4747
<row>
48+
<panel>
49+
<single>
50+
<title>Mean Time to Resolution (MTTR)</title>
51+
<search base="baseSearch">
52+
<query>| search severity=$severity_label$ repository=$repoTkn$ action="resolve"
53+
| eval age = avg(duration)
54+
| appendpipe [ stats avg(age) as totalTime ]
55+
| eval mttr = toString(round(totalTime), "duration"), clean_mttr = replace (mttr , "\+" , " days, ")
56+
| stats max(clean_mttr)
57+
</query>
58+
</search>
59+
<option name="drilldown">none</option>
60+
<option name="height">100</option>
61+
<option name="rangeColors">["0x53a051","0x0877a6","0xf8be34","0xf1813f","0xdc4e41"]</option>
62+
<option name="refresh.display">progressbar</option>
63+
</single>
64+
</panel>
4865
<panel>
4966
<single>
5067
<title>Created</title>
5168
<search base="baseSearch">
5269
<query>| search severity=$severity_label$ repository=$repoTkn$ action="create" | stats count</query>
5370
</search>
5471
<option name="drilldown">none</option>
55-
<option name="height">50</option>
72+
<option name="height">100</option>
5673
<option name="rangeColors">["0x53a051","0x0877a6","0xf8be34","0xf1813f","0xdc4e41"]</option>
5774
<option name="refresh.display">progressbar</option>
5875
</single>
@@ -64,7 +81,7 @@
6481
<query>| search severity=$severity_label$ repository=$repoTkn$ (action="resolve") | stats count</query>
6582
</search>
6683
<option name="drilldown">none</option>
67-
<option name="height">50</option>
84+
<option name="height">100</option>
6885
<option name="refresh.display">progressbar</option>
6986
</single>
7087
</panel>
@@ -75,7 +92,7 @@
7592
<query>| search severity=$severity_label$ repository=$repoTkn$ (action="dismiss") | stats count</query>
7693
</search>
7794
<option name="drilldown">none</option>
78-
<option name="height">50</option>
95+
<option name="height">100</option>
7996
<option name="refresh.display">progressbar</option>
8097
</single>
8198
</panel>
@@ -97,29 +114,20 @@
97114
<option name="charting.chart">line</option>
98115
<option name="charting.drilldown">none</option>
99116
<option name="refresh.display">progressbar</option>
100-
<option name="height">150</option>
117+
<option name="height">200</option>
101118
</chart>
102119
</panel>
103120
<panel>
104121
<chart>
105-
<title>Commit/Alert Ratio</title>
122+
<title>Vulnerabilities by Repo</title>
106123
<search base="baseSearch">
107-
<query>| search (eventtype="GitHub::Push" repository=$repoTkn$) OR ((action=create) severity=$severity_label$ repository=$repoTkn$ )
108-
| timechart count(_raw) by eventtype
109-
| accum "GitHub::Push"
110-
| accum "GitHub::VulnerabilityAlert"
111-
| rename GitHub::Push as "Pushes"
112-
| rename GitHub::VulnerabilityAlert as "Dependabot Alerts"
113-
| fields - err0r</query>
124+
<query>| search severity=$severity_label$ repository=$repoTkn$ action=create | chart count by repository
125+
</query>
114126
</search>
115-
<option name="charting.axisTitleX.visibility">collapsed</option>
116-
<option name="charting.axisY.scale">log</option>
117-
<option name="charting.axisY2.enabled">1</option>
118-
<option name="charting.chart">line</option>
119-
<option name="charting.chart.overlayFields">DC_cumulative</option>
127+
<option name="charting.chart">pie</option>
120128
<option name="charting.drilldown">none</option>
121129
<option name="charting.legend.mode">standard</option>
122-
<option name="height">150</option>
130+
<option name="height">200</option>
123131
<option name="refresh.display">progressbar</option>
124132
</chart>
125133
</panel>
@@ -132,7 +140,7 @@
132140
<option name="charting.chart">column</option>
133141
<option name="charting.chart.stackMode">stacked</option>
134142
<option name="charting.drilldown">none</option>
135-
<option name="height">150</option>
143+
<option name="height">200</option>
136144
<option name="refresh.display">progressbar</option>
137145
</chart>
138146
</panel>
@@ -170,4 +178,4 @@
170178
</table>
171179
</panel>
172180
</row>
173-
</form>
181+
</form>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy