consul-templaterb 1.8.4 → 1.8.5

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 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