consul-templaterb 1.9.9 → 1.10.0

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: 1bc60bdb2bf31bd1da18ee4623f62fdf7a664daa5f31a273712168591612a666
4
- data.tar.gz: 05dbb95ce7faba2da08b30cd6c7e8cdd96246d4e0bd4fd93996b279c9c2f6c61
3
+ metadata.gz: 9d389019e21022ecf1c1e1783133ff49379d6e97141cf5a083b2c9c805c013f7
4
+ data.tar.gz: 4860d2607e32173aae5e4e2aa606564bc1cc1ccec4876d2079c7f22404c2a4b0
5
5
  SHA512:
6
- metadata.gz: 11019612ceefc6258fe2d578bfedc836689c82c7e3118621298d7eaea21b22e65a48778422e378b50ac7799f733af8c4af1d3330356b8a0d0b10758f829725f4
7
- data.tar.gz: aa338fff43589ddbc32b6d8bc20982cbd58bf0f2fd556cc18c46865014592fdffb8b9ccd7f34d54a352b3476474ceb4edfd53b12785fa1a2e76c0f9836851a4b
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`):
@@ -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 "[ERROR] The process is dead, aborting run: #{e.inspect}"
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
- STDERR.puts "[INFO] Hot reload of template #{res.template_file} with success" if res.hot_reloaded
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
- STDERR.puts("[INFO] File written: #{results} #{template_manager.net_info.inspect}")
205
+ ::Consul::Async::Debug.puts_info "File written: #{results} #{template_manager.net_info.inspect}"
201
206
  else
202
- STDERR.print "[DBUG] Files not changed #{results} #{template_manager.net_info.inspect}\r"
207
+ ::Consul::Async::Debug.print_debug "Files not changed #{results} #{template_manager.net_info.inspect}\r"
203
208
  end
204
209
  else
205
- STDERR.print "[DBUG] Still waiting for data #{template_manager.net_info.inspect}...\r"
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
- puts "Using #{dest} output for #{tpl}"
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
- STDERR.puts "[INFO] Overriding #{symbol}:=#{sub[symbol]} for #{path}"
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
- STDERR.puts "[ERROR][#{path}] X-Consul-Index:#{consul_index} - #{http.error} - Retry in #{retry_in}s #{stats.body_bytes_human}"
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
- STDERR.puts "[RETRY][#{path}] (#{@consecutive_errors} errors) due to #{http.error}" if (@consecutive_errors % 10) == 1
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
- STDERR.print "[INFO] #{@last_debug} Waiting for data from #{not_ready.count}/#{not_ready.count + ready} endpoints: #{not_ready[0..2]}..."
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
- STDERR.puts "[INFO] Cleaned up #{to_cleanup.count} endpoints: #{to_cleanup}"
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
- STDERR.print "[INFO] Write #{Utilities.bytes_to_h data.bytesize} bytes to #{file}, "\
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 ...\n"
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
- STDERR.print '[INFO] Setting up vault token renewal'
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
- STDERR.print "[INFO] path #{path.ljust(64)} #{query_params.inspect}\r"
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
- STDERR.puts "[INFO] First rendering of #{results.count} templates completed"
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
- STDERR.puts "[ERROR] callback error: #{cbk_error.inspect}"
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 "[ERROR] Fatal error occured: #{e.inspect} - #{e.backtrace.join("\n\t")}"
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
- STDERR.puts "[INFO] Overriding #{symbol}:=#{sub[symbol]} for #{path}"
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| STDERR.puts "[ERROR]: #{path}: #{http.error}" }
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
- STDERR.puts "[ERROR][#{path}][#{http_method}] Code: #{http.response_header.status} #{_get_errors(http).join(' - ')} - Retry in #{retry_in}s #{stats.body_bytes_human}"
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
@@ -1,5 +1,5 @@
1
1
  module Consul
2
2
  module Async
3
- VERSION = '1.9.9'.freeze
3
+ VERSION = '1.10.0'.freeze
4
4
  end
5
5
  end
@@ -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 = instance.name + '::' + checkInstance.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).each do |snode|
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: service(service_name).endpoint.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 %> <%= datacenters().endpoint.stats.last_success_or_error.to_i * 1000 %>
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 %> <%= nodes().endpoint.stats.last_success_or_error.to_i * 1000 %>
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 %> <%= services(tag: service_tag_filter).endpoint.stats.last_success_or_error.to_i * 1000 %>
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.9.9
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-01-18 00:00:00.000000000 Z
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
- rubygems_version: 3.0.2
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