{% if !repo_choices.is_empty() || !runner_choices.is_empty() %}
16
<formclass="filters"method="get"action="{{ base }}">
17
<inputtype="hidden"name="range"value="{{ i.range.key() }}">{% if wall %}<inputtype="hidden"name="wall"value="1">{% endif %}
18
<selectname="repo"aria-label="Repository or owner"><optionvalue="">every repository</option>{% for r in repo_choices %}<option{% if *r == repo_filter %} selected{% endif %}>{{ r }}</option>{% endfor %}</select>
19
<selectname="runner"aria-label="Runner"><optionvalue="">every runner</option>{% for r in runner_choices %}<option{% if *r == runner_filter %} selected{% endif %}>{{ r }}</option>{% endfor %}</select>
20
<button>filter</button>
21
</form>
22
{% endif %}
23
<spanclass="insights-links small">
24
{% if let Some((label, url)) = wider %}<ahref="{{ url }}?range={{ i.range.key() }}">{{ label }}</a>{% endif %}
25
{% if wall %}<ahref="{{ base }}?range={{ i.range.key() }}{% if !repo_filter.is_empty() %}&repo={{ repo_filter|urlencode }}{% endif %}{% if !runner_filter.is_empty() %}&runner={{ runner_filter|urlencode }}{% endif %}">leave the wall view</a>{% else %}<ahref="{{ base }}?range={{ i.range.key() }}{{ keep }}&wall=1"target="_blank"rel="noopener"title="For a second monitor: large, no menus, refreshing itself">wall view ↗</a>{% endif %}
26
{% if !grafana.is_empty() %}<ahref="{{ grafana }}"target="_blank"rel="noopener">open in Grafana ↗</a>{% endif %}
27
</span>
28
</div>
29
30
<divclass="kpis">
31
<divclass="kpi"><spanclass="kpi-v">{{ secs(i.pickup_median) }}</span><spanclass="kpi-l">time to pickup, median</span><spanclass="kpi-s">95th percentile {{ secs(i.pickup_p95) }}</span></div>
32
<divclass="kpi"><spanclass="kpi-v">{{ i.ended }}</span><spanclass="kpi-l">jobs finished</span><spanclass="kpi-s">{{ pass_rate() }} passed of those that passed or failed</span></div>
33
<divclass="kpi"><spanclass="kpi-v">{{ secs(i.duration_median) }}</span><spanclass="kpi-l">job duration, median</span><spanclass="kpi-s">started to finished</span></div>
<figureclass="chart-card"><figcaption>Time to pickup <spanclass="mute small">ready to started</span></figcaption>{{ charts.pickup|safe }}<divclass="legend">{% for s in i.pickup %}<spanclass="key {{ s.class }}">{{ s.name }}</span>{% endfor %}</div></figure>
40
<figureclass="chart-card"><figcaption>Jobs finished <spanclass="mute small">per {% if range_on("1h") %}minute{% else if range_on("7d") %}3 hours{% else %}30 minutes{% endif %}</span></figcaption>{{ charts.results|safe }}<divclass="legend">{% for s in i.results %}<spanclass="key {{ s.class }}">{{ s.name }}</span>{% endfor %}</div></figure>
41
<figureclass="chart-card"><figcaption>Queued and running</figcaption>{{ charts.load|safe }}<divclass="legend">{% for s in i.load %}<spanclass="key {{ s.class }}">{{ s.name }}</span>{% endfor %}</div></figure>
42
<figureclass="chart-card"><figcaption>Job duration <spanclass="mute small">started to finished</span></figcaption>{{ charts.durations|safe }}<divclass="legend">{% for s in i.durations %}<spanclass="key {{ s.class }}">{{ s.name }}</span>{% endfor %}</div></figure>
43
<figureclass="chart-card"><figcaption>Runner utilisation <spanclass="mute small">running jobs over the slots of the runners online now</span></figcaption>{{ charts.utilisation|safe }}<divclass="legend">{% for s in i.utilisation %}<spanclass="key {{ s.class }}">{{ s.name }}</span>{% endfor %}</div></figure>
{% for r in i.repos %}<tr><td><ahref="/{{ r.slug }}/insights?range={{ i.range.key() }}">{{ r.slug }}</a></td><td>{{ r.jobs }}</td><td>{% if r.failed > 0 %}{{ r.failed }}{% else %}<spanclass="mute">0</span>{% endif %}</td><td>{{ r.queued }}</td><td>{{ secs(r.pickup_median) }}</td><td>{{ secs(r.pickup_p95) }}</td></tr>{% endfor %}
60
</table></div>
61
</section>
62
{% endif %}
63
<pclass="small mute">Updated <timetitle="{{ i.now_ms|when_i }}">{{ i.now_ms|ago_i }}</time>; this page refreshes itself every 30 seconds. Pickup is from when a job could run (queued, its dependencies passed, approved) to when a runner took it.</p>