consul-templaterb 1.9.9 → 1.10.0
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/.gitignore +3 -1
- data/CHANGELOG.md +11 -0
- data/README.md +2 -0
- data/bin/consul-templaterb +11 -6
- data/lib/consul/async/consul_endpoint.rb +3 -3
- data/lib/consul/async/consul_template.rb +6 -6
- data/lib/consul/async/consul_template_engine.rb +5 -3
- data/lib/consul/async/debug.rb +39 -0
- data/lib/consul/async/vault_endpoint.rb +4 -3
- data/lib/consul/async/version.rb +1 -1
- data/samples/consul-ui/consul_nodes.json.erb +2 -0
- data/samples/consul-ui/js/nodes.js +5 -0
- data/samples/consul-ui/js/service.js +9 -1
- data/samples/consul-ui/js/utils.js +2 -2
- data/samples/metrics.erb +16 -5
- data/samples/service_checks_metrics.erb +34 -0
- data/samples/tools/find_all_failing_services.txt.erb +25 -0
- data/samples/tools/find_all_nodes_without_id.txt.erb +14 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d389019e21022ecf1c1e1783133ff49379d6e97141cf5a083b2c9c805c013f7
|
4
|
+
data.tar.gz: 4860d2607e32173aae5e4e2aa606564bc1cc1ccec4876d2079c7f22404c2a4b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d092840b101377b92a526778b6b77aa73cac04f7f97526fcd8e8c52a54bb9e335e8644e4c18362fa07cba982f5edd748d47bd0d2440c7f3ad0b4c037ec9d5cbf
|
7
|
+
data.tar.gz: 8805e42b635107b8936daf0b71e1f789afa9da4b61fb88aca3c0d3f4192d5d5a03f997cda5df5e3526433e81de95d436e8c4dbc5290673d357b29a1753c6449b
|
data/.gitignore
CHANGED
@@ -19,7 +19,9 @@ samples/consul-ui/common/*.html
|
|
19
19
|
/samples/criteo/haproxy.cfg
|
20
20
|
/samples/consul_template
|
21
21
|
/samples/metrics
|
22
|
+
/samples/service_checks_metrics
|
22
23
|
/samples/find_blocked_choregraphies
|
24
|
+
/samples/tools/*.txt
|
23
25
|
/spec/consul/async/resources/templates/*.txt
|
24
26
|
/spec/consul/async/resources/templates/*.result
|
25
27
|
/out.txt
|
@@ -29,7 +31,7 @@ samples/consul-ui/common/*.html
|
|
29
31
|
# Mac OS
|
30
32
|
.DS_Store
|
31
33
|
|
32
|
-
# IntelliJ project files
|
34
|
+
# IntelliJ project files
|
33
35
|
*.iml
|
34
36
|
*.iws
|
35
37
|
*.ipr
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
## (UNRELEASED)
|
4
4
|
|
5
|
+
IMPROVEMENTS:
|
6
|
+
|
7
|
+
## 1.10.0 (February 27, 2019)
|
8
|
+
|
9
|
+
* new sample [samples/tools/find_all_failing_services.txt.erb](samples/tools/find_all_failing_services.txt.erb)
|
10
|
+
to find all failing service instances on all DCs very easily.
|
11
|
+
* Do not report timestamps in metrics.erb as it is toxic for Prometheus
|
12
|
+
* in metrics.erb, add all net_info statistics to observe consul-templaterb itself
|
13
|
+
* new flag -l <error|info|debug> to control verbosity of messages
|
14
|
+
* Now diplays Checks of a Node in Consul-UI
|
15
|
+
|
5
16
|
## 1.9.9 (January 18, 2019)
|
6
17
|
|
7
18
|
IMPROVEMENTS:
|
data/README.md
CHANGED
@@ -144,6 +144,7 @@ USAGE: consul-templaterb [[options]]
|
|
144
144
|
-v, --version Show Version
|
145
145
|
-g, --no-gzip-compression Disable GZIP compression in HTTP requests
|
146
146
|
-c, --consul-addr=<address> Address of Consul, eg: http://localhost:8500
|
147
|
+
-l, --log-level=<log_level> Log level, default=info, any of none|error|info|debug
|
147
148
|
--consul-token=<token> Use a token to connect to Consul
|
148
149
|
-V, --vault-addr=<address> Address of Vault, eg: http://localhost:8200
|
149
150
|
--vault-token=<token> Token used to authenticate against vault.
|
@@ -239,6 +240,7 @@ examples:
|
|
239
240
|
9. [Export Consul Statistics to Prometheus](samples/metrics.erb) : count all services, their state,
|
240
241
|
datacenters and nodes and export it to prometheus easily to trigger alerts.
|
241
242
|
10. [List all services/Nodes with their statuses for all datacenters](samples/all_services.txt.erb)
|
243
|
+
11. [Show all services/instances not passing on all DCs](samples/tools/find_all_failing_services.txt.erb)
|
242
244
|
|
243
245
|
If you want to test it quickly, you might try with (assuming your consul agent is listening on
|
244
246
|
`http://localhost:8500`):
|
data/bin/consul-templaterb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# This script can be launched to get a uniq id for this instance
|
3
3
|
require 'consul/async/consul_template_engine'
|
4
4
|
require 'consul/async/process_handler'
|
5
|
+
require 'consul/async/debug'
|
5
6
|
require 'consul/async/version'
|
6
7
|
require 'optparse'
|
7
8
|
require 'optparse/uri'
|
@@ -97,6 +98,10 @@ optparse = OptionParser.new do |opts|
|
|
97
98
|
options[:consul][:base_url] = consul_url
|
98
99
|
end
|
99
100
|
|
101
|
+
opts.on('-l', '--log-level=<log_level>', String, "Log level, default=info, any of #{::Consul::Async::Debug.levels.join('|')}") do |log_level|
|
102
|
+
::Consul::Async::Debug.level = log_level
|
103
|
+
end
|
104
|
+
|
100
105
|
opts.on('--consul-token=<token>', String, 'Use a token to connect to Consul') do |consul_token|
|
101
106
|
options[:consul][:token] = consul_token
|
102
107
|
end
|
@@ -177,7 +182,7 @@ optparse = OptionParser.new do |opts|
|
|
177
182
|
begin
|
178
183
|
@programs[cmd].process_status
|
179
184
|
rescue Consul::Async::ProcessDoesNotExist => e
|
180
|
-
STDERR.puts "[
|
185
|
+
STDERR.puts "[FATAL] The process is dead, aborting run: #{e.inspect}"
|
181
186
|
template_manager.terminate
|
182
187
|
EventMachine.stop
|
183
188
|
end
|
@@ -193,16 +198,16 @@ optparse = OptionParser.new do |opts|
|
|
193
198
|
mod = false
|
194
199
|
results = results.map do |res|
|
195
200
|
mod ||= res.modified
|
196
|
-
|
201
|
+
::Consul::Async::Debug.puts_info "Hot reload of template #{res.template_file} with success" if res.hot_reloaded
|
197
202
|
"#{res.modified ? 'WRITTEN' : 'UNCHANGED'}[#{res.output_file}]"
|
198
203
|
end.join(' ')
|
199
204
|
if mod
|
200
|
-
|
205
|
+
::Consul::Async::Debug.puts_info "File written: #{results} #{template_manager.net_info.inspect}"
|
201
206
|
else
|
202
|
-
|
207
|
+
::Consul::Async::Debug.print_debug "Files not changed #{results} #{template_manager.net_info.inspect}\r"
|
203
208
|
end
|
204
209
|
else
|
205
|
-
|
210
|
+
::Consul::Async::Debug.print_debug "Still waiting for data #{template_manager.net_info.inspect}...\r"
|
206
211
|
end
|
207
212
|
end
|
208
213
|
end
|
@@ -286,7 +291,7 @@ template_manager = Consul::Async::EndPointsManager.new(consul_conf, vault_conf,
|
|
286
291
|
|
287
292
|
ARGV.each do |tpl|
|
288
293
|
dest = compute_default_output(tpl)
|
289
|
-
|
294
|
+
::Consul::Async::Debug.puts_info "Using #{dest} output for #{tpl}"
|
290
295
|
consul_engine.add_template(tpl, dest)
|
291
296
|
end
|
292
297
|
|
@@ -37,7 +37,7 @@ module Consul
|
|
37
37
|
def ch(path, symbol)
|
38
38
|
sub = @paths[path.to_sym]
|
39
39
|
if sub && sub[symbol]
|
40
|
-
|
40
|
+
::Consul::Async::Debug.puts_debug "Overriding #{symbol}:=#{sub[symbol]} for #{path}"
|
41
41
|
sub[symbol]
|
42
42
|
else
|
43
43
|
method(symbol).call
|
@@ -196,7 +196,7 @@ module Consul
|
|
196
196
|
|
197
197
|
def _handle_error(http, consul_index)
|
198
198
|
retry_in = _compute_retry_in([600, conf.retry_duration + 2**@consecutive_errors].min)
|
199
|
-
|
199
|
+
::Consul::Async::Debug.puts_error "[#{path}] X-Consul-Index:#{consul_index} - #{http.error} - Retry in #{retry_in}s #{stats.body_bytes_human}"
|
200
200
|
@consecutive_errors += 1
|
201
201
|
http_result = HttpResponse.new(http)
|
202
202
|
EventMachine.add_timer(retry_in) do
|
@@ -257,7 +257,7 @@ module Consul
|
|
257
257
|
http.errback do
|
258
258
|
unless @stopping
|
259
259
|
_handle_error(http, consul_index) do
|
260
|
-
|
260
|
+
::Consul::Async::Debug.puts_error "[RETRY][#{path}] (#{@consecutive_errors} errors) due to #{http.error}" if (@consecutive_errors % 10) == 1
|
261
261
|
end
|
262
262
|
end
|
263
263
|
end
|
@@ -215,21 +215,21 @@ module Consul
|
|
215
215
|
if not_ready.count.positive?
|
216
216
|
if @iteration - @last_debug_time > 1
|
217
217
|
@last_debug_time = @iteration
|
218
|
-
|
218
|
+
::Consul::Async::Debug.print_info "Waiting for data from #{not_ready.count}/#{not_ready.count + ready} endpoints: #{not_ready[0..2]}...\r"
|
219
219
|
end
|
220
220
|
return [false, false, nil]
|
221
221
|
end
|
222
222
|
if to_cleanup.count > 1
|
223
|
-
|
223
|
+
::Consul::Async::Debug.puts_info "Cleaned up #{to_cleanup.count} endpoints: #{to_cleanup}"
|
224
224
|
to_cleanup.each do |to_remove|
|
225
225
|
x = @endpoints.delete(to_remove)
|
226
226
|
x.endpoint.terminate
|
227
227
|
end
|
228
228
|
end
|
229
229
|
if last_result != data
|
230
|
-
|
230
|
+
::Consul::Async::Debug.print_info "Write #{Utilities.bytes_to_h data.bytesize} bytes to #{file}, "\
|
231
231
|
"netinfo=#{@net_info} aka "\
|
232
|
-
"#{Utilities.bytes_to_h((net_info[:network_bytes] / (Time.now.utc - @start_time)).round(1))}/s ...\
|
232
|
+
"#{Utilities.bytes_to_h((net_info[:network_bytes] / (Time.now.utc - @start_time)).round(1))}/s ...\r"
|
233
233
|
tmp_file = "#{file}.tmp"
|
234
234
|
File.open(tmp_file, 'w') do |f|
|
235
235
|
f.write data
|
@@ -248,7 +248,7 @@ module Consul
|
|
248
248
|
|
249
249
|
def vault_setup_token_renew
|
250
250
|
path = 'v1/auth/token/renew-self'
|
251
|
-
|
251
|
+
::Consul::Async::Debug.print_debug 'Setting up vault token renewal'
|
252
252
|
VaultEndpoint.new(vault_conf, path, :POST, {}, {})
|
253
253
|
end
|
254
254
|
|
@@ -260,7 +260,7 @@ module Consul
|
|
260
260
|
tpl = @endpoints[fqdn]
|
261
261
|
unless tpl
|
262
262
|
tpl = yield
|
263
|
-
|
263
|
+
::Consul::Async::Debug.print_debug "path #{path.ljust(64)} #{query_params.inspect}\r"
|
264
264
|
@endpoints[fqdn] = tpl
|
265
265
|
tpl.endpoint.on_response do |result|
|
266
266
|
@net_info[:success] += 1
|
@@ -20,6 +20,7 @@ module Consul
|
|
20
20
|
@periodic_started = false
|
21
21
|
@debug_memory = false
|
22
22
|
@last_memory_state = build_memory_info
|
23
|
+
@start = Time.now
|
23
24
|
end
|
24
25
|
|
25
26
|
def build_memory_info
|
@@ -45,14 +46,15 @@ module Consul
|
|
45
46
|
all_ready = results.reduce(true) { |a, e| a && e.ready? }
|
46
47
|
if !@all_templates_rendered && all_ready
|
47
48
|
@all_templates_rendered = true
|
48
|
-
|
49
|
+
cur_time = Time.now
|
50
|
+
::Consul::Async::Debug.puts_info "First rendering of #{results.count} templates completed in #{cur_time - @start}s at #{cur_time}. "
|
49
51
|
end
|
50
52
|
begin
|
51
53
|
@template_callbacks.each do |c|
|
52
54
|
c.call([all_ready, template_manager, results])
|
53
55
|
end
|
54
56
|
rescue StandardError => cbk_error
|
55
|
-
|
57
|
+
::Consul::Async::Debug.puts_error "callback error: #{cbk_error.inspect}"
|
56
58
|
raise cbk_error
|
57
59
|
end
|
58
60
|
rescue Consul::Async::InvalidTemplateException => e
|
@@ -60,7 +62,7 @@ module Consul
|
|
60
62
|
template_manager.terminate
|
61
63
|
EventMachine.stop
|
62
64
|
rescue StandardError => e
|
63
|
-
STDERR.puts "[
|
65
|
+
STDERR.puts "[FATAL] Error occured: #{e.inspect} - #{e.backtrace.join("\n\t")}"
|
64
66
|
template_manager.terminate
|
65
67
|
EventMachine.stop
|
66
68
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Consul
|
2
|
+
module Async
|
3
|
+
class Debug
|
4
|
+
def self.level
|
5
|
+
@level || 2
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.levels
|
9
|
+
%w[none error info debug]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.level=(log_level)
|
13
|
+
lvl = levels.index(log_level)
|
14
|
+
raise "Log level #{log_level} unsupported, must be one of #{levels.inspect}" if lvl.nil?
|
15
|
+
@level = lvl
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.puts_error(msg)
|
19
|
+
STDERR.puts "[ERROR] #{msg}" if level.positive?
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.puts_info(msg)
|
23
|
+
STDERR.puts "[INFO] #{msg}" if level > 1
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.print_info(msg)
|
27
|
+
STDERR.print "[INFO] #{msg}" if level > 1
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.puts_debug(msg)
|
31
|
+
STDERR.puts "[DEBG] #{msg}" if level > 2
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.print_debug(msg)
|
35
|
+
STDERR.print "[DEBG] #{msg}" if level > 2
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'consul/async/utilities'
|
2
2
|
require 'consul/async/stats'
|
3
|
+
require 'consul/async/debug'
|
3
4
|
require 'em-http'
|
4
5
|
require 'net/http'
|
5
6
|
require 'thread'
|
@@ -34,7 +35,7 @@ module Consul
|
|
34
35
|
def ch(path, symbol)
|
35
36
|
sub = @paths[path.to_sym]
|
36
37
|
if sub && sub[symbol]
|
37
|
-
|
38
|
+
::Consul::Async::Debug.puts_info "Overriding #{symbol}:=#{sub[symbol]} for #{path}"
|
38
39
|
sub[symbol]
|
39
40
|
else
|
40
41
|
method(symbol).call
|
@@ -138,7 +139,7 @@ module Consul
|
|
138
139
|
"[#{stats.body_bytes_human.ljust(8)}][#{stats.bytes_per_sec_human.ljust(9)}]"\
|
139
140
|
" #{path.ljust(48)} idx:#{result.x_consul_index}, next in #{result.retry_in} s"
|
140
141
|
end
|
141
|
-
on_error { |http|
|
142
|
+
on_error { |http| ::Consul::Async::Debug.puts_error "#{path}: #{http.error}" }
|
142
143
|
end
|
143
144
|
|
144
145
|
def on_response(&block)
|
@@ -193,7 +194,7 @@ module Consul
|
|
193
194
|
|
194
195
|
def _handle_error(http)
|
195
196
|
retry_in = [conf.max_retry_duration, conf.retry_duration + 2**@consecutive_errors].min
|
196
|
-
|
197
|
+
::Consul::Async::Debug.puts_error "[#{path}][#{http_method}] Code: #{http.response_header.status} #{_get_errors(http).join(' - ')} - Retry in #{retry_in}s"
|
197
198
|
@consecutive_errors += 1
|
198
199
|
http_result = VaultHttpResponse.new(http, default_value)
|
199
200
|
EventMachine.add_timer(retry_in) do
|
data/lib/consul/async/version.rb
CHANGED
@@ -53,6 +53,8 @@
|
|
53
53
|
node_data = {
|
54
54
|
Node: node_node_data,
|
55
55
|
Service: node_services_data,
|
56
|
+
# Only put Checks on a Node
|
57
|
+
checks: snode["Checks"].select{|c| c['ServiceID'].empty? }.map{|c| {output: c['Output'], notes: c['Notes'], name: c['Name'], checkid: c['CheckID'], status: c['Status']}},
|
56
58
|
}
|
57
59
|
|
58
60
|
service_per_node[snode['Node']['Node']] = node_data
|
@@ -98,6 +98,11 @@ class ConsulNodes {
|
|
98
98
|
contentHead.appendChild(nodeAddressGenator(instance['Node']['Address']));
|
99
99
|
contentHead.appendChild(nodeMetaGenator(instance['Node']['Meta']));
|
100
100
|
content.appendChild(contentHead);
|
101
|
+
var nodesChecks = document.createElement('div');
|
102
|
+
nodesChecks.setAttribute('class','nodes-checks');
|
103
|
+
nodesChecks.appendChild(checksStatusGenerator(instance, instance['Node']['Name']));
|
104
|
+
content.appendChild(nodesChecks);
|
105
|
+
|
101
106
|
content.appendChild(servicesGenerator(instance['Service']));
|
102
107
|
content.appendChild(tagsGenerator(getTagsNode(instance)));
|
103
108
|
|
@@ -68,6 +68,14 @@ class ConsulService {
|
|
68
68
|
if(this.refresh > 0) {
|
69
69
|
setTimeout(this.fetchRessource, this.refresh * 1000);
|
70
70
|
}
|
71
|
+
|
72
|
+
let urlServiceParam = new URL(location.href).searchParams.get('filter');
|
73
|
+
if (urlServiceParam === null) {
|
74
|
+
return
|
75
|
+
} else if (urlServiceParam) {
|
76
|
+
this.serviceFilter.val(urlServiceParam);
|
77
|
+
this.filterService()
|
78
|
+
}
|
71
79
|
}
|
72
80
|
|
73
81
|
reloadServiceList() {
|
@@ -251,7 +259,7 @@ class ConsulService {
|
|
251
259
|
serviceHtml.appendChild(tagsGenerator(instance.tags));
|
252
260
|
serviceHtml.appendChild(serviceMetaGenerator(instance.sMeta));
|
253
261
|
serviceHtml.appendChild(connectGenerator(instance))
|
254
|
-
serviceHtml.appendChild(checksStatusGenerator(instance));
|
262
|
+
serviceHtml.appendChild(checksStatusGenerator(instance, instance.name));
|
255
263
|
serviceHtml.setAttribute('status', state);
|
256
264
|
$("#instances-list").append(serviceHtml);
|
257
265
|
}
|
@@ -227,7 +227,7 @@ function servicesGenerator(instanceServices) {
|
|
227
227
|
return services;
|
228
228
|
}
|
229
229
|
|
230
|
-
function checksStatusGenerator(instance) {
|
230
|
+
function checksStatusGenerator(instance, prefix) {
|
231
231
|
var instanceChecks = instance.checks;
|
232
232
|
var checks = document.createElement('div');
|
233
233
|
checks.className = 'checks';
|
@@ -236,7 +236,7 @@ function checksStatusGenerator(instance) {
|
|
236
236
|
|
237
237
|
for (var checkKey in instanceChecks) {
|
238
238
|
var checkInstance = instanceChecks[checkKey];
|
239
|
-
var checkId =
|
239
|
+
var checkId = prefix + '::' + checkInstance.checkid;
|
240
240
|
var btn = 'btn-' + toCSSClass(instanceChecks[checkKey]['status'])
|
241
241
|
var check = document.createElement('div');
|
242
242
|
|
data/samples/metrics.erb
CHANGED
@@ -25,28 +25,39 @@
|
|
25
25
|
'warning' => 0,
|
26
26
|
'critical' => 0,
|
27
27
|
}
|
28
|
-
service(service_name)
|
28
|
+
srv = service(service_name)
|
29
|
+
srv.each do |snode|
|
29
30
|
state = snode.status
|
30
31
|
res[state] += 1
|
31
32
|
end
|
32
33
|
backends[service_name] = {
|
33
34
|
state: res,
|
34
|
-
stats:
|
35
|
+
stats: srv.endpoint.stats,
|
35
36
|
}
|
36
37
|
end
|
37
38
|
end
|
38
39
|
%>
|
39
40
|
# HELP consul_datacenters_count A gauge of number of datacenters available
|
40
41
|
# TYPE consul_nodes_count gauge
|
41
|
-
consul_datacenters_count <%= datacenters().count %>
|
42
|
+
consul_datacenters_count <%= datacenters().count %>
|
42
43
|
|
43
44
|
# HELP consul_nodes_count A gauge of number of nodes in the cluster
|
44
45
|
# TYPE consul_nodes_count gauge
|
45
|
-
consul_nodes_count <%= nodes().count %>
|
46
|
+
consul_nodes_count <%= nodes().count %>
|
46
47
|
|
47
48
|
# HELP consul_services_count A gauge of the number of services
|
48
49
|
# TYPE consul_services_count gauge
|
49
|
-
consul_services_count <%= service_count %>
|
50
|
+
consul_services_count <%= service_count %>
|
51
|
+
|
52
|
+
<%
|
53
|
+
%i[success errors bytes_read changes network_bytes].each do |sym|
|
54
|
+
%>
|
55
|
+
# HELP consul_net_info_<%= sym.to_s %> consul-templaterb global stats for <%= sym.to_s %>
|
56
|
+
# TYPE consul_net_info_<%= sym.to_s %> counter
|
57
|
+
consul_net_info_<%= sym.to_s %> <%= @net_info[sym] %>
|
58
|
+
<%
|
59
|
+
end
|
60
|
+
%>
|
50
61
|
|
51
62
|
# HELP consul_service_count A gauge of number instances of service with their current state
|
52
63
|
# TYPE consul_service_count gauge
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# A template for exporting metrics for prometheus using consul-templaterb
|
2
|
+
# This template can be configure the following way with environment variables
|
3
|
+
# Environment variables to filter services/instances
|
4
|
+
# SERVICES_TAG_FILTER: basic tag filter for service (default HTTP)
|
5
|
+
# INSTANCE_MUST_TAG: Second level of filtering (optional, default to SERVICES_TAG_FILTER)
|
6
|
+
# INSTANCE_EXCLUDE_TAG: Exclude instances having the given tag
|
7
|
+
# EXCLUDE_SERVICES: comma-separated services regexps to exclude (example: lbl7.*,netsvc-probe.*,consul-probed.*)
|
8
|
+
|
9
|
+
|
10
|
+
# HELP consul_service_check_count The number of service check for each service
|
11
|
+
# TYPE consul_service_check_count gauge
|
12
|
+
# HELP consul_node_check_count The number of node check for each service
|
13
|
+
# TYPE consul_node_check_count gauge
|
14
|
+
|
15
|
+
<%
|
16
|
+
service_tag_filter = ENV['SERVICES_TAG_FILTER'] || nil
|
17
|
+
instance_must_tag = ENV['INSTANCE_MUST_TAG'] || service_tag_filter
|
18
|
+
instance_exclude_tag = ENV['INSTANCE_EXCLUDE_TAG']
|
19
|
+
|
20
|
+
# Services to hide
|
21
|
+
services_blacklist_raw = (ENV['EXCLUDE_SERVICES'] || 'lbl7.*,netsvc-probe.*,consul-probed.*').split(',')
|
22
|
+
services_blacklist = services_blacklist_raw.map { |v| Regexp.new(v) }
|
23
|
+
|
24
|
+
|
25
|
+
services().each do |service_name, tags|
|
26
|
+
if !services_blacklist.any? {|r| r.match(service_name)} && (instance_must_tag.nil? || tags.include?(instance_must_tag))
|
27
|
+
service(service_name).each do |snode|
|
28
|
+
%>consul_service_check_count{service="<%= service_name %>", node="<%= snode['Node']['Node'] %>"} <%= snode['Checks'].select{|chk| chk['ServiceID'] != ""}.length %>
|
29
|
+
consul_node_check_count{service="<%= service_name %>", node="<%= snode['Node']['Node'] %>"} <%= snode['Checks'].select{|chk| chk['ServiceID'] == ""}.length %>
|
30
|
+
<%
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
%>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
service_name ; service_status ; node ; service_address ; non_passing_checks
|
2
|
+
<%
|
3
|
+
# find all the failing services.
|
4
|
+
# Usage: consul-templaterb --once samples/tools/find_all_failing_services.txt.erb
|
5
|
+
#
|
6
|
+
# Environment variables:
|
7
|
+
# * `CONSUL_SERVICE_FILTER` : regexp to filter services `.*` by default
|
8
|
+
# * `CONSUL_DC_FILTER`: regexp to filter datacenters `.*` by default
|
9
|
+
|
10
|
+
service_filter = Regexp.new(ENV['CONSUL_SERVICE_FILTER'] || '.*')
|
11
|
+
dc_filter = Regexp.new(ENV['CONSUL_DC_FILTER'] || '.*')
|
12
|
+
datacenters.each do |dc|
|
13
|
+
next unless dc_filter.match(dc)
|
14
|
+
services(dc: dc).each do |service_name, tags|
|
15
|
+
next unless service_filter.match(service_name)
|
16
|
+
service(service_name, dc: dc).each do |snode|
|
17
|
+
if snode.status != 'passing'
|
18
|
+
failing_checks = snode['Checks'].select{ |c| c['Status'] != 'passing' }.map { |c| c['Name'] || c['ID'] || c['CheckID']}
|
19
|
+
%><%= service_name %> ; <%= snode.status %> ; <%= snode['Node']['Node']%> ; <%= snode.service_address %> ; <%= failing_checks %>
|
20
|
+
<%
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
%>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%
|
2
|
+
# find all nodes without ID
|
3
|
+
# Usage: consul-templaterb --once samples/tools/find_all_failing_services.txt.erb
|
4
|
+
#
|
5
|
+
|
6
|
+
datacenters.each do |dc|
|
7
|
+
nodes(dc:dc).each do |snode|
|
8
|
+
if snode['ID'] == ''
|
9
|
+
%><%= snode['Node'] %>; <%= snode.inspect %>
|
10
|
+
<%
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
%>
|
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.
|
4
|
+
version: 1.10.0
|
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-
|
11
|
+
date: 2019-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -168,6 +168,7 @@ files:
|
|
168
168
|
- lib/consul/async/consul_template.rb
|
169
169
|
- lib/consul/async/consul_template_engine.rb
|
170
170
|
- lib/consul/async/consul_template_render.rb
|
171
|
+
- lib/consul/async/debug.rb
|
171
172
|
- lib/consul/async/process_handler.rb
|
172
173
|
- lib/consul/async/stats.rb
|
173
174
|
- lib/consul/async/utilities.rb
|
@@ -211,7 +212,10 @@ files:
|
|
211
212
|
- samples/metrics.erb
|
212
213
|
- samples/nodes.html.erb
|
213
214
|
- samples/sample_keys.html.erb
|
215
|
+
- samples/service_checks_metrics.erb
|
214
216
|
- samples/services.html.erb
|
217
|
+
- samples/tools/find_all_failing_services.txt.erb
|
218
|
+
- samples/tools/find_all_nodes_without_id.txt.erb
|
215
219
|
- samples/vault-ldap.txt.erb
|
216
220
|
homepage: https://rubygems.org/gems/consul-templaterb
|
217
221
|
licenses:
|
@@ -236,7 +240,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
240
|
- !ruby/object:Gem::Version
|
237
241
|
version: '0'
|
238
242
|
requirements: []
|
239
|
-
|
243
|
+
rubyforge_project:
|
244
|
+
rubygems_version: 2.7.7
|
240
245
|
signing_key:
|
241
246
|
specification_version: 4
|
242
247
|
summary: Implementation of Consul template using Ruby and .erb templating language
|