consul-templaterb 1.8.4 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30e36b411332292a31c63add335521285556e3a1e6350ef2a548c9dacf01142c
4
- data.tar.gz: f46920293d0b25fdcbe8ceb27d75faa4cb401f1aa19bd38f952a44a292f44723
3
+ metadata.gz: d17ec48b3c3611a4e49e13ef9daaeeb44f3f6cc02768ccdcd579e64c2af1a7ec
4
+ data.tar.gz: 59300692c12bacfa4e232679fc7568437ebf9fd3ca977161f702b2f1f4666b76
5
5
  SHA512:
6
- metadata.gz: f7ee00e33c8796ee5a6b6483693d6ca49f05959d59c29c184912feb95da44df6659d3dd513105338166906e2098ddd342c374623bef7610b576e3afea9ca37b8
7
- data.tar.gz: '0787cdbfae7aa011793a12be3c6f6ce798b326913aabe430627aa8eb8d9baaaf3bd3a205faa26d5ad3d15e4617fcb882bb91238f54a9f9593bd2d1debb15027f'
6
+ metadata.gz: b3356add5c81df85061ed0810ea6775252044e771ca10cce3cec5a60fc22c9e1f2cd5e60707d90c4e939b061baa3c8c97155ffe7e3fa41b16a195730f3ebbd98
7
+ data.tar.gz: 6f6b3a75a175d7314f8f7b8878c161d283500011beb7b4e21ae9c1a410d326a15ca7d83e135ed4a0a13705995053940036689a6b4cb4f2d249494881013466b1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## (UNRELEASED)
4
4
 
5
+ ## 1.8.5 (December 18, 2018)
6
+
7
+ OPTIMIZATIONS:
8
+
9
+ * Use less memory on the client side for consul-timeline
10
+ * Properly handle multiple instances of JSON file behinf a LB
11
+
5
12
  ## 1.8.3 / 1.8.4 (December 18, 2018)
6
13
 
7
14
  OPTIMIZATIONS:
@@ -185,6 +185,7 @@ module Consul
185
185
  template_info: tpl_info
186
186
  }
187
187
  result = ERB.new(tpl, nil, @trim_mode).result(binding)
188
+ raise "Result is not a string :='#{result}' for #{tpl_file_path}" unless result.is_a?(String)
188
189
  @context = old_value
189
190
  result
190
191
  rescue StandardError => e
@@ -1,5 +1,5 @@
1
1
  module Consul
2
2
  module Async
3
- VERSION = '1.8.4'.freeze
3
+ VERSION = '1.8.5'.freeze
4
4
  end
5
5
  end
@@ -11,13 +11,17 @@
11
11
  </div>
12
12
  <div id="service-wrapper" >
13
13
  <ul id="service-list" class="list-group">
14
- <li onfocus="serviceTimeline.selectService(this)" onclick="serviceTimeline.selectService(this)" value="" class="serviceListItem list-group-item list-group-item-actionn" id="anyService"><div class="statuses float-right"><span id="allServicesCount" class="lookup badge badge-pill badge-secondary">loading&hellip;</span></div><div class="service-name">All</div></li>
14
+ <li onfocus="serviceTimeline.selectService(this)" onclick="serviceTimeline.selectService(this, true)" value="" class="serviceListItem list-group-item list-group-item-actionn" id="anyService"><div class="statuses float-right"><span id="allServicesCount" class="lookup badge badge-pill badge-secondary">loading&hellip;</span></div><div class="service-name">All</div></li>
15
15
  </ul>
16
16
  </div>
17
17
  </div>
18
18
  <div class="col-10 col-m-9">
19
- <div id="autorefresh"><input id="autorefresh-check" type="checkbox" checked><label for="autorefresh-check">Autorefresh</label></div>
20
- <h2 class="text-center" id="service-title"></h2>
19
+ <div id="autorefresh">
20
+ <input id="autorefresh-check" type="checkbox" checked><label for="autorefresh-check">Autorefresh</label><br/>
21
+ <label for="autorefresh-check">Max Rows:</label>
22
+ <input id="maxRows" style="width: 5em;" type="number" min="100" max="<%= (ENV['CONSUL_TIMELINE_BUFFER'] || 10000) %>" step="100" value="5000"/>
23
+ </div>
24
+ <h2 class="text-center" id="service-title" style="clear:both"></h2>
21
25
  <div class="row mb-2">
22
26
  <div class="input-group float-left col-12">
23
27
  <input id="instance-filter" type="search" placeholder="filter events" class="form-control" />
@@ -135,7 +135,7 @@ class ServiceTimeline {
135
135
  setInterval(sT.reloadDataFromJSON, 10000);
136
136
  }, 150);
137
137
  } else {
138
- this.doFilter();
138
+ this.performFiltering($('#instance-filter')[0].value);
139
139
  }
140
140
  }
141
141
 
@@ -182,17 +182,20 @@ class ServiceTimeline {
182
182
  }
183
183
  console.log("Filtering on service", serviceTimeline.serviceInstanceFilter, " with ", matcher, "filterValue:=", filterValue);
184
184
  var isCorrectService = function(){ return true; };
185
+ if (serviceTimeline.serviceInstanceFilter == 'All') {
186
+ serviceTimeline.serviceInstanceFilter = '';
187
+ }
185
188
  if (serviceTimeline.serviceInstanceFilter == ''){
186
189
  var stylesheet = document.getElementById('serviceCol');
187
190
  var txt = '';
188
- if (filterValue) {
191
+ if (filterValue != '') {
189
192
  txt+='tr.filtered { display: none; }';
190
193
  }
191
194
  stylesheet.textContent = txt;
192
195
  } else {
193
196
  var stylesheet = document.getElementById('serviceCol');
194
197
  var txt = '.serviceCol';
195
- if (filterValue) {
198
+ if (filterValue != '') {
196
199
  txt+=',tr.filtered'
197
200
  }
198
201
  for (var i in this.presentServices) {
@@ -203,7 +206,7 @@ class ServiceTimeline {
203
206
  stylesheet.textContent = txt + ' { display: none; }';
204
207
  isCorrectService = function(ui) { return ui.hasClass('srv-' + serviceTimeline.serviceInstanceFilter) };
205
208
  }
206
- if (filterValue) {
209
+ if (filterValue != '') {
207
210
  $("#all-events > tbody").children('tr').each(function (){
208
211
  var ui = $(this);
209
212
  var shouldShow = isCorrectService(ui) && ui.children('.lookup').is(function (){
@@ -226,6 +229,7 @@ class ServiceTimeline {
226
229
  var filterValue = $('#instance-filter')[0].value;
227
230
  if (this.refreshTimeout) {
228
231
  clearTimeout(this.refreshTimeout);
232
+ this.refreshTimeout = null;
229
233
  }
230
234
  this.refreshTimeout = window.setTimeout(function(){
231
235
  serviceTimeline.performFiltering(filterValue);
@@ -238,7 +242,6 @@ class ServiceTimeline {
238
242
  this.selectedService = source.closest('li');
239
243
  $(this.selectedService).addClass('active');
240
244
  if (serviceName == 'All') {
241
- serviceName = '';
242
245
  $("#service-title").html('');
243
246
  } else {
244
247
  var titleText = '<a href="consul-services-ui.html?service=' + serviceName + '">'+serviceName+'</a>';
@@ -246,7 +249,7 @@ class ServiceTimeline {
246
249
  }
247
250
  serviceTimeline.serviceInstanceFilter = serviceName;
248
251
  if (updateUrl) {
249
- serviceTimeline.updateURL(serviceName == 'All' ? '' : serviceName);
252
+ serviceTimeline.updateURL(serviceName);
250
253
  }
251
254
  this.doFilter();
252
255
  }
@@ -283,6 +286,7 @@ class ServiceTimeline {
283
286
  }
284
287
 
285
288
  displayEvents(firstReload) {
289
+ var maxRows = document.getElementById("maxRows").value;
286
290
  //$("#service-title").html(service['name']);
287
291
  var tableBody = $('#all-events > tbody');
288
292
  var startIndex = 0;
@@ -290,19 +294,37 @@ class ServiceTimeline {
290
294
  tableBody.html("");
291
295
  } else {
292
296
  // We first try to find new entries...
293
- var o = this.lastEntryLoaded;
297
+ var lastDisplayedIndex = indexOfTimelineEvent(this.lastEntryLoaded);
298
+ var newestIndexInNewDocument = "000";
299
+ if (this.data.length > 0) {
300
+ newestIndexInNewDocument = indexOfTimelineEvent(this.data[this.data.length - 1]);
301
+ }
302
+ if (lastDisplayedIndex >= newestIndexInNewDocument) {
303
+ // Might happen when behind a VIP
304
+ console.log("Skip reload, index: ", lastDisplayedIndex, ", new is ", newestIndexInNewDocument);
305
+ return;
306
+ } else {
307
+ console.log("Index ", lastDisplayedIndex, " -> ", newestIndexInNewDocument);
308
+ }
294
309
  for (var i = 0 ; i < this.data.length; i++) {
295
310
  var e = this.data[i];
296
- if (o.ts == e.ts && o.instance == e.instance) {
311
+ if (lastDisplayedIndex < indexOfTimelineEvent(e)) {
297
312
  startIndex = i + 1;
298
313
  console.log('Resuming at ', startIndex, " with ", e);
299
314
  break;
300
315
  }
301
316
  }
302
317
  }
303
- var tbody = tableBody[0];
318
+ var frag = document.createDocumentFragment();
304
319
  var filter = "";
305
320
  var lastEntryFound = null;
321
+ if (this.data.length > maxRows) {
322
+ var remaining = this.data.length - startIndex;
323
+ if (startIndex < remaining) {
324
+ startIndex = this.data.length - maxRows;
325
+ console.log('Skip first ', startIndex, " entries on ", this.data.length, " lines...");
326
+ }
327
+ }
306
328
  for (var i = startIndex ; i < this.data.length; i++) {
307
329
  var e = this.data[i];
308
330
  lastEntryFound = e;
@@ -391,8 +413,22 @@ class ServiceTimeline {
391
413
  }
392
414
  this.buildCell(row, 'td', 'ipercents', this.createBadge(percent + " %", clazz));
393
415
  }
394
- tbody.prepend(row)
416
+ frag.prepend(row);
395
417
  }
418
+ var tbody = tableBody[0];
419
+ tbody.prepend(frag);
396
420
  this.lastEntryLoaded = lastEntryFound;
421
+ console.log("Last entry loaded: ", indexOfTimelineEvent(this.lastEntryLoaded));
422
+ var i = 0;
423
+
424
+ var tbody = tableBody.children('tr').each (function() {
425
+ i++;
426
+ if (i > maxRows) {
427
+ $(this).remove()
428
+ }
429
+ });
430
+ if (i > maxRows) {
431
+ console.log("Removed ", maxRows - i, " lines.")
432
+ }
397
433
  }
398
434
  }
@@ -20,6 +20,12 @@ function formatDate(date) {
20
20
  return padDateUnit(date.getMonth()+1) + "/" + padDateUnit(date.getDate()) + " " + padDateUnit(date.getHours()) + ':' + padDateUnit(date.getMinutes()) + ':' + padDateUnit(date.getSeconds());
21
21
  }
22
22
 
23
+ function indexOfTimelineEvent(e) {
24
+ if (e == null) {
25
+ return 'k/0000000000/0000/0000';
26
+ }
27
+ return 'k/' + e.idx.toString().padStart(10, '0') + '/' + e.service + '/' + e.instance;
28
+ }
23
29
 
24
30
  function nodeState(checks) {
25
31
  status='passing';
@@ -77,6 +77,7 @@ def diff(old, new)
77
77
  end
78
78
 
79
79
  @events = RingBuffer.new(max_size: (ENV['CONSUL_TIMELINE_BUFFER'] || 10000).to_i) unless @events
80
+ @new_events = []
80
81
 
81
82
  def log_event(line)
82
83
  puts "#{Time.now.to_i} #{line}" if ENV['DEBUG_TIMELINE']
@@ -84,7 +85,7 @@ end
84
85
 
85
86
  def store_event(service: service_name, instance: nil, old_state: nil, new_state: nil, instance_info: nil, checks: [])
86
87
  STDERR.puts "empty instance_info for #{service} ; #{instance} ; #{new_state}" unless instance_info
87
- @events << { 'service' => service, 'instance' => instance, 'old_state' => old_state, 'new_state' => new_state,
88
+ @new_events << { 'service' => service, 'instance' => instance, 'idx' => instance_info['idx'], 'old_state' => old_state, 'new_state' => new_state,
88
89
  'ts' => @current_time, 'instance_info' => instance_info }.tap do |ev|
89
90
  ev['checks'] = checks if checks
90
91
  ev['stats'] = if instance_info
@@ -176,10 +177,20 @@ end
176
177
  checks: checks)
177
178
  end
178
179
  end
180
+ sorted_events = @new_events.sort do |a, b|
181
+ res = 0
182
+ %w[idx service instance].each do |f|
183
+ res = a[f] <=> b[f]
184
+ break if res != 0
185
+ end
186
+ res
187
+ end
188
+ sorted_events.each { |e| @events << e }
189
+ @new_events.clear
190
+
179
191
  # We save the previous state only when we have a complete state once
180
192
  if template_info['was_rendered_once']
181
193
  warn "First full rendering completed at #{@current_time} !" unless @previous_state
182
194
  @previous_state = cur_state
183
195
  end
184
-
185
- %><%= JSON.generate(@events)%>
196
+ %><%= JSON.generate(@events) %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: consul-templaterb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.4
4
+ version: 1.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - SRE Core Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-18 00:00:00.000000000 Z
11
+ date: 2018-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-http-request