Add support for tracking custom metrics
Builds can now emit metrics that Hydra will store in its database and render as time series via flot charts. Typical applications are to keep track of performance indicators, coverage percentages, artifact sizes, and so on. For example, a coverage build can emit the coverage percentage as follows: echo "lineCoverage $pct %" > $out/nix-support/hydra-metrics Graphs of all metrics for a job can be seen at http://.../job/<project>/<jobset>/<job>#tabs-charts Specific metrics are also visible at http://.../job/<project>/<jobset>/<job>/metric/<metric> The latter URL also allows getting the data in JSON format (e.g. via "curl -H 'Accept: application/json'").
This commit is contained in:
@ -106,7 +106,7 @@
|
||||
[% END %]
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="active"><a href="#tabs-summary" data-toggle="tab">Summary</a></li>
|
||||
[% IF isAggregate %]<li><a href="#tabs-constituents" data-toggle="tab">Constituents</a></li>[% END %]
|
||||
<li><a href="#tabs-details" data-toggle="tab">Details</a></li>
|
||||
@ -385,6 +385,25 @@
|
||||
</tr>
|
||||
[% END %]
|
||||
</table>
|
||||
|
||||
[% IF build.finished && build.buildmetrics %]
|
||||
<h3>Metrics</h3>
|
||||
|
||||
<table class="table table-small table-striped table-hover clickable-rows">
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
[% FOREACH metric IN build.buildmetrics %]
|
||||
<tr>
|
||||
<td><tt><a class="row-link" href="[% c.uri_for('/job' project.name jobset.name job.name 'metric' metric.name) %]">[%HTML.escape(metric.name)%]</a></tt></td>
|
||||
<td>[%metric.value%][%metric.unit%]</td>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
[% END %]
|
||||
|
||||
</div>
|
||||
|
||||
<div id="tabs-buildinputs" class="tab-pane">
|
||||
|
@ -566,12 +566,14 @@ BLOCK createChart %]
|
||||
success: function(data) {
|
||||
var ids = [];
|
||||
var d = [];
|
||||
var max = 0;
|
||||
var maxTime = 0;
|
||||
var minTime = Number.MAX_SAFE_INTEGER;
|
||||
data.forEach(function(x) {
|
||||
var t = x.timestamp * 1000;
|
||||
ids[t] = x.id;
|
||||
d.push([t, x.value [% IF yaxis == "mib" %] / (1024.0 * 1024.0)[% END %]]);
|
||||
max = Math.max(t, max);
|
||||
maxTime = Math.max(t, maxTime);
|
||||
minTime = Math.min(t, minTime);
|
||||
});
|
||||
|
||||
var options = {
|
||||
@ -634,7 +636,7 @@ BLOCK createChart %]
|
||||
});
|
||||
|
||||
// Zoom in to the last two months by default.
|
||||
plot.setSelection({ xaxis: { from: max - 60 * 24 * 60 * 60 * 1000, to: max } });
|
||||
plot.setSelection({ xaxis: { from: Math.max(minTime, maxTime - 60 * 24 * 60 * 60 * 1000), to: maxTime } });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -98,6 +98,14 @@ removed or had an evaluation error.</div>
|
||||
|
||||
[% INCLUDE createChart id="output-size" yaxis="mib" dataUrl=c.uri_for('/job' project.name jobset.name job.name 'output-sizes') %]
|
||||
|
||||
[% FOREACH metric IN metrics %]
|
||||
|
||||
<h3>Metric: <tt>[%HTML.escape(metric.name)%]</tt></h3>
|
||||
|
||||
[% INCLUDE createChart id="metric-${metric.name}" dataUrl=c.uri_for('/job' project.name jobset.name job.name 'metric' metric.name) %]
|
||||
|
||||
[% END %]
|
||||
|
||||
</div>
|
||||
|
||||
<div id="tabs-links" class="tab-pane">
|
||||
|
7
src/root/metric.tt
Normal file
7
src/root/metric.tt
Normal file
@ -0,0 +1,7 @@
|
||||
[% WRAPPER layout.tt title="Job metric ‘$metricName’" %]
|
||||
[% PROCESS common.tt %]
|
||||
|
||||
[% INCLUDE includeFlot %]
|
||||
[% INCLUDE createChart id="chart" dataUrl=c.req.uri %]
|
||||
|
||||
[% END %]
|
@ -29,6 +29,10 @@ table.productList {
|
||||
border-spacing: 0em 1em;
|
||||
}
|
||||
|
||||
table.table-small {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
span:target > span.dep-tree-line {
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
|
Reference in New Issue
Block a user