riemann-dash 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|