riemann-dash 0.2.6 → 0.2.7

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f4c289eed32e6170e10dbe98f328ad9eef4be086
4
+ data.tar.gz: 72850ab6107b78532fe7c786aa42d27ec3e3e765
5
+ SHA512:
6
+ metadata.gz: 58bfdfb8cbaff5681efc68a5c3836c47e849b17b9ff80e1895f9e19b31c9364690ae942afee15bde2b8107eec2d2de7326554dd048f4c6165441d897447f79fd
7
+ data.tar.gz: 04db465f234ea5d5e55003d719e8c2026393e6da7a5556b4c0acbff432be56a778102f3177c43546b4d6ad72956b3695e37563936d31759969545d9325d27c11
@@ -1,6 +1,9 @@
1
1
  var format = (function() {
2
2
 
3
3
  var formatFloat = function(number, precision, commas) {
4
+ if (number == null) {
5
+ return null;
6
+ }
4
7
  precision = precision || 2;
5
8
  var base = Math.pow(10, precision);
6
9
  var val = Math.round(number * base) / base;
@@ -14,7 +14,7 @@ var subs = (function() {
14
14
 
15
15
  // Switch to turn on/off event processing
16
16
  var active = true;
17
-
17
+
18
18
  // Error queue for notification
19
19
  var errorQueue = [];
20
20
 
@@ -34,6 +34,7 @@ var subs = (function() {
34
34
 
35
35
  // Closes a subscription and deletes it from the subscription manager.
36
36
  var unsubscribe = function(sub) {
37
+ clock.unsubscribe(sub.clockSub);
37
38
  delete subs[sub.id];
38
39
  return sub.close();
39
40
  }
@@ -48,12 +49,30 @@ var subs = (function() {
48
49
  return sub.open();
49
50
  }
50
51
 
52
+ // Emit an expired event if oldest item from prioqueue is in the past.
53
+ var expire = function(sub, now) {
54
+ prioqueue = subs[sub.id].prioqueue;
55
+ if (prioqueue) {
56
+ bottom = prioqueue.bottomPriority();
57
+ if (bottom) {
58
+ expiry = new Date(bottom);
59
+ if (expiry < now) {
60
+ expired = prioqueue.shift();
61
+ expired.state = 'expired';
62
+ sub.f(expired);
63
+ }
64
+ }
65
+ }
66
+ }
67
+
51
68
  var Subscription = Backbone.Model.extend({
52
69
 
53
70
  initialize: function(id, query, f) {
54
71
  this.id = id;
55
72
  this.query = query;
56
73
  this.f = f;
74
+ this.prioqueue = new PriorityQueue();
75
+ this.clockSub = false;
57
76
  },
58
77
 
59
78
  isOpen: function() {
@@ -109,6 +128,12 @@ var subs = (function() {
109
128
  var event = JSON.parse(e.data);
110
129
  event.time = Date.parse(event.time);
111
130
  clock.advance(event.time);
131
+ if (event.ttl > 0) { // only expired events have no TTL
132
+ this.prioqueue.update(
133
+ {host: event.host, service: event.service},
134
+ event.time + (event.ttl * 1000) // convert TTL to ms
135
+ );
136
+ }
112
137
  this.f(event);
113
138
  }
114
139
  var t2 = Date.now();
@@ -134,6 +159,11 @@ var subs = (function() {
134
159
  var subscribe = function(query, f) {
135
160
  var sub = new Subscription(newId(), query, f).open();
136
161
  subs[sub.id] = sub;
162
+
163
+ sub.clockSub = clock.subscribe(function(now) {
164
+ expire(sub, now);
165
+ });
166
+
137
167
  return sub;
138
168
  }
139
169
 
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Object to be appended in the priority queue.
3
+ *
4
+ * @class
5
+ * @param mixed v
6
+ * @param integer p
7
+ * @author Augusto Pascutti
8
+ */
9
+ var QueueItem = function(v, p) {
10
+ this.value = v;
11
+ this.priority = p;
12
+ };
13
+
14
+ /**
15
+ * Priority queue class.
16
+ *
17
+ * @class
18
+ * @param Function[optional] c Compare function to be used
19
+ * @param integer[optional] m Max number of elements to hold
20
+ * @author Augusto Pascutti
21
+ */
22
+ var PriorityQueue = function(c, m) { this.init(c, m) };
23
+ PriorityQueue.prototype = {
24
+ _queue: [],
25
+ _compare: undefined,
26
+ _size: 0,
27
+
28
+ /**
29
+ * Priority queue class constructor.
30
+ *
31
+ * @class
32
+ * @param Function[optional] compare_function Compare function to be used
33
+ * @param integer[optional] maximum_size Max number of elements to hold
34
+ */
35
+ init: function(compare_function, maximum_size) {
36
+ this._compare = compare_function || undefined;
37
+ this._size = maximum_size || 0 ;
38
+ this.reset();
39
+ },
40
+
41
+ /**
42
+ * Pushes something to the priority queue.
43
+ *
44
+ * @param mixed value
45
+ * @param integer priority
46
+ * @return void
47
+ */
48
+ push: function(value, priority) {
49
+ this._queue.push(new QueueItem(value, priority));
50
+ this._queue.sort(this.compare());
51
+ this._maitain();
52
+ },
53
+
54
+
55
+ /**
56
+ * Update priority of something in the queue. Will silently add it if it
57
+ * doesn't already exist.
58
+ *
59
+ * @param mixed value
60
+ * @param integer priority
61
+ * @return void
62
+ */
63
+ update: function(value, priority) {
64
+ known = false;
65
+ idx = 0;
66
+
67
+ this._queue.forEach(function() {
68
+ if (JSON.stringify(this._queue[idx].value) === JSON.stringify(value)) {
69
+ this._queue[idx].priority = priority;
70
+ known = true;
71
+ return;
72
+ }
73
+ idx++;
74
+ }, this);
75
+
76
+ if (!known) {
77
+ this._queue.push(new QueueItem(value, priority));
78
+ }
79
+ this._queue.sort(this.compare());
80
+ this._maitain();
81
+ },
82
+
83
+ /**
84
+ * Removes the most important item and return its value.
85
+ *
86
+ * @return mixed
87
+ */
88
+ pop: function() {
89
+ item = this._queue.shift();
90
+ this._maitain();
91
+ return (item) ? item.value : undefined;
92
+ },
93
+
94
+ /**
95
+ * Returns most important item value from this queue, without removing it.
96
+ *
97
+ * @return mixed
98
+ */
99
+ top: function() {
100
+ item = this._queue[0];
101
+ return (item) ? item.value : undefined;
102
+ },
103
+
104
+ /**
105
+ * Returns most important item priority from this queue, without removing it.
106
+ *
107
+ * @return mixed
108
+ */
109
+ topPriority: function() {
110
+ item = this._queue[0];
111
+ return (item) ? item.priority : undefined;
112
+ },
113
+
114
+ /**
115
+ * Removes the less important item and return its value.
116
+ *
117
+ * @return mixed
118
+ */
119
+ shift: function() {
120
+ item = this._queue.pop();
121
+ this._maitain();
122
+ return (item) ? item.value : undefined;
123
+ },
124
+
125
+ /**
126
+ * Returns the less important item value, without removing it.
127
+ *
128
+ * @return mixed
129
+ */
130
+ bottom: function() {
131
+ idx = this.length-1;
132
+ item = this._queue[idx];
133
+ return (item) ? item.value : undefined;
134
+ },
135
+
136
+ /**
137
+ * Returns the less important item priority, without removing it.
138
+ *
139
+ * @return mixed
140
+ */
141
+ bottomPriority: function() {
142
+ idx = this.length-1;
143
+ item = this._queue[idx];
144
+ return (item) ? item.priority : undefined;
145
+ },
146
+
147
+ /**
148
+ * Returns the ordered queue as an Array.
149
+ *
150
+ * @return Array
151
+ */
152
+ getArray: function() {
153
+ return this._queue || new Array();
154
+ },
155
+
156
+ /**
157
+ * Resets the queue.
158
+ *
159
+ * @return void
160
+ */
161
+ reset: function() {
162
+ this._queue = [];
163
+ this._maitain();
164
+ },
165
+
166
+ /**
167
+ * Returns the compare function.
168
+ * If no compare function is set, defines a default one.
169
+ *
170
+ * @return Function
171
+ */
172
+ compare: function() {
173
+ if (!this._compare) {
174
+ this._compare = function(a,b) {
175
+ return b.priority - a.priority;
176
+ };
177
+ }
178
+ return this._compare;
179
+ },
180
+
181
+ /**
182
+ * Defines a fixed size to the queue.
183
+ * Zero for no limit and any other number to set it as the highest number
184
+ * of items allowed in this queue.
185
+ *
186
+ * @param integer i
187
+ * @return void
188
+ */
189
+ size: function(i) {
190
+ this._size = i;
191
+ },
192
+
193
+ /**
194
+ * Keeps the size of the queue by removing the less important item of it and length
195
+ * information atribute.
196
+ *
197
+ * @return void
198
+ */
199
+ _maitain: function() {
200
+ this.length = this._queue.length;
201
+ if ( this._size == 0 ) return;
202
+ while (this._size < this.length) {
203
+ this.shift();
204
+ }
205
+ },
206
+ };
@@ -32,6 +32,7 @@
32
32
 
33
33
  // Create local copies of slurred functions
34
34
  this.reflowGraph = util.slur(200, this.reflowGraph);
35
+ this.setGraphData = util.slur(1000, this.setGraphData);
35
36
 
36
37
  // This view can be clicked to focus on it.
37
38
  this.clickFocusable = true;
@@ -48,7 +49,8 @@
48
49
 
49
50
  this.clockSub = clock.subscribe(function(t) {
50
51
  self.trimData(t);
51
- self.setupGraph(t);
52
+ self.updateTime(t);
53
+ // self.setupGraph(t);
52
54
  });
53
55
 
54
56
  // Subscribe to our query
@@ -69,7 +71,10 @@
69
71
  FlotView.prototype.setupGraph = function(t) {
70
72
  if (this.container.width() === 0 ||
71
73
  this.container.height() === 0) {
72
- this.graph = null;
74
+ if (this.graph != null) {
75
+ this.graph.shutdown();
76
+ this.graph = null;
77
+ }
73
78
  return;
74
79
  }
75
80
 
@@ -99,6 +104,20 @@
99
104
  });
100
105
  };
101
106
 
107
+ // Called as the clock advances to new times.
108
+ FlotView.prototype.updateTime = function(t) {
109
+ if (this.graph == null) {
110
+ this.setupGraph(t);
111
+ return;
112
+ }
113
+
114
+ var axis = this.graph.getOptions().xaxes[0];
115
+ axis.min = t - this.timeRange;
116
+ axis.max = t;
117
+ this.graph.setupGrid();
118
+ this.graph.draw();
119
+ }
120
+
102
121
  // Re-order the data list and series index to be in sorted order by label.
103
122
  FlotView.prototype.resortSeries = function() {
104
123
  // Shorten labels
@@ -177,7 +196,11 @@
177
196
  series.push([event.time, event.metric]);
178
197
  }
179
198
 
180
- // Update graph data
199
+ this.setGraphData();
200
+ };
201
+
202
+ // Tells the Flot graph to use our current dataset.
203
+ FlotView.prototype.setGraphData = function() {
181
204
  if (this.graph) {
182
205
  this.graph.setData(this.data);
183
206
  }
@@ -162,12 +162,15 @@
162
162
  e.td.attr('class', "state box " + event.state);
163
163
 
164
164
  // Description
165
- e.td.attr('title', event.host + ' ' + event.service + "\n" +
166
- event.state + ' at ' + new Date(event.time).toString() + "\n\n" +
167
- event.description);
165
+ e.td.attr('title', event.host + ' ' + event.service + "\n" + event.state +
166
+ "\nreceived at " + new Date(event.time).toString() +
167
+ "\nexpiring at " + new Date(event.time + event.ttl * 1000).toString() +
168
+ (event.description ? ("\n\n" + event.description) : ""));
168
169
 
169
170
  // Metric
170
- e.metric.text(format.float(event.metric));
171
+ if (event.metric != undefined) {
172
+ e.metric.text(format.float(event.metric));
173
+ }
171
174
 
172
175
  // Bar chart
173
176
  if (event.metric === 0) {
@@ -354,7 +357,9 @@
354
357
  Grid.prototype.remove = function(e) {
355
358
  var row_key = this.row_fn(e);
356
359
  var col_key = this.col_fn(e);
357
- delete this.events[row_key][col_key];
360
+ if (this.events[row_key] && this.events[row_key][col_key]) {
361
+ delete this.events[row_key][col_key];
362
+ }
358
363
 
359
364
  // Wipe element cache
360
365
  if (this.elCache[row_key]) {
@@ -385,7 +390,11 @@
385
390
 
386
391
  // Accept an event.
387
392
  Grid.prototype.update = function(e) {
388
- this.add(e);
393
+ if (e.state === "expired") {
394
+ this.remove(e);
395
+ } else {
396
+ this.add(e);
397
+ }
389
398
  };
390
399
 
391
400
  Grid.prototype.reflow = function() {
@@ -10,6 +10,7 @@
10
10
  "<p>To save your changes to the server, press s. You can refresh the page, or press r to reload.</p>" +
11
11
  "<p>Make views bigger and smaller with the +/- keys. Pageup selects the parent of the current view. To delete a view, use the delete key.</p>" +
12
12
  "<p>Switch between workspaces with alt-1, alt-2, etc.</p>" +
13
+ "<p>View is an empty space. Title is an editable text title. Fullscreen and Balloon are top-level container views; you probably won't use them. HStack and VStack are the horizontal and vertical container views; they're implicitly created by splits, but you can create them yourself for fine control. Gauge shows a single event. Grid shows a table of events. Timeseries and Flot show metrics over time--Timeseries is deprecated; Flot will probably replace it.</p>" +
13
14
  "<p>My sincere apologies for layout jankiness. There are a few gross bugs and incapabilities in the current hstack/vstack system; if things get really bad, you can always edit ws/config.json on the server. The control scheme will probably change; I appreciate your ideas and patches.</p>" +
14
15
  '</div>'
15
16
  );
@@ -1,4 +1,4 @@
1
1
  module Riemann; end
2
2
  module Riemann::Dash
3
- VERSION = '0.2.6'
3
+ VERSION = '0.2.7'
4
4
  end
@@ -168,18 +168,14 @@ html,table {
168
168
  background: $green;
169
169
  color: #000;
170
170
  }
171
- .state.warning, .bar.warning {
171
+ .state.warning, .state.warn, .bar.warning, .bar.warn {
172
172
  background: $amber;
173
173
  color: #000;
174
174
  }
175
- .state.critical, .state.failure, .bar.critical, .bar.failure {
175
+ .state.critical, .state.failure, .state.err, .bar.critical, .bar.failure, .bar.err {
176
176
  background: $orange;
177
177
  color: #000;
178
178
  }
179
- .state.expired {
180
- background: $purple;
181
- color: #000;
182
- }
183
179
 
184
180
  .view .query {
185
181
  display: block;
@@ -341,6 +337,8 @@ h2 {
341
337
  }
342
338
 
343
339
  .grid {
340
+ white-space: nowrap;
341
+
344
342
  h2 {
345
343
  height: 28px;
346
344
  font-size: 24px;
@@ -376,6 +374,10 @@ h2 {
376
374
  position: absolute;
377
375
  width: 100%;
378
376
  border-spacing: 3px;
377
+
378
+ th {
379
+ text-align: right;
380
+ }
379
381
 
380
382
  thead {
381
383
  margin: 0;
@@ -386,7 +388,7 @@ h2 {
386
388
  position: relative;
387
389
  top: 3px;
388
390
  vertical-align: bottom;
389
- text-align: right;
391
+ text-align: left;
390
392
  }
391
393
  }
392
394
  }
@@ -24,6 +24,7 @@
24
24
  <script src="vendor/flot/jquery.flot.canvas.min.js"></script>
25
25
  <script src="vendor/flot/jquery.flot.time.min.js"></script>
26
26
  <script src="vendor/flot/jquery.flot.stack.min.js"></script>
27
+ <script src="vendor/PriorityQueue.js"></script>
27
28
  <script> // turn underscore templates into mustache style templates
28
29
  _.templateSettings = {
29
30
  evaluate : /\{\%([\s\S]+?)\%\}/g, // {% eval(js); %}
metadata CHANGED
@@ -1,100 +1,88 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riemann-dash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
5
- prerelease:
4
+ version: 0.2.7
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kyle Kingsbury
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-10-21 00:00:00.000000000 Z
11
+ date: 2014-01-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: riemann-client
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 0.0.7
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 0.0.7
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: erubis
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: 2.7.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: 2.7.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: sinatra
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: 1.3.2
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: 1.3.2
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: sass
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: 3.1.14
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: 3.1.14
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: thin
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - '>='
84
74
  - !ruby/object:Gem::Version
85
75
  version: 1.3.1
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - '>='
92
81
  - !ruby/object:Gem::Version
93
82
  version: 1.3.1
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: multi_json
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - '='
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :runtime
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - '='
108
95
  - !ruby/object:Gem::Version
@@ -138,6 +125,7 @@ files:
138
125
  - lib/riemann/dash/public/subs.js
139
126
  - lib/riemann/dash/public/toolbar.js
140
127
  - lib/riemann/dash/public/util.js
128
+ - lib/riemann/dash/public/vendor/PriorityQueue.js
141
129
  - lib/riemann/dash/public/vendor/backbone.js
142
130
  - lib/riemann/dash/public/vendor/flot/jquery.colorhelpers.js
143
131
  - lib/riemann/dash/public/vendor/flot/jquery.colorhelpers.min.js
@@ -204,27 +192,26 @@ files:
204
192
  - test/test_helper.rb
205
193
  homepage: https://github.com/aphyr/riemann-dash
206
194
  licenses: []
195
+ metadata: {}
207
196
  post_install_message:
208
197
  rdoc_options: []
209
198
  require_paths:
210
199
  - lib
211
200
  required_ruby_version: !ruby/object:Gem::Requirement
212
- none: false
213
201
  requirements:
214
- - - ! '>='
202
+ - - '>='
215
203
  - !ruby/object:Gem::Version
216
204
  version: '0'
217
205
  required_rubygems_version: !ruby/object:Gem::Requirement
218
- none: false
219
206
  requirements:
220
- - - ! '>='
207
+ - - '>='
221
208
  - !ruby/object:Gem::Version
222
209
  version: '0'
223
210
  requirements: []
224
211
  rubyforge_project: riemann-dash
225
- rubygems_version: 1.8.23
212
+ rubygems_version: 2.1.11
226
213
  signing_key:
227
- specification_version: 3
214
+ specification_version: 4
228
215
  summary: HTTP dashboard for the distributed event system Riemann.
229
216
  test_files:
230
217
  - test/config_test.rb