add support for installing the web dashboard

move the web dashboard from config tree into elastic recheck and
make it installable into $prefix/share. Documentation on the expected
way this would work is provided in the web sub tree.

Also ensure that we actually fetch from /elastic-recheck/data as we
expect people to set things up.

Change-Id: I514b6cf2c18bb4d570f830d78e87e713b9c3531e
This commit is contained in:
Sean Dague 2013-12-01 08:52:51 -05:00 committed by James E. Blair
parent 142d520dba
commit 0924c1b12f
5 changed files with 203 additions and 0 deletions

View File

@ -22,6 +22,8 @@ classifier =
[files]
packages =
elastic_recheck
data_files =
share/elastic-recheck = web/share/*
[entry_points]
console_scripts =

32
web/README.rst Normal file
View File

@ -0,0 +1,32 @@
===========================
Elastic Recheck Dashboard
===========================
Elastic Recheck is a handy tool for mining the data in our logstash
environment to categorize race conditions in the OpenStack gate. In
addition to including a number of command line tools, we provide an
html dashboard, because the kids love that html.
Architecture
============
The dashboard currently consists of static html and a set of
javascript libraries, which read json files full of data, and do
client side rendering of graphs. This may change in the future.
Below this tree you'll find a set of sub-directories that assume that
you are running this in an apache environment.
- static files - /usr/share/elastic-recheck
- dynamic json - /var/lib/elastic-recheck
- apache config - /etc/apache/conf.d/elastic-recheck.conf
Json files directory is expected to be mapped to /elastic-recheck/data
and the static files to /elastic-recheck.
Installation
============
At install time for elastic-recheck the static files are installed as
per our assumed location. The apache configuration is not changed,
however an example is provided in the conf directory.

View File

@ -0,0 +1,15 @@
Alias /elastic-recheck /usr/share/elastic-recheck
<Directory /usr/share/elastic-recheck>
Options FollowSymlinks
AllowOverride None
Require all granted
</Directory>
Alias /elastic-recheck/data /usr/share/elastic-recheck/data
<Directory /var/lib/elastic-recheck>
Options FollowSymlinks
AllowOverride None
Require all granted
</Directory>

View File

@ -0,0 +1,90 @@
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
lang="en">
<HEAD>
<TITLE>Elastic Recheck</TITLE>
<script type="text/javascript"
src="http://status.openstack.org/jquery.min.js"></script>
<script type="text/javascript"
src="http://status.openstack.org/jquery-visibility.min.js"></script>
<script type="text/javascript"
src="http://status.openstack.org/jquery-graphite.js"></script>
<script type="text/javascript"
src="http://status.openstack.org/common.js"></script>
<script type="text/javascript"
src="http://status.openstack.org/jquery.flot.min.js"></script>
<script type="text/javascript"
src="http://status.openstack.org/jquery.flot.time.min.js"></script>
<script type="text/javascript"
src="elastic-recheck.js"></script>
<!-- Google Fonts -->
<link href='http://fonts.googleapis.com/css?family=PT+Sans&amp;subset=latin' rel='stylesheet' type='text/css'/>
<!-- Framework CSS -->
<link rel="stylesheet" href="http://www.openstack.org/themes/openstack/css/blueprint/screen.css" type="text/css" media="screen, projection"/>
<link rel="stylesheet" href="http://www.openstack.org/themes/openstack/css/blueprint/print.css" type="text/css" media="print"/>
<!-- IE CSS -->
<!--[if lt IE 8]><link rel="stylesheet" href="http://www.openstack.org/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->
<!-- OpenStack Specific CSS -->
<link rel="stylesheet" href="http://www.openstack.org/themes/openstack/css/dropdown.css" type="text/css" media="screen, projection, print"/>
<!-- Page Specific CSS -->
<link rel="stylesheet" href="http://www.openstack.org/themes/openstack/css/home.css" type="text/css" media="screen, projection, print"/>
<link rel="stylesheet" type="text/css" href="http://www.openstack.org/themes/openstack/css/main.css" />
<style type="text/css">
.graph {
width: 600px;
height: 200px;
margin-bottom: 6px;
}
.extlink {
margin-left: 2em;
margin-right: 2em;
}
.bug-container {
margin-bottom: 2em;
}
</style>
<script type="text/javascript">
</script>
</HEAD>
<BODY>
<script type="text/javascript">header('Rechecks');</script>
<div class="container" id="graph-container">
<script type="text/javascript">
$("#graph-container").append($(new Image()).graphite({
from: "-36hours",
url: "http://graphite.openstack.org/render/",
width: 600,
height: 400,
bgcolor: 'ffffff',
fgcolor: '000000',
target: [
"color(alias(movingAverage(asPercent(stats.zuul.pipeline.gate.job.gate-tempest-dsvm-neutron.FAILURE,sum(stats.zuul.pipeline.gate.job.gate-tempest-dsvm-neutron.{SUCCESS,FAILURE})),200), 'gate-tempest-dsvm-neutron'),'00c868')",
"color(alias(movingAverage(asPercent(stats.zuul.pipeline.check.job.check-tempest-dsvm-neutron.FAILURE,sum(stats.zuul.pipeline.check.job.check-tempest-dsvm-neutron.{SUCCESS,FAILURE})),200), 'check-tempest-dsvm-neutron'),'6464ff')",
"color(alias(movingAverage(asPercent(stats.zuul.pipeline.gate.job.gate-tempest-dsvm-full.FAILURE,sum(stats.zuul.pipeline.gate.job.gate-tempest-dsvm-full.{SUCCESS,FAILURE})),200), 'gate-tempest-dsvm-full'),'00FF00')",
"color(alias(movingAverage(asPercent(stats.zuul.pipeline.check.job.check-tempest-dsvm-full.FAILURE,sum(stats.zuul.pipeline.check.job.check-tempest-dsvm-full.{SUCCESS,FAILURE})),200), 'check-tempest-dsvm-full'),'ffbf52')",
"color(alias(movingAverage(asPercent(stats.zuul.pipeline.check.job.check-grenade-dsvm.FAILURE,sum(stats.zuul.pipeline.check.job.check-grenade-dsvm.{SUCCESS,FAILURE})),200), 'check-grenade-dsvm'),'800080')",
],
title: "Gate Failure Rates"
}));
</script>
</div>
<div id="main-container" class="container">
</div>
<script type="text/javascript">footer();</script>
</BODY>
</html>

View File

@ -0,0 +1,64 @@
// Copyright 2013 OpenStack Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
function update() {
$.getJSON('http://status.openstack.org/elastic-recheck/data/graph.json', function(data) {
var seen = [];
$.each(data, function(i, bug) {
var id = 'bug-'+bug['number'];
seen.push(id);
var div = $('#'+id);
if (!div.length) {
div = $('<div/>', {'id': id, 'class': 'bug-container'});
div.appendTo($('#main-container'));
$('<h2/>', {text: 'Bug ' + bug['number']}).appendTo(div);
$('<div/>', {'class': 'graph'}).appendTo(div);
$('<a/>', {
href: 'http://logstash.openstack.org/#'+bug['logstash_query'],
text: 'Logstash'
}).appendTo($('<span/>', {
'class': 'extlink'
}).appendTo(div));
$('<a/>', {
href: 'https://bugs.launchpad.net/bugs/'+bug['number'],
text: 'Launchpad'
}).appendTo($('<span/>', {
'class': 'extlink'
}).appendTo(div));
}
div = div.find(".graph");
if (bug['data'].length > 0) {
$.plot(div, bug['data'],
{xaxis: {
mode: "time"
}}
);
} else {
div.html("No matches");
}
});
$.each($('.bug-container'), function(i, container) {
if (seen.indexOf(container.id) == -1) {
container.remove();
}
});
});
}
$(function() {
update();
});