lib/riemann/dash/views/index.erubis in riemann-dash-0.1.1 vs lib/riemann/dash/views/index.erubis in riemann-dash-0.2.0

- old
+ new

@@ -1,8 +1,202 @@ -<h2>Problems</h2> -<div class="box"><%= state_list query('state != "ok"') %></div> +<!doctype html> +<html> +<head> + <meta charset="UTF-8" /> + <title>Riemann</title> + <link rel="stylesheet" href="/css" type="text/css" /> + <link rel="stylesheet" href="/toastr.css" type="text/css" /> +</head> +<body> + <div id="toolbar"></div> + <div id="view"></div> -<div class="box"> -<%= state_chart query('service = "cpu" or service = "memory" or service =~ "disk%" or service = "load"'), :title => "Health" %> -</div> + <script type="text/javascript" src="/underscore-min.js"></script> + <script type="text/javascript" src="/jquery-1.7.2.min.js"></script> + <script type="text/javascript" src="/jquery-ui-1.9.0.custom.min.js"></script> + <script type="text/javascript" src="/jquery.json-2.2.min.js"></script> + <script type="text/javascript" src="/jquery.simplemodal.1.4.3.min.js"></script> + <script type="text/javascript" src="/toastr.js"></script> + <script type="text/javascript" src="/jquery.quickfit.js"></script> + <script type="text/javascript" src="/util.js"></script> + <script type="text/javascript" src="/mustache.js"></script> + <script src="http://d3js.org/d3.v2.js"></script> + <script type="text/javascript" src="/profile.js"></script> + <script type="text/javascript" src="/clock.js"></script> + <script type="text/javascript" src="/persistence.js"></script> + <script type="text/javascript" src="/keys.js"></script> + <script type="text/javascript" src="/subs.js"></script> + <script type="text/javascript" src="/format.js"></script> + <script type="text/javascript" src="/toolbar.js"></script> + <script type="text/javascript" src="/view.js"></script> + <script type="text/javascript" src="/views/title.js"></script> + <script type="text/javascript" src="/views/help.js"></script> + <script type="text/javascript" src="/views/gauge.js"></script> + <script type="text/javascript" src="/views/grid.js"></script> + <script type="text/javascript" src="/dash.js"></script> -<div class="box"><%= state_chart query('true'), :title => "Everything" %></div> + <script type="text/javascript"> +function logTable(container, query) { + var $container = $(container); + $container.addClass("log-table"); + $container.append('<input type="text" class="query"></input>'); + var prompt = $container.find('input'); + $container.append('<div class="scroll"><table><thead><tr>' + + '<th>host</th>' + + '<th>service</th>' + + '<th>state</th>' + + '<th>metric</th>' + + '<th>description</th>' + + '</tr></thead><tbody></tbody></table></div>'); + var scroll = $container.find('.scroll'); + var log = $container.find('tbody'); + var sub = null; + var tracking = true; + + var template = "<tr><td>{{host}}</td><td>{{service}}</td><td>{{state}}</td><td>{{{metric}}}</td><td>{{description}}</td></tr>"; + + // Are we following the bottom of the log? + scroll.scroll(function(e) { + if (scroll.scrollTop() > (log.height() - scroll.height())) { + tracking = true; + } else { + tracking = false; + } + }); + + var scrollToBottom = function() { + scroll.stop().animate({ + scrollTop: (log.height() - scroll.height() + 20) + }, 1000, "swing"); + } + + var atBottom = function() { + console.log(scroll.scrollTop()); + console.log(log.height() - scroll.height()); + return (scroll.scrollTop() > (log.height() - scroll.height())); + } + + // Add an event + var append = function(e) { + $.extend(e, { + metric: format.metric(e) + }); + log.append(Mustache.render(template, e)); + if (tracking) { scrollToBottom() }; + } + + // Set up our query + var startQuery = function(query) { + // Cancel existing sub + if (sub != null) { sub.close(); } + + // Subscribe + sub = subs.subscribe(query, function(e) { + e.time = d3.time.format.iso.parse(e.time); + clock.advance(e.time); + append(e); + }); + } + + // Initial subscription + if (query) { prompt[0].value = query; startQuery(query); } + + // Prompt entry + prompt.change(function() { startQuery(this.value) }); +} + + +function timeSeries(container) { + // Container + var $container = $(container); + var container = d3.select(container); + $container.append('<input type=\"text\" style="display: block"></input>'); + var prompt = $container.children().last(); + + // Data structures + var data = []; + var n = 60; + var sub = null; + + // Scale + var w = 20; + var h = 80; + + var x = d3.time.scale() + .domain([0,1]) + .range([0, w * n]); + var y = d3.scale.linear() + .domain([0,100]) + .rangeRound([0,h]); + + var updateTime = function(max) { + var min = d3.time.minute.offset(max, -1); + x.domain([min, max]); + } + updateTime(new Date()); + + // Chart itself + var chart = container.append("svg") + .attr("class", "timeSeries") + .attr("width", w * (n - 1)) + .attr("height", h); + + // Baseline + chart.append("line") + .attr("x1", 0) + .attr("x2", w * n) + .attr("y1", h - .5) + .attr("y2", h - .5) + .style("stroke", "#000"); + + // Subscribe + prompt.change(function() { + if (sub != null) { sub.close(); } + + sub = subscribe(this.value, function(e) { + // Move time + e.time = d3.time.format.iso.parse(e.time); + clock.advance(e.time); + + // Append to window + if (data.length >= n) { + data.shift(); + } + data.push(e); + + console.log(e.time, "maps to", x(e.time), "in", x.domain(), x.range()); + }); + }); + + var clockSub = clock.register(function(t) { + updateTime(t); + + // Move events + var rect = chart.selectAll("rect") + .data(data, function(e) { if (e) { return e.time } }); + + rect.enter().insert("rect", "line") + .attr("x", function(e, i) { + return x(e.time) - .5; }) + .attr("y", function(e) { return h - y(e.metric) - .5 }) + .attr("width", w) + .attr("height", function(e) { return y(e.metric); }) + .transition() + .duration(1000) + .attr("x", function(e, i) { return x(e.time) - .5 }); + + rect.transition() + .duration(1000) + .attr("x", function(e) { return x(e.time) - .5; }); + + rect.exit().transition() + .duration(1000) + .attr("x", function(e) { return x(e.time) - .5 }) + .remove(); + }); + +} + + dash.reload(); + </script> +</body> +</html>