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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/consul/async/consul_template.rb +1 -0
- data/lib/consul/async/version.rb +1 -1
- data/samples/consul-ui/consul-timeline-ui.html.erb +7 -3
- data/samples/consul-ui/js/timeline.js +46 -10
- data/samples/consul-ui/js/utils.js +6 -0
- data/samples/consul-ui/timeline.json.erb +14 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d17ec48b3c3611a4e49e13ef9daaeeb44f3f6cc02768ccdcd579e64c2af1a7ec
|
4
|
+
data.tar.gz: 59300692c12bacfa4e232679fc7568437ebf9fd3ca977161f702b2f1f4666b76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/consul/async/version.rb
CHANGED
@@ -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…</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…</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"
|
20
|
-
|
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.
|
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
|
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
|
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 (
|
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
|
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
|
-
|
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
|
-
@
|
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
|
+
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-
|
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
|