riemann-dash 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +7 -7
- data/README.markdown +3 -2
- data/lib/riemann/dash/config.rb +3 -0
- data/lib/riemann/dash/public/dash.js +11 -0
- data/lib/riemann/dash/public/format.js +10 -2
- data/lib/riemann/dash/public/keys.js +0 -2
- data/lib/riemann/dash/public/subs.js +29 -6
- data/lib/riemann/dash/public/toolbar.js +40 -0
- data/lib/riemann/dash/public/views/flot.js +46 -13
- data/lib/riemann/dash/public/views/gauge.js +7 -3
- data/lib/riemann/dash/public/views/grid.js +43 -43
- data/lib/riemann/dash/version.rb +1 -1
- data/lib/riemann/dash/views/index.erubis +32 -32
- metadata +3 -3
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
|
4
|
+
riemann-dash (0.2.5)
|
5
5
|
erubis (>= 2.7.0)
|
6
6
|
multi_json (= 1.3.6)
|
7
7
|
riemann-client (>= 0.0.7)
|
@@ -25,23 +25,23 @@ GEM
|
|
25
25
|
method_source (~> 0.8)
|
26
26
|
slop (~> 3.4)
|
27
27
|
rack (1.5.2)
|
28
|
-
rack-protection (1.
|
28
|
+
rack-protection (1.5.0)
|
29
29
|
rack
|
30
|
-
riemann-client (0.
|
30
|
+
riemann-client (0.2.2)
|
31
31
|
beefcake (>= 0.3.5)
|
32
32
|
mtrc (>= 0.0.4)
|
33
33
|
trollop (>= 1.16.2)
|
34
34
|
sass (3.2.7)
|
35
|
-
sinatra (1.3.
|
35
|
+
sinatra (1.3.6)
|
36
36
|
rack (~> 1.4)
|
37
37
|
rack-protection (~> 1.3)
|
38
38
|
tilt (~> 1.3, >= 1.3.3)
|
39
39
|
slop (3.4.3)
|
40
|
-
thin (1.5.
|
40
|
+
thin (1.5.1)
|
41
41
|
daemons (>= 1.0.9)
|
42
42
|
eventmachine (>= 0.12.6)
|
43
43
|
rack (>= 1.0.0)
|
44
|
-
tilt (1.
|
44
|
+
tilt (1.4.1)
|
45
45
|
trollop (2.0)
|
46
46
|
|
47
47
|
PLATFORMS
|
@@ -49,4 +49,4 @@ PLATFORMS
|
|
49
49
|
|
50
50
|
DEPENDENCIES
|
51
51
|
pry
|
52
|
-
|
52
|
+
riemann-dash!
|
data/README.markdown
CHANGED
@@ -22,7 +22,8 @@ directory: config.rb. That file can override any configuration options on the
|
|
22
22
|
Dash class, and hence, all Sinatra configuration.
|
23
23
|
|
24
24
|
``` ruby
|
25
|
-
set :port, 6000
|
25
|
+
set :port, 6000 # HTTP server on port 6000
|
26
|
+
set :bind, "1.2.3.4" # Bind to a different interface
|
26
27
|
config[:ws_config] = 'custom/config.json' # Specify custom workspace config
|
27
28
|
```
|
28
29
|
|
@@ -49,4 +50,4 @@ REPL
|
|
49
50
|
====
|
50
51
|
$ sh/c
|
51
52
|
> irb :001 > Riemann::Dash::VERSION
|
52
|
-
> => "0.2.2"
|
53
|
+
> => "0.2.2"
|
data/lib/riemann/dash/config.rb
CHANGED
@@ -142,6 +142,9 @@ class Riemann::Dash::Config
|
|
142
142
|
# Server
|
143
143
|
new_config['server'] = update['server'] or old['server']
|
144
144
|
|
145
|
+
# Server Type
|
146
|
+
new_config['server_type'] = update['server_type'] or old['server_type']
|
147
|
+
|
145
148
|
#p update['workspaces']
|
146
149
|
new_config['workspaces'] = update['workspaces'] or old['workspaces']
|
147
150
|
|
@@ -134,8 +134,11 @@ dash = (function() {
|
|
134
134
|
persistence.load(function(config) {
|
135
135
|
// Server
|
136
136
|
var server = config.server || '127.0.0.1:5556';
|
137
|
+
var server_type = config.server_type || "ws";
|
137
138
|
subs.server(server);
|
139
|
+
subs.server_type(server_type);
|
138
140
|
toolbar.server(server);
|
141
|
+
toolbar.server_type(server_type);
|
139
142
|
|
140
143
|
// Workspaces
|
141
144
|
if (config.workspaces) {
|
@@ -173,6 +176,7 @@ dash = (function() {
|
|
173
176
|
persistence.save(
|
174
177
|
{
|
175
178
|
server: toolbar.server(),
|
179
|
+
server_type: toolbar.server_type(),
|
176
180
|
workspaces: workspaces
|
177
181
|
},
|
178
182
|
function() { toastr.info("Configuration saved.") },
|
@@ -235,6 +239,13 @@ dash = (function() {
|
|
235
239
|
switchWorkspace(currentWorkspace());
|
236
240
|
});
|
237
241
|
|
242
|
+
toolbar.onServerTypeChange(function (server_type) {
|
243
|
+
console.log("Server type changed to", server_type);
|
244
|
+
subs.server_type(server_type);
|
245
|
+
// Reload view.
|
246
|
+
switchWorkspace(currentWorkspace());
|
247
|
+
});
|
248
|
+
|
238
249
|
// Handle toolbar workspace switching.
|
239
250
|
toolbar.onWorkspaceSwitch(function(workspace) {
|
240
251
|
switchWorkspace(workspace);
|
@@ -1,9 +1,17 @@
|
|
1
1
|
var format = (function() {
|
2
2
|
|
3
|
-
var formatFloat = function(number, precision) {
|
3
|
+
var formatFloat = function(number, precision, commas) {
|
4
4
|
precision = precision || 2;
|
5
5
|
var base = Math.pow(10, precision);
|
6
|
-
|
6
|
+
var val = Math.round(number * base) / base;
|
7
|
+
|
8
|
+
if(!commas) {
|
9
|
+
return val;
|
10
|
+
}
|
11
|
+
|
12
|
+
var parts = (val + '').split(".");
|
13
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
14
|
+
return parts.join(".");
|
7
15
|
}
|
8
16
|
|
9
17
|
var metricTemplate = _.template('<div class="bar {{state}}" style="width: {{percent}}%">{{metric}}</div>');
|
@@ -3,6 +3,9 @@ var subs = (function() {
|
|
3
3
|
// What server shall we connect to by default?
|
4
4
|
var server;
|
5
5
|
|
6
|
+
// What type of connection should we emit ?
|
7
|
+
var server_type;
|
8
|
+
|
6
9
|
// Subscription ID counter.
|
7
10
|
var id_counter = -1;
|
8
11
|
|
@@ -54,24 +57,36 @@ var subs = (function() {
|
|
54
57
|
},
|
55
58
|
|
56
59
|
isOpen: function() {
|
57
|
-
|
60
|
+
if (server_type == "ws") {
|
61
|
+
return this.ws && (this.ws.readyState != EventSource.CLOSED)
|
62
|
+
} else {
|
63
|
+
return this.ws && (this.ws.readyState != WebSocket.CLOSED)
|
64
|
+
}
|
58
65
|
},
|
59
66
|
isClosed: function() { return !this.isOpen() },
|
60
67
|
|
61
68
|
url: function() {
|
62
69
|
var queryString = "query=" + encodeURIComponent(this.query);
|
63
70
|
var loc = window.location, ws_uri;
|
64
|
-
|
65
|
-
|
71
|
+
|
72
|
+
if (server_type == "sse") {
|
73
|
+
return loc.protocol + "//" + server + "/index?" + queryString;
|
66
74
|
} else {
|
67
|
-
|
75
|
+
ws_uri = (loc.protocol == "https:") ? "wss://" : "ws://";
|
76
|
+
return ws_uri + server + "/index?subscribe=true&" + queryString;
|
68
77
|
}
|
69
|
-
return ws_uri + server + "/index?subscribe=true&" + queryString;
|
70
78
|
},
|
71
79
|
|
72
80
|
open: function() {
|
73
81
|
if (this.isOpen()) return this;
|
74
|
-
|
82
|
+
console.log("will open url: " + this.url());
|
83
|
+
|
84
|
+
var ws;
|
85
|
+
if (server_type == "sse") {
|
86
|
+
ws = this.ws = new EventSource(this.url());
|
87
|
+
} else {
|
88
|
+
ws = this.ws = new WebSocket(this.url());
|
89
|
+
}
|
75
90
|
|
76
91
|
ws.onopen = _.bind(function() {
|
77
92
|
console.log("Socket opened", this.query);
|
@@ -184,6 +199,14 @@ var subs = (function() {
|
|
184
199
|
server = s;
|
185
200
|
return s;
|
186
201
|
}
|
202
|
+
},
|
203
|
+
server_type: function(s) {
|
204
|
+
if (s === undefined) {
|
205
|
+
return server_type;
|
206
|
+
} else {
|
207
|
+
server_type = s;
|
208
|
+
return s;
|
209
|
+
}
|
187
210
|
}
|
188
211
|
};
|
189
212
|
})();
|
@@ -7,7 +7,12 @@ var toolbar = (function() {
|
|
7
7
|
var pager = $('<div class="pager">');
|
8
8
|
var load = $('<div class="load"><div class="bar load1" /><div class="bar load5" /><span title="1- and 5-second subscription manager load averages">Load</span></div>');
|
9
9
|
var server = $('<input class="server" type="text" name="text">');
|
10
|
+
var server_type = $('<div class="server"><label><input type="radio" id="ws" name="server_type" value="ws" checked>websockets</label><input type="radio" id="sse" name="server_type" value="sse">sse</label></div>');
|
11
|
+
var server_type_selector = $("input[name=server_type]");
|
12
|
+
var server_type_sse_selector = $("input#ws");
|
13
|
+
var server_type_ws_selector = $("input#sse");
|
10
14
|
form.append(pager);
|
15
|
+
form.append(server_type);
|
11
16
|
form.append(server);
|
12
17
|
form.append(load);
|
13
18
|
form.submit(function(e) {
|
@@ -28,12 +33,17 @@ var toolbar = (function() {
|
|
28
33
|
|
29
34
|
// Callbacks
|
30
35
|
var onServerChangeCallbacks = [];
|
36
|
+
var onServerTypeChangeCallbacks = [];
|
31
37
|
|
32
38
|
// React to server being set.
|
33
39
|
var onServerChange = function(callback) {
|
34
40
|
onServerChangeCallbacks.push(callback);
|
35
41
|
}
|
36
42
|
|
43
|
+
var onServerTypeChange = function(callback) {
|
44
|
+
onServerTypeChangeCallbacks.push(callback);
|
45
|
+
}
|
46
|
+
|
37
47
|
// When server is set, call callbacks.
|
38
48
|
server.change(function() {
|
39
49
|
onServerChangeCallbacks.forEach(function(f) {
|
@@ -41,6 +51,21 @@ var toolbar = (function() {
|
|
41
51
|
});
|
42
52
|
server.blur();
|
43
53
|
});
|
54
|
+
|
55
|
+
// When server_type is set, call callbacks.
|
56
|
+
$('input#ws').change(function(e) {
|
57
|
+
onServerTypeChangeCallbacks.forEach(function(f) {
|
58
|
+
f($("input[name=server_type]:checked").val());
|
59
|
+
});
|
60
|
+
server.blur();
|
61
|
+
});
|
62
|
+
|
63
|
+
$('input#sse').change(function(e) {
|
64
|
+
onServerTypeChangeCallbacks.forEach(function(f) {
|
65
|
+
f($("input[name=server_type]:checked").val());
|
66
|
+
});
|
67
|
+
server.blur();
|
68
|
+
});
|
44
69
|
|
45
70
|
// Suppress keybindings
|
46
71
|
server.focus(keys.disable);
|
@@ -205,7 +230,22 @@ var toolbar = (function() {
|
|
205
230
|
return s;
|
206
231
|
}
|
207
232
|
},
|
233
|
+
server_type: function(s) {
|
234
|
+
if (s === undefined) {
|
235
|
+
return $("input[name=server_type]:checked").val();
|
236
|
+
} else {
|
237
|
+
console.log("handling server_type: " + s);
|
238
|
+
if (s == "sse") {
|
239
|
+
$("input[name=server_type]#sse").attr("checked",true);
|
240
|
+
} else if (s == "ws") {
|
241
|
+
$("input[name=server_type]#ws").attr("checked",true);
|
242
|
+
}
|
243
|
+
return s;
|
244
|
+
}
|
245
|
+
},
|
246
|
+
|
208
247
|
onServerChange: onServerChange,
|
248
|
+
onServerTypeChange: onServerTypeChange,
|
209
249
|
onWorkspaceChange: onWorkspaceChange,
|
210
250
|
onWorkspaceReorder: onWorkspaceReorder,
|
211
251
|
onWorkspaceSwitch: onWorkspaceSwitch,
|
@@ -5,6 +5,8 @@
|
|
5
5
|
view.View.call(this, json);
|
6
6
|
this.query = json.query;
|
7
7
|
this.title = json.title;
|
8
|
+
this.graphType = json.graphType || 'line';
|
9
|
+
this.stackMode = json.stackMode || 'false';
|
8
10
|
this.lineWidth = json.lineWidth || 1;
|
9
11
|
this.timeRange = (json.timeRange * 1000) || 300000;
|
10
12
|
|
@@ -56,7 +58,7 @@
|
|
56
58
|
}
|
57
59
|
);
|
58
60
|
}
|
59
|
-
}
|
61
|
+
};
|
60
62
|
|
61
63
|
// Set up our FlotView class and register it with the view system
|
62
64
|
view.inherit(view.View, FlotView);
|
@@ -95,7 +97,7 @@
|
|
95
97
|
max: t
|
96
98
|
}
|
97
99
|
});
|
98
|
-
}
|
100
|
+
};
|
99
101
|
|
100
102
|
// Re-order the data list and series index to be in sorted order by label.
|
101
103
|
FlotView.prototype.resortSeries = function() {
|
@@ -137,16 +139,35 @@
|
|
137
139
|
|
138
140
|
// If this is a new series, add it.
|
139
141
|
if (this.series[key] === undefined) {
|
140
|
-
|
142
|
+
var seriesOptions = {
|
141
143
|
riemannKey: key,
|
142
144
|
riemannHost: event.host || 'nil',
|
143
145
|
riemannService: event.service || 'nil',
|
144
|
-
lineWidth: this.lineWidth,
|
145
146
|
shadowSize: 0,
|
146
147
|
data: []
|
147
|
-
}
|
148
|
+
};
|
149
|
+
|
150
|
+
switch(this.graphType) {
|
151
|
+
case 'line':
|
152
|
+
seriesOptions.lineWidth = this.lineWidth;
|
153
|
+
seriesOptions.lines = {
|
154
|
+
show: true,
|
155
|
+
fill: this.stackMode === 'true'
|
156
|
+
};
|
157
|
+
break;
|
158
|
+
case 'bar':
|
159
|
+
seriesOptions.bars = {show: true, fill: true};
|
160
|
+
break;
|
161
|
+
}
|
162
|
+
|
163
|
+
if (this.stackMode === 'true') {
|
164
|
+
seriesOptions.stack = true;
|
165
|
+
}
|
166
|
+
|
167
|
+
this.data.push(seriesOptions);
|
148
168
|
this.resortSeries();
|
149
169
|
}
|
170
|
+
|
150
171
|
var series = this.data[this.series[key]].data;
|
151
172
|
|
152
173
|
// Add event to series
|
@@ -160,11 +181,11 @@
|
|
160
181
|
if (this.graph) {
|
161
182
|
this.graph.setData(this.data);
|
162
183
|
}
|
163
|
-
}
|
184
|
+
};
|
164
185
|
|
165
186
|
// Clean up old data points.
|
166
187
|
FlotView.prototype.trimData = function(t) {
|
167
|
-
|
188
|
+
t = t - this.timeRange;
|
168
189
|
var empties = false;
|
169
190
|
|
170
191
|
_.each(this.data, function(s) {
|
@@ -187,7 +208,7 @@
|
|
187
208
|
});
|
188
209
|
this.resortSeries();
|
189
210
|
}
|
190
|
-
}
|
211
|
+
};
|
191
212
|
|
192
213
|
// Serialize current state to JSON
|
193
214
|
FlotView.prototype.json = function() {
|
@@ -195,14 +216,26 @@
|
|
195
216
|
type: 'Flot',
|
196
217
|
title: this.title,
|
197
218
|
query: this.query,
|
198
|
-
timeRange: this.timeRange / 1000
|
219
|
+
timeRange: this.timeRange / 1000,
|
220
|
+
graphType: this.graphType,
|
221
|
+
stackMode: this.stackMode
|
199
222
|
});
|
200
|
-
}
|
223
|
+
};
|
201
224
|
|
202
225
|
// HTML template used to edit this view
|
203
226
|
var editTemplate = _.template(
|
204
227
|
'<label for="title">title</label>' +
|
205
228
|
'<input type="text" name="title" value="{{title}}" /><br />' +
|
229
|
+
'<label for="graphType">Graph Type</label>' +
|
230
|
+
'<select name="graphType">' +
|
231
|
+
'<option value="line" {% if(graphType == \'line\') print(\'selected\') %}>Line</option>' +
|
232
|
+
'<option value="bar" {% if(graphType == \'bar\') print(\'selected\') %}>Bar</option>' +
|
233
|
+
'</select>' +
|
234
|
+
'<label for="stackMode">Stack Mode</label>' +
|
235
|
+
'<select name="stackMode">' +
|
236
|
+
'<option value="true" {% if(stackMode == \'true\') print(\'selected\') %}>Stacked</option>' +
|
237
|
+
'<option value="false" {% if(stackMode == \'false\') print(\'selected\') %}>Normal</option>' +
|
238
|
+
'</select><br />' +
|
206
239
|
'<label for="query">query</label>' +
|
207
240
|
'<textarea type="text" class="query" name="query">{{ query }}</textarea><br />' +
|
208
241
|
'<label for="timeRange">Time range (s)</label>' +
|
@@ -227,12 +260,12 @@
|
|
227
260
|
this.graph.setupGrid();
|
228
261
|
this.graph.draw();
|
229
262
|
}
|
230
|
-
}
|
263
|
+
};
|
231
264
|
|
232
265
|
// Called when our parent needs to resize us
|
233
266
|
FlotView.prototype.reflow = function() {
|
234
267
|
this.reflowGraph();
|
235
|
-
}
|
268
|
+
};
|
236
269
|
|
237
270
|
// When the view is deleted, remove our subscription
|
238
271
|
FlotView.prototype.delete = function() {
|
@@ -243,6 +276,6 @@
|
|
243
276
|
subs.unsubscribe(this.sub);
|
244
277
|
}
|
245
278
|
view.View.prototype.delete.call(this);
|
246
|
-
}
|
279
|
+
};
|
247
280
|
})();
|
248
281
|
|
@@ -5,6 +5,7 @@
|
|
5
5
|
view.View.call(this, json);
|
6
6
|
this.query = json.query;
|
7
7
|
this.title = json.title;
|
8
|
+
this.commaSeparateThousands = json.commaSeparateThousands;
|
8
9
|
this.clickFocusable = true;
|
9
10
|
this.el.addClass('gauge');
|
10
11
|
this.el.append(
|
@@ -23,7 +24,7 @@
|
|
23
24
|
var value = this.el.find('.value');
|
24
25
|
this.sub = subs.subscribe(this.query, function(e) {
|
25
26
|
me.box.attr('class', 'box state ' + e.state);
|
26
|
-
value.text(format.float(e.metric));
|
27
|
+
value.text(format.float(e.metric, 2, me.commaSeparateThousands));
|
27
28
|
value.attr('title', e.description);
|
28
29
|
|
29
30
|
// The first time, do a full-height reflow.
|
@@ -45,7 +46,8 @@
|
|
45
46
|
return $.extend(view.View.prototype.json.call(this), {
|
46
47
|
type: 'Gauge',
|
47
48
|
title: this.title,
|
48
|
-
query: this.query
|
49
|
+
query: this.query,
|
50
|
+
commaSeparateThousands: this.commaSeparateThousands
|
49
51
|
});
|
50
52
|
}
|
51
53
|
|
@@ -53,7 +55,9 @@
|
|
53
55
|
"<label for='title'>Title</label>" +
|
54
56
|
"<input type='text' name='title' value='{{title}}' /><br />" +
|
55
57
|
"<label for='query'>Query</label>" +
|
56
|
-
'<textarea type="text" name="query" class="query">{{query}}</textarea>'
|
58
|
+
'<textarea type="text" name="query" class="query">{{query}}</textarea>' +
|
59
|
+
"<label for='commaSeparateThousands'>Comma Separate Thousands</label>" +
|
60
|
+
"<input type='checkbox' name='commaSeparateThousands' {% if(commaSeparateThousands) { %} checked='checked' {% } %} />" );
|
57
61
|
|
58
62
|
Gauge.prototype.editForm = function() {
|
59
63
|
return editTemplate(this);
|
@@ -19,9 +19,9 @@
|
|
19
19
|
|
20
20
|
// Property access
|
21
21
|
return function(e) {
|
22
|
-
return e[str]
|
23
|
-
}
|
24
|
-
}
|
22
|
+
return e[str];
|
23
|
+
};
|
24
|
+
};
|
25
25
|
|
26
26
|
// Takes a string and returns either:
|
27
27
|
// - a function which extracts a maximum value from an event.
|
@@ -29,15 +29,15 @@
|
|
29
29
|
var max_fn = function(str) {
|
30
30
|
if ((!str) || str === "all") {
|
31
31
|
// Always the same value: global maxima
|
32
|
-
return function(e) { return "all" };
|
32
|
+
return function(e) { return "all"; };
|
33
33
|
}
|
34
34
|
if (isNaN(parseFloat(str))) {
|
35
35
|
// Not a number. Extract a field.
|
36
|
-
return function(e) { return e[str] };
|
36
|
+
return function(e) { return e[str]; };
|
37
37
|
}
|
38
38
|
// Return a constant number.
|
39
39
|
return parseFloat(str);
|
40
|
-
}
|
40
|
+
};
|
41
41
|
|
42
42
|
var Grid = function(json) {
|
43
43
|
// We want a per-grid slurred rendering.
|
@@ -80,7 +80,7 @@
|
|
80
80
|
me.update.call(me, e);
|
81
81
|
});
|
82
82
|
}
|
83
|
-
}
|
83
|
+
};
|
84
84
|
|
85
85
|
view.inherit(view.View, Grid);
|
86
86
|
view.Grid = Grid;
|
@@ -95,7 +95,7 @@
|
|
95
95
|
rows: this.rows_str,
|
96
96
|
cols: this.cols_str
|
97
97
|
});
|
98
|
-
}
|
98
|
+
};
|
99
99
|
|
100
100
|
var editTemplate = _.template(
|
101
101
|
"<label for='title'>Title</label>" +
|
@@ -110,21 +110,21 @@
|
|
110
110
|
"<label for='max'>Max</label>" +
|
111
111
|
"<input type='text' name='max' value=\"{{-max}}\" /><br />" +
|
112
112
|
"<span class='desc'>'all', 'host', 'service', or any number.</span>"
|
113
|
-
)
|
113
|
+
);
|
114
114
|
|
115
115
|
Grid.prototype.editForm = function() {
|
116
116
|
return editTemplate(this);
|
117
|
-
}
|
117
|
+
};
|
118
118
|
|
119
119
|
// Returns all events, flat.
|
120
120
|
Grid.prototype.allEvents = function() {
|
121
121
|
var events = [];
|
122
|
-
for (row in this.events) {
|
123
|
-
for (column in this.events[row]) {
|
122
|
+
for (var row in this.events) {
|
123
|
+
for (var column in this.events[row]) {
|
124
124
|
events.push(this.events[row][column]);
|
125
125
|
}
|
126
126
|
}
|
127
|
-
}
|
127
|
+
};
|
128
128
|
|
129
129
|
// What is the maximum for this event?
|
130
130
|
Grid.prototype.eventMax = function(event) {
|
@@ -136,7 +136,7 @@
|
|
136
136
|
var max_key = this.max_fn(event);
|
137
137
|
return this.maxima[this.max_fn(event)] || -1/0;
|
138
138
|
}
|
139
|
-
}
|
139
|
+
};
|
140
140
|
|
141
141
|
// Generates a td cell for an event. Returns a map of the td, bar, and metric
|
142
142
|
// elements.
|
@@ -145,7 +145,7 @@
|
|
145
145
|
var bar = td.find('.bar');
|
146
146
|
var metric = td.find('.metric');
|
147
147
|
return {td: td, bar: bar, metric: metric};
|
148
|
-
}
|
148
|
+
};
|
149
149
|
|
150
150
|
// Update a single jq element with information about an event.
|
151
151
|
Grid.prototype.renderElement = function(e, event) {
|
@@ -163,14 +163,14 @@
|
|
163
163
|
|
164
164
|
// Description
|
165
165
|
e.td.attr('title', event.host + ' ' + event.service + "\n" +
|
166
|
-
event.state + ' at ' + event.time + "\n\n" +
|
166
|
+
event.state + ' at ' + new Date(event.time).toString() + "\n\n" +
|
167
167
|
event.description);
|
168
168
|
|
169
169
|
// Metric
|
170
170
|
e.metric.text(format.float(event.metric));
|
171
171
|
|
172
172
|
// Bar chart
|
173
|
-
if (event.metric
|
173
|
+
if (event.metric === 0) {
|
174
174
|
// Zero
|
175
175
|
e.bar.css('width', 0);
|
176
176
|
} else if (0 < event.metric) {
|
@@ -181,7 +181,7 @@
|
|
181
181
|
// Nil or negative
|
182
182
|
e.bar.css('width', 0);
|
183
183
|
}
|
184
|
-
}
|
184
|
+
};
|
185
185
|
|
186
186
|
// Render a single event if there's been no change to table structure.
|
187
187
|
Grid.prototype.partialRender = function(event) {
|
@@ -194,7 +194,7 @@
|
|
194
194
|
|
195
195
|
// Update cache
|
196
196
|
if (!this.elCache[rowKey]) {
|
197
|
-
this.elCache[rowKey] = {}
|
197
|
+
this.elCache[rowKey] = {};
|
198
198
|
}
|
199
199
|
this.elCache[rowKey][colKey] = cache;
|
200
200
|
|
@@ -207,7 +207,7 @@
|
|
207
207
|
}
|
208
208
|
|
209
209
|
this.renderElement(cache, event);
|
210
|
-
}
|
210
|
+
};
|
211
211
|
|
212
212
|
// A full re-rendering of the table.
|
213
213
|
Grid.prototype.render = function() {
|
@@ -219,18 +219,18 @@
|
|
219
219
|
var rowPrefix = strings.commonPrefix(this.rows);
|
220
220
|
var colPrefixLen = colPrefix.length;
|
221
221
|
var rowPrefixLen = rowPrefix.length;
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
var shortRowNames = _.map(this.rows, function(s) {
|
229
|
-
if (s) {
|
230
|
-
return s.substring(rowPrefixLen);
|
222
|
+
|
223
|
+
var shortener = function(fieldLen, s) {
|
224
|
+
var res = s;
|
225
|
+
if (s && s.length !== fieldLen) {
|
226
|
+
// Avoid trimming if it would trim the entire string.
|
227
|
+
res = s.substring(fieldLen);
|
231
228
|
}
|
232
|
-
return
|
233
|
-
}
|
229
|
+
return res;
|
230
|
+
};
|
231
|
+
|
232
|
+
var shortColNames = _.map(this.cols, _.partial(shortener, colPrefixLen));
|
233
|
+
var shortRowNames = _.map(this.rows, _.partial(shortener, rowPrefixLen));
|
234
234
|
|
235
235
|
// Header
|
236
236
|
table.append("<thead><tr><th></th></tr></thead>");
|
@@ -264,7 +264,7 @@
|
|
264
264
|
row.append(cache.td);
|
265
265
|
}, this);
|
266
266
|
}, this);
|
267
|
-
}
|
267
|
+
};
|
268
268
|
|
269
269
|
// Update cached maxima with a new event. Returns true if maxima changed.
|
270
270
|
Grid.prototype.updateMax = function(event) {
|
@@ -292,8 +292,8 @@
|
|
292
292
|
// Traverse all events looking for a match.
|
293
293
|
var e;
|
294
294
|
var currentMax = -1/0;
|
295
|
-
for (name in this.events) {
|
296
|
-
for (subName in this.events[name]) {
|
295
|
+
for (var name in this.events) {
|
296
|
+
for (var subName in this.events[name]) {
|
297
297
|
e = this.events[name][subName];
|
298
298
|
if (e.metric && this.max_fn(e) === max_key) {
|
299
299
|
currentMax = Math.max(currentMax, e.metric);
|
@@ -305,7 +305,7 @@
|
|
305
305
|
this.maxima[max_key] = currentMax;
|
306
306
|
|
307
307
|
return true;
|
308
|
-
}
|
308
|
+
};
|
309
309
|
|
310
310
|
// Stores an event in the internal state tables. Returns true if we
|
311
311
|
// haven't seen this host/service before.
|
@@ -336,7 +336,7 @@
|
|
336
336
|
this.events[row_key][col_key] = e;
|
337
337
|
|
338
338
|
return newEvent;
|
339
|
-
}
|
339
|
+
};
|
340
340
|
|
341
341
|
// Add an event.
|
342
342
|
Grid.prototype.add = function(e) {
|
@@ -348,7 +348,7 @@
|
|
348
348
|
} else {
|
349
349
|
this.partialRender(e);
|
350
350
|
}
|
351
|
-
}
|
351
|
+
};
|
352
352
|
|
353
353
|
// Remove an event.
|
354
354
|
Grid.prototype.remove = function(e) {
|
@@ -361,7 +361,7 @@
|
|
361
361
|
delete this.elCache[row_key][col_key];
|
362
362
|
if (_.isEmpty(this.events[row_key])) {
|
363
363
|
delete this.events[row_key];
|
364
|
-
}
|
364
|
+
}
|
365
365
|
}
|
366
366
|
if (_.isEmpty(this.elCache[row_key])) {
|
367
367
|
delete this.events[row_key];
|
@@ -381,25 +381,25 @@
|
|
381
381
|
|
382
382
|
this.updateMax();
|
383
383
|
this.render();
|
384
|
-
}
|
384
|
+
};
|
385
385
|
|
386
386
|
// Accept an event.
|
387
387
|
Grid.prototype.update = function(e) {
|
388
388
|
this.add(e);
|
389
|
-
}
|
389
|
+
};
|
390
390
|
|
391
391
|
Grid.prototype.reflow = function() {
|
392
392
|
// this.el.find('table').height(
|
393
393
|
// this.height() -
|
394
394
|
// this.el.find('h2').height()
|
395
395
|
// );
|
396
|
-
}
|
396
|
+
};
|
397
397
|
|
398
398
|
Grid.prototype.delete = function() {
|
399
|
-
if (this.sub
|
399
|
+
if (this.sub !== undefined) {
|
400
400
|
subs.unsubscribe(this.sub);
|
401
401
|
}
|
402
402
|
this.update = function() {};
|
403
403
|
view.View.prototype.delete.call(this);
|
404
|
-
}
|
404
|
+
};
|
405
405
|
})();
|
data/lib/riemann/dash/version.rb
CHANGED
@@ -3,27 +3,27 @@
|
|
3
3
|
<head>
|
4
4
|
<meta charset="UTF-8" />
|
5
5
|
<title>riemann</title>
|
6
|
-
<link rel="stylesheet" type="text/css" href="
|
7
|
-
<link rel="stylesheet" type="text/css" href="
|
6
|
+
<link rel="stylesheet" type="text/css" href="vendor/toastr/toastr.css" />
|
7
|
+
<link rel="stylesheet" type="text/css" href="css" />
|
8
8
|
</head>
|
9
9
|
<body>
|
10
10
|
<div id="toolbar"></div>
|
11
11
|
<div id="view"></div>
|
12
12
|
|
13
13
|
<!-- begin third party dependencies -->
|
14
|
-
<script src="
|
15
|
-
<script src="
|
16
|
-
<script src="
|
17
|
-
<script src="
|
18
|
-
<script src="
|
19
|
-
<script src="
|
20
|
-
<script src="
|
21
|
-
<script src="
|
22
|
-
<script src="
|
23
|
-
<script src="
|
24
|
-
<script src="
|
25
|
-
<script src="
|
26
|
-
|
14
|
+
<script src="vendor/smoothie.js"></script>
|
15
|
+
<script src="vendor/lodash.min.js"></script>
|
16
|
+
<script src="vendor/jquery/jquery-1.9.1.min.js"></script>
|
17
|
+
<script src="vendor/backbone.js"></script>
|
18
|
+
<script src="vendor/jquery/jquery-ui-1.10.2.custom.min.js"></script>
|
19
|
+
<script src="vendor/jquery/jquery.simplemodal.1.4.4.min.js"></script>
|
20
|
+
<script src="vendor/jquery/jquery.quickfit.js"></script>
|
21
|
+
<script src="vendor/toastr/toastr.js"></script>
|
22
|
+
<script src="vendor/flot/jquery.colorhelpers.min.js"></script>
|
23
|
+
<script src="vendor/flot/jquery.flot.js"></script>
|
24
|
+
<script src="vendor/flot/jquery.flot.canvas.min.js"></script>
|
25
|
+
<script src="vendor/flot/jquery.flot.time.min.js"></script>
|
26
|
+
<script src="vendor/flot/jquery.flot.stack.min.js"></script>
|
27
27
|
<script> // turn underscore templates into mustache style templates
|
28
28
|
_.templateSettings = {
|
29
29
|
evaluate : /\{\%([\s\S]+?)\%\}/g, // {% eval(js); %}
|
@@ -33,23 +33,23 @@
|
|
33
33
|
</script>
|
34
34
|
<!-- end third party deps -->
|
35
35
|
|
36
|
-
<script src="
|
37
|
-
<script src="
|
38
|
-
<script src="
|
39
|
-
<script src="
|
40
|
-
<script src="
|
41
|
-
<script src="
|
42
|
-
<script src="
|
43
|
-
<script src="
|
44
|
-
<script src="
|
45
|
-
<script src="
|
46
|
-
<script src="
|
47
|
-
<script src="
|
48
|
-
<script src="
|
49
|
-
<script src="
|
50
|
-
<script src="
|
51
|
-
<script src="
|
52
|
-
<script src="
|
36
|
+
<script src="util.js"></script>
|
37
|
+
<script src="strings.js"></script>
|
38
|
+
<script src="format.js"></script>
|
39
|
+
<script src="profile.js"></script>
|
40
|
+
<script src="clock.js"></script>
|
41
|
+
<script src="persistence.js"></script>
|
42
|
+
<script src="keys.js"></script>
|
43
|
+
<script src="subs.js"></script>
|
44
|
+
<script src="toolbar.js"></script>
|
45
|
+
<script src="view.js"></script>
|
46
|
+
<script src="views/timeseries.js"></script>
|
47
|
+
<script src="views/flot.js"></script>
|
48
|
+
<script src="views/title.js"></script>
|
49
|
+
<script src="views/help.js"></script>
|
50
|
+
<script src="views/gauge.js"></script>
|
51
|
+
<script src="views/grid.js"></script>
|
52
|
+
<script src="dash.js"></script>
|
53
53
|
|
54
54
|
<script>dash.reload()</script>
|
55
55
|
</body>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riemann-dash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: riemann-client
|
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
222
|
version: '0'
|
223
223
|
requirements: []
|
224
224
|
rubyforge_project: riemann-dash
|
225
|
-
rubygems_version: 1.8.
|
225
|
+
rubygems_version: 1.8.23
|
226
226
|
signing_key:
|
227
227
|
specification_version: 3
|
228
228
|
summary: HTTP dashboard for the distributed event system Riemann.
|