consul-templaterb 1.9.2 → 1.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/consul/async/consul_endpoint.rb +7 -2
- data/lib/consul/async/utilities.rb +5 -0
- data/lib/consul/async/version.rb +1 -1
- data/samples/consul-ui/common/header.html.erb +1 -0
- data/samples/consul-ui/images/favicon.png +0 -0
- data/samples/consul-ui/js/service.js +1 -1
- data/samples/consul-ui/js/timeline.js +1 -1
- data/samples/consul-ui/js/utils.js +9 -2
- data/samples/consul-ui/ringbuffer.rb +107 -0
- data/samples/consul-ui/timeline.json.erb +4 -30
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5782528a3540e33076a9db4244d558f9e62d846b68f7aa57cb625dbc2cca7415
|
4
|
+
data.tar.gz: c3d33c3bb5f760f1b0108807213e8d59aceca92cce6eccb67c32ff759010ece8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02cb21ad2703bfd0a847181c4b4d0b5bd4a96503130e949db99498461dee4e1744e35b406a056ddcd2023eacc6aac3463e51b33685748a8733dd02fa57852efd
|
7
|
+
data.tar.gz: 19015ff464cdeb7ee09b04471d78562b415b02878349c2d9c5bd96acac758276759efdff2132000558b96d3003ac473d29369c47090189fc29cf16178918e3d6
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## (UNRELEASED)
|
4
4
|
|
5
|
+
## 1.9.3 (January 9, 2019)
|
6
|
+
|
7
|
+
IMPROVEMENTS:
|
8
|
+
|
9
|
+
* Perform some randomization on retries, so in case of massive errors,
|
10
|
+
system will likely re-open all connections at the same time.
|
11
|
+
* consul-timeline more optimize ringbuffer for larger history
|
12
|
+
* UI improvements (tooltips for services/checks)
|
13
|
+
|
5
14
|
## 1.9.2 (January 4, 2019)
|
6
15
|
|
7
16
|
IMPROVEMENTS:
|
@@ -137,7 +137,7 @@ module Consul
|
|
137
137
|
"[#{stats.body_bytes_human.ljust(8)}][#{stats.bytes_per_sec_human.ljust(9)}]"\
|
138
138
|
" #{path.ljust(48)} idx:#{result.x_consul_index}, next in #{result.retry_in} s"
|
139
139
|
end
|
140
|
-
on_error { |http| STDERR.puts "[ERROR]: #{path}: #{http.error}" }
|
140
|
+
on_error { |http| STDERR.puts "[ERROR]: #{path}: #{http.error.inspect}" }
|
141
141
|
end
|
142
142
|
|
143
143
|
def on_response(&block)
|
@@ -185,8 +185,12 @@ module Consul
|
|
185
185
|
http.response_header['X-Consul-Index']
|
186
186
|
end
|
187
187
|
|
188
|
+
def _compute_retry_in(retry_in)
|
189
|
+
retry_in / 2 + Consul::Async::Utilities.random.rand(retry_in)
|
190
|
+
end
|
191
|
+
|
188
192
|
def _handle_error(http, consul_index)
|
189
|
-
retry_in = [600, conf.retry_duration + 2**@consecutive_errors].min
|
193
|
+
retry_in = _compute_retry_in([600, conf.retry_duration + 2**@consecutive_errors].min)
|
190
194
|
STDERR.puts "[ERROR][#{path}] X-Consul-Index:#{consul_index} - #{http.error} - Retry in #{retry_in}s #{stats.body_bytes_human}"
|
191
195
|
@consecutive_errors += 1
|
192
196
|
http_result = HttpResponse.new(http)
|
@@ -227,6 +231,7 @@ module Consul
|
|
227
231
|
else
|
228
232
|
retry_in = modified ? conf.min_duration : conf.retry_on_non_diff
|
229
233
|
end
|
234
|
+
retry_in = _compute_retry_in(retry_in)
|
230
235
|
retry_in = 0.1 if retry_in < 0.1
|
231
236
|
unless @stopping
|
232
237
|
EventMachine.add_timer(retry_in) do
|
data/lib/consul/async/version.rb
CHANGED
@@ -31,6 +31,7 @@
|
|
31
31
|
<meta name="description" content="Display Consul information"/>
|
32
32
|
<meta name="author" content="Criteo"/>
|
33
33
|
<title><%= param('title', 'Consul Real Time information') %></title>
|
34
|
+
<link rel="icon" type="image/png" href="images/favicon.png" sizes="32x32" />
|
34
35
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
35
36
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.11/css/all.css" integrity="sha384-p2jx59pefphTFIpeqCcISO9MdVfIm4pNnsL08A6v5vaQc4owkQqxMV8kg4Yvhaw/" crossorigin="anonymous">
|
36
37
|
<link rel="stylesheet" href="css/style.css">
|
Binary file
|
@@ -251,7 +251,7 @@ class ConsulService {
|
|
251
251
|
serviceHtml.appendChild(tagsGenerator(instance.tags));
|
252
252
|
serviceHtml.appendChild(serviceMetaGenerator(instance.sMeta));
|
253
253
|
serviceHtml.appendChild(connectGenerator(instance))
|
254
|
-
serviceHtml.appendChild(checksStatusGenerator(instance
|
254
|
+
serviceHtml.appendChild(checksStatusGenerator(instance));
|
255
255
|
serviceHtml.setAttribute('status', state);
|
256
256
|
$("#instances-list").append(serviceHtml);
|
257
257
|
}
|
@@ -457,7 +457,7 @@ class ServiceTimeline {
|
|
457
457
|
var checkName = document.createElement('div');
|
458
458
|
checkName.setAttribute('class', 'lookup checkName');
|
459
459
|
checkName.setAttribute('data-toggle', 'tooltip');
|
460
|
-
checkName.setAttribute('title', c['id']+'\n\n' + c.output);
|
460
|
+
checkName.setAttribute('title', 'ID: ' + c['id'] + '\nName: ' + c['name'] + '\n\n' + c.output);
|
461
461
|
checkName.appendChild(document.createTextNode(c['name']));
|
462
462
|
checksCell.appendChild(checkName);
|
463
463
|
}
|
@@ -52,6 +52,10 @@ function serviceTitleGenerator(instance) {
|
|
52
52
|
}
|
53
53
|
|
54
54
|
var htmlTitle = document.createElement('h5');
|
55
|
+
htmlTitle.setAttribute('title', 'Node Name: ' + instance.name +
|
56
|
+
'\nAddress : ' + instance.addr +
|
57
|
+
'\nService ID: ' + instance.id +
|
58
|
+
'\nService Port : ' + instance.port);
|
55
59
|
|
56
60
|
var instanceLink = document.createElement('a');
|
57
61
|
instanceLink.setAttribute('class', 'instance-name');
|
@@ -223,14 +227,16 @@ function servicesGenerator(instanceServices) {
|
|
223
227
|
return services;
|
224
228
|
}
|
225
229
|
|
226
|
-
function checksStatusGenerator(
|
230
|
+
function checksStatusGenerator(instance) {
|
231
|
+
var instanceChecks = instance.checks;
|
227
232
|
var checks = document.createElement('div');
|
228
233
|
checks.className = 'checks';
|
229
234
|
checks.appendChild(document.createTextNode("Checks: "));
|
230
235
|
checks.appendChild(document.createElement('br'));
|
231
236
|
|
232
237
|
for (var checkKey in instanceChecks) {
|
233
|
-
|
238
|
+
var checkInstance = instanceChecks[checkKey];
|
239
|
+
var checkId = instance.name + '::' + checkInstance.checkid;
|
234
240
|
var btn = 'btn-' + toCSSClass(instanceChecks[checkKey]['status'])
|
235
241
|
var check = document.createElement('div');
|
236
242
|
|
@@ -240,6 +246,7 @@ function checksStatusGenerator(instanceChecks) {
|
|
240
246
|
btnCheck.setAttribute('data-toggle', 'collapse');
|
241
247
|
btnCheck.setAttribute('data-target', '#' + checkId);
|
242
248
|
btnCheck.setAttribute('aria-expanded', 'false');
|
249
|
+
btnCheck.setAttribute('title', checkInstance.checkid);
|
243
250
|
|
244
251
|
btnCheck.appendChild(document.createTextNode(instanceChecks[checkKey]['name']));
|
245
252
|
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module ConsulTimeline
|
2
|
+
class RingBufferNode
|
3
|
+
attr_reader :prev, :value, :next
|
4
|
+
attr_writer :prev, :next, :value
|
5
|
+
def initialize(value, p_elem, n_elem)
|
6
|
+
@value = value
|
7
|
+
@prev = p_elem
|
8
|
+
@next = n_elem
|
9
|
+
end
|
10
|
+
|
11
|
+
# Insert element before current element, return inserted Node
|
12
|
+
def insert_before(obj)
|
13
|
+
old_prev = @prev
|
14
|
+
@prev = RingBufferNode.new(obj, old_prev, self)
|
15
|
+
old_prev&.next = @prev
|
16
|
+
@prev
|
17
|
+
end
|
18
|
+
|
19
|
+
# Append element after current ince, return inserted Node
|
20
|
+
def append(obj)
|
21
|
+
old_next = @next
|
22
|
+
@next = RingBufferNode.new(obj, self, old_next)
|
23
|
+
old_next&.prev = @next
|
24
|
+
@next
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"[prev=#{@prev.object_id}, next=#{@next.object_id}, value=#{@value}]"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
class SortedRingBuffer
|
32
|
+
include Enumerable
|
33
|
+
def initialize(max_size, sort_func)
|
34
|
+
raise "Invalid size #{max_size}" unless max_size.positive?
|
35
|
+
@head = RingBufferNode.new(nil, nil, nil)
|
36
|
+
@sort_func = sort_func
|
37
|
+
@tail = @head
|
38
|
+
@max_size = max_size
|
39
|
+
(max_size - 1).times do
|
40
|
+
@head = @head.insert_before(nil)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def push(obj)
|
45
|
+
return unless obj
|
46
|
+
cur = @tail
|
47
|
+
raise "No head.next found in #{@head}" unless @head.next
|
48
|
+
while cur && cur.value && @sort_func.call(cur.value, obj).positive?
|
49
|
+
cur = cur.prev
|
50
|
+
end
|
51
|
+
if cur.nil?
|
52
|
+
# The value we try to insert is before @head
|
53
|
+
# no need to do anything
|
54
|
+
elsif cur == @head
|
55
|
+
# This is the head, just update the value
|
56
|
+
@head.value = obj
|
57
|
+
else
|
58
|
+
@head = @head.next
|
59
|
+
@head.prev = nil
|
60
|
+
new_val = cur.append(obj)
|
61
|
+
@tail = new_val if @tail == cur
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def each
|
66
|
+
return enum_for(:each) unless block_given? # Sparkling magic!
|
67
|
+
cur = @head
|
68
|
+
until cur.nil?
|
69
|
+
yield cur.value if cur.value
|
70
|
+
cur = cur.next
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_a
|
75
|
+
arr = Array.new(@max_size)
|
76
|
+
cur = @head
|
77
|
+
i = 0
|
78
|
+
until cur.nil?
|
79
|
+
if cur.value
|
80
|
+
arr[i] = cur.value
|
81
|
+
i += 1
|
82
|
+
end
|
83
|
+
cur = cur.next
|
84
|
+
end
|
85
|
+
if i != @max_size
|
86
|
+
arr.reject(&:nil?)
|
87
|
+
else
|
88
|
+
arr
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
if ARGV.count.positive? && ARGV[0] == 'debug'
|
95
|
+
require 'json'
|
96
|
+
size = (ARGV[1] || 10).to_i
|
97
|
+
ringbuff = ConsulTimeline::SortedRingBuffer.new(size, ->(a, b) { a <=> b })
|
98
|
+
ringbuff.push 0.5
|
99
|
+
puts ringbuff.to_a
|
100
|
+
(size * 10).times do |i|
|
101
|
+
ringbuff.push(2 * i + Random.rand(size / 10))
|
102
|
+
end
|
103
|
+
ringbuff.push 99_999_999_999_999
|
104
|
+
arr = ringbuff.to_a
|
105
|
+
raise "OOPS wrong size := #{arr.count} instead of #{size}" unless arr.count == size
|
106
|
+
STDOUT.puts JSON.generate(arr)
|
107
|
+
end
|
@@ -55,33 +55,7 @@ old_state = if @previous_state
|
|
55
55
|
end
|
56
56
|
|
57
57
|
unless @events
|
58
|
-
|
59
|
-
attr_reader :max_size
|
60
|
-
|
61
|
-
def initialize(max_size:, enum: nil)
|
62
|
-
@max_size = max_size
|
63
|
-
warn "Ringbuffer initialized with #{max_size}"
|
64
|
-
enum&.each { |e| self << e }
|
65
|
-
end
|
66
|
-
|
67
|
-
def <<(element)
|
68
|
-
return unless element
|
69
|
-
if size >= @max_size
|
70
|
-
shift
|
71
|
-
end
|
72
|
-
previous_e = last
|
73
|
-
after = []
|
74
|
-
while !previous_e.nil? && (previous_e['idx'] > element['idx'])
|
75
|
-
after.insert(0, pop)
|
76
|
-
previous_e = last
|
77
|
-
end
|
78
|
-
push(element)
|
79
|
-
after.each do |x|
|
80
|
-
push(x)
|
81
|
-
end
|
82
|
-
self
|
83
|
-
end
|
84
|
-
end
|
58
|
+
load File.expand_path(File.join(File.dirname(template_info['source']), 'ringbuffer.rb'))
|
85
59
|
|
86
60
|
def diff(old, new_e)
|
87
61
|
diff = OpenStruct.new
|
@@ -92,7 +66,7 @@ unless @events
|
|
92
66
|
diff
|
93
67
|
end
|
94
68
|
|
95
|
-
@events =
|
69
|
+
@events = ::ConsulTimeline::SortedRingBuffer.new((ENV['CONSUL_TIMELINE_BUFFER'] || 10000).to_i, lambda {|a, b| a['idx'] <=> b['idx'] })
|
96
70
|
end
|
97
71
|
@new_events = []
|
98
72
|
|
@@ -209,7 +183,7 @@ sorted_events = @new_events.sort do |a, b|
|
|
209
183
|
end
|
210
184
|
res
|
211
185
|
end
|
212
|
-
sorted_events.each { |e| @events
|
186
|
+
sorted_events.each { |e| @events.push e }
|
213
187
|
@new_events.clear
|
214
188
|
|
215
189
|
# We save the previous state only when we have a complete state once
|
@@ -217,4 +191,4 @@ if template_info['was_rendered_once']
|
|
217
191
|
warn "First full rendering completed at #{@current_time} !" unless @previous_state
|
218
192
|
@previous_state = cur_state
|
219
193
|
end
|
220
|
-
%><%= JSON.generate(@events) %>
|
194
|
+
%><%= JSON.generate(@events.to_a) %>
|
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.9.
|
4
|
+
version: 1.9.3
|
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: 2019-01-
|
11
|
+
date: 2019-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -184,11 +184,13 @@ files:
|
|
184
184
|
- samples/consul-ui/consul_nodes.json.erb
|
185
185
|
- samples/consul-ui/consul_services.json.erb
|
186
186
|
- samples/consul-ui/css/style.css
|
187
|
+
- samples/consul-ui/images/favicon.png
|
187
188
|
- samples/consul-ui/js/keys.js
|
188
189
|
- samples/consul-ui/js/nodes.js
|
189
190
|
- samples/consul-ui/js/service.js
|
190
191
|
- samples/consul-ui/js/timeline.js
|
191
192
|
- samples/consul-ui/js/utils.js
|
193
|
+
- samples/consul-ui/ringbuffer.rb
|
192
194
|
- samples/consul-ui/timeline.json.erb
|
193
195
|
- samples/consul-ui/vendors/highlight/atom-one-dark.css
|
194
196
|
- samples/consul-ui/vendors/highlight/highlight.pack.js
|