blob: fa55b58ca833f4bcd7b05074e634e06c36d86713 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="/dashboard/static/base.css">
<title>Anomaly Detection Function Debugger</title>
<script src="/jquery/jquery-2.1.4.min.js"></script>
<script src="/flot/jquery.flot.min.js"></script>
<style>
/* The content container contains all the content after the title. */
#content {
margin-left: 20px;
}
/* This class is applied to segment endpoint revision labels. */
.label {
background-color: white;
border: 2px solid #f90;
padding: 2px;
position: absolute;
z-index: 1000;
}
code {
font-weight: bold;
}
</style>
</head>
<body>
{% include 'nav.html' %}
<h1>Anomaly Detection Function Debugger</h1>
<div id="content">
<p>This page shows the results of running the anomaly detection function
on some test data for some anomaly threshold configuration.</p>
{% if plot_data and lookup %}
<p>The test data series is shown in <strong
style="color:#666">grey</strong>. The segment and segment endpoints
are shown in <strong style="color:#f90">orange</strong>; if a
revision is specified, a <strong style="color:blue">blue</strong>
line is also shown indicating the position of the revision.
Above each detected anomaly is a label showing the revision number
and percent change from the median before the anomaly to the median
after the anomaly.</p>
<div id="plot" style="width: 800px; height: 400px"></div>
{% endif %}
{% if error %}
<p class="error">{{error}}</p>
{% endif %}
<!-- Form for changing query parameters. -->
<form method="GET">
<table>
<tr>
<td><label>Test path:</label></td>
<td><input type="text" name="test_path" size="100" value="{{test_path}}"></td>
</tr>
<tr>
<td><label>Target revision:</label></td>
<td><input type="text" name="rev" placeholder="280000" value="{{rev}}"></td>
</tr>
<tr>
<td><label>Number of points before:</label></td>
<td><input type="text" name="num_before" placeholder="50" value="{{num_before}}"></td>
</tr>
<tr>
<td><label>Number of points after:</label></td>
<td><input type="text" name="num_after" placeholder="10" value="{{num_after}}"></td>
</tr>
</table>
<p>Sheriff: {{sheriff_name}}</p>
<label>Threshold configuration: {{config_name}}<br>
<textarea name="config" rows="7" cols="60">{{config_json | safe}}</textarea>
</label>
<input type="submit" value="Update">
</form>
<h2>About the threshold parameters</h2>
<ul>
<li>
<code>max_window_size</code> is the number of points
that's analyzed at once. A larger window size means that more
points before a change-point can be considered. The window is
split into two segments. Must be at least twice as big as the
<code>min_segment_size</code>.
</li>
<li>
<code>min_segment_size</code> determines how many points must
be on both sides of the change-point. A larger value makes it less
sensitive to noise, but it also increases the time before an alert
is fired.
</li>
<li>
<code>min_relative_change</code> is the minimum relative
difference between the median of the points before and the median
of the points after. that's reported. For example, to disallow
alerts for a change of less than 5%, this can be set to 0.05.
</li>
<li>
<code>min_absolute_change</code> sets a threshold on the absolute
difference before and after.
</li>
<li>
<code>multiple_of_std_dev</code> is a threshold on the jump
size measured in multiples of the standard deviation of the
points. For example, a value of 3.0 means that only a jump 3
or more times larger than a sample of points around the change
point is considered.
</li>
<li>
<code>min_steppiness</code> is a measure of how similar the change
is to a perfect step, where 0.0 corresponds to a flat line or
completely random noise, and 1.0 corresponds to a any perfect step.
</li>
</ul>
{% if csv_url %}
<p><a href="{{csv_url}}">Download data as CSV</a></p>
{% endif %}
{% if graph_url %}
<p><a href="{{graph_url}}">See graph</a></p>
{% endif %}
{% if stored_anomalies %}
<h3>Recent Anomaly entities in the datastore for this test:</h3>
<table border="1">
<thead>
<tr>
<th>End Revision</th>
<th>Bug ID</th>
<th>Median before anomaly</th>
<th>Median after anomaly</th>
<th>Percent changed</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
{% for alert in stored_anomalies %}
<tr>
<td>{{alert.revision}}</td>
<td>{{alert.bug_id}}</td>
<td>{{alert.median_before}}</td>
<td>{{alert.median_after}}</td>
<td>{{alert.percent_changed}}</td>
<td>{{alert.timestamp}}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
{% if plot_data and lookup %}
<link rel="import" href="/dashboard/static/debug_alert.html">
<script>
'use strict';
// Array with data series in Flot format. Expected series are:
// [0] Chart data series.
// [1] Anomaly points.
// [2..] Segments and their medians.
var DATA = {{plot_data | safe}};
// Map of indexes to revision numbers.
var LOOKUP = {{lookup | safe}};
// Information returned from the anomaly detection algorithm.
var ANOMALIES = {{anomalies | safe}};
{% if rev %}
var REVISION = {{rev}};
{% endif %}
</script>
{% endif %}
</body>
</html>