consul-templaterb 1.5.4 → 1.5.5

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: 29433f0be694b9d9358498c00ac3f4c0cf2112fdabd86801d94c2afe899243f9
4
- data.tar.gz: df4dcdd2a3862122ffb122e3abaad2da1691366fd672c4a111b703586161ad37
3
+ metadata.gz: ed586b6f530661c89df4f8f31dd1f4960742b1fcfd9ea2aed2af44da9f059c05
4
+ data.tar.gz: d0eb5d09751bd5a8eafac6bf67febce94601ceae65f03ede0f576627f1d179ef
5
5
  SHA512:
6
- metadata.gz: b20f9e3549f5a886da874cf48b567a264269573c8fdb0204c0d6e3627adc68297411a55de04fa9ec9e8946e5141b8a7dce548d90448d843792b29b8df533d680
7
- data.tar.gz: 06722bbfaf0149c3fb3ee5b071de9950fb950ebaa53167926ad8f7d24f0bb86ea43a07e0d08f4809d19e15d7607e6d4c3a5bb6ea5365c0dd3905c403b3b1d664
6
+ metadata.gz: 865873980923a237af55f5809eb8a9ebb484279897c5dd3f37c6b7a8a19a780ed1bde203a566883f921fb14c4dc8c3e750abdf10807f86546c47d681da7a9483
7
+ data.tar.gz: 96dfd1d681f5760897609a6ec69b66fde406745ee4fb718d94e8faa566f97581637e08bd57fc91dc520be109221d426da0e9c6d327480e04fc8f0ae5b5dafdbc
data/.travis.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.3
4
+ - 2.4
5
+ - 2.5
4
6
  deploy:
5
7
  provider: rubygems
6
8
  api_key:
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## (UNRELEASED)
4
4
 
5
+ ## 1.5.4 (September 27, 2018)
6
+
7
+ IMPROVEMENTS:
8
+
9
+ * Improved [Prometheus template](samples/metrics.erb) with many new metrics
10
+ * Documentation improvements regarding statistics and endpoints
11
+ * Code cleanups, code style, remove unused source file
12
+ * Travis build now runs rubocop and test with Ruby version from 2.3.x to 2.5.x
13
+
5
14
  ## 1.5.4 (September 26, 2018)
6
15
 
7
16
  IMPROVEMENTS:
data/TemplateAPI.md CHANGED
@@ -19,12 +19,29 @@ Have a look to [samples/](samples/) directory to start writing your own template
19
19
  All objects returned by those functions described below all share the same structure:
20
20
 
21
21
  * `.result` : handle the result
22
- * `.endpoint` : get technical information about how data was retrieved and statistics
22
+ * `.endpoint` : get technical information about how data was retrieved and statistics.
23
+
24
+ ## Accessing to statistics to monitor your cluster
25
+
26
+ All endpoints implement technical interface that allow to get information about what
27
+ is going on in your Consul Cluster.
28
+
29
+ On each object, you can access the `.endpoint` object that includes several informations about the endpoint being queried:
30
+
31
+ * `myresult.endpoint.x_consul_index` return the current index on blocking query
32
+ * `myresult.endpoint.stats` a object with interresting fields: `bytes_per_sec`,
33
+ `bytes_per_sec_human`, `successes`, `errors`, `body_bytes`. All stats details
34
+ are available in the file [lib/consul/async/stats.rb](lib/consul/async/stats.rb).
35
+
36
+ Using those statistics might be useful to trigger alerts very easily when something
37
+ is going on. Have a look to [samples/metrics.erb](samples/metrics.erb) that exposes
38
+ most of those metrics to [Prometheus](https://prometheus.io/).
23
39
 
24
40
  ## Common re-implemented functions for all objects
25
41
 
26
42
  Most objects returned by all those functions are contained within a `.result` object. However, in order
27
43
  to avoid having to write .result in all templates, some shortcuts have been added:
44
+
28
45
  * `[]` allow to either access values for map-based data or arrays
29
46
  * for all objects: `.each`, `sort`, `.select`, `.each_value`, `.count`, `.empty?`
30
47
  * additionnaly, for map based results, the following methods are available: `.keys`, `.values`, `.each_pair`,
@@ -1,5 +1,5 @@
1
1
  module Consul
2
2
  module Async
3
- VERSION = '1.5.4'.freeze
3
+ VERSION = '1.5.5'.freeze
4
4
  end
5
5
  end
data/samples/metrics.erb CHANGED
@@ -41,7 +41,10 @@
41
41
  state = compute_state(snode)[0]
42
42
  res[state] += 1
43
43
  end
44
- backends[service_name] = res
44
+ backends[service_name] = {
45
+ state: res,
46
+ stats: service(service_name).endpoint.stats,
47
+ }
45
48
  end
46
49
  end
47
50
  %>
@@ -59,13 +62,31 @@ consul_services_count <%= service_count %>
59
62
 
60
63
  # HELP consul_service_count A gauge of number instances of service with their current state
61
64
  # TYPE consul_service_count gauge
65
+ # HELP consul_service_stats_requests_total A counter of requests performed by consul-templaterb, show activity on a service
66
+ # TYPE consul_service_stats_requests_total counter
67
+ # HELP consul_service_stats_requests_bytes A counter of bytes transfered from Consul Agent to consul-templaterb
68
+ # TYPE consul_service_stats_requests_bytes counter
69
+ # HELP consul_service_stats_requests_bytes_per_sec A counter of bytes transfered from Consul Agent to consul-templaterb
70
+ # TYPE consul_service_stats_requests_bytes_per_sec gauge
71
+
62
72
  <%
63
73
  json_backends = {}
64
- backends.each_pair do |service_name, stats|
65
- stats.each_pair do |state_name, state_count|
74
+ backends.each_pair do |service_name, service_info|
75
+ service_info[:state].each_pair do |state_name, state_count|
66
76
  %>consul_service_count{service="<%= service_name %>",state="<%= state_name %>"} <%= state_count %>
67
77
  <%
68
78
  end
79
+ current_stats = service_info[:stats]
80
+ %>consul_service_stats_requests_total{service="<%= service_name %>",type="success"} <%= current_stats.successes %>
81
+ <%
82
+ if current_stats.errors > 0
83
+ %>consul_service_stats_requests_total{service="<%= service_name %>",type="errors"} <%= current_stats.errors %>
84
+ <%
85
+ end
86
+ %>consul_service_stats_requests_bytes{service="<%= service_name %>"} <%= service_info[:stats].body_bytes %>
87
+ consul_service_stats_requests_bytes_per_sec{service="<%= service_name %>"} <%= service_info[:stats].bytes_per_sec %>
88
+
89
+ <%
69
90
  end
70
91
  %>
71
92
 
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.5.4
4
+ version: 1.5.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-09-26 00:00:00.000000000 Z
11
+ date: 2018-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-http-request
@@ -165,7 +165,6 @@ files:
165
165
  - lib/consul/async/consul_template.rb
166
166
  - lib/consul/async/consul_template_engine.rb
167
167
  - lib/consul/async/consul_template_render.rb
168
- - lib/consul/async/endpoint.rb
169
168
  - lib/consul/async/process_handler.rb
170
169
  - lib/consul/async/stats.rb
171
170
  - lib/consul/async/utilities.rb
@@ -1,133 +0,0 @@
1
- require 'consul/async/utilities'
2
-
3
- class Endpoint
4
- attr_reader :conf, :path, :x_consul_index, :queue, :stats, :last_result, :enforce_json_200, :start_time, :default_value, :query_params
5
- def initialize(conf, path, enforce_json_200 = true, query_params = {}, default_value = '[]')
6
- @conf = conf.create(path)
7
- @default_value = default_value
8
- @path = path
9
- @queue = EM::Queue.new
10
- @s_callbacks = []
11
- @e_callbacks = []
12
- @enforce_json_200 = enforce_json_200
13
- @start_time = Time.now.utc
14
- @consecutive_errors = 0
15
- @query_params = query_params
16
- @stopping = false
17
- @stats = EndPointStats.new
18
- @last_result = ConsulResult.new(default_value, false, HttpResponse.new(nil), 0, stats, 1)
19
- on_response { |result| @stats.on_reponse result }
20
- on_error { |http| @stats.on_error http }
21
- _enable_network_debug if conf.debug && conf.debug[:network]
22
- fetch
23
- queue << 0
24
- end
25
-
26
- def _enable_network_debug
27
- on_response do |result|
28
- state = result.x_consul_index.to_i < 1 ? '[WARN]' : '[ OK ]'
29
- stats = result.stats
30
- STDERR.puts "[DEBUG]#{state}#{result.modified? ? '[MODIFIED]' : '[NO DIFF]'}" \
31
- "[s:#{stats.successes},err:#{stats.errors}]" \
32
- "[#{stats.body_bytes_human.ljust(8)}][#{stats.bytes_per_sec_human.ljust(9)}]"\
33
- " #{path.ljust(48)} idx:#{result.x_consul_index}, next in #{result.retry_in} s"
34
- end
35
- on_error { |http| STDERR.puts "[ERROR]: #{path}: #{http.error}" }
36
- end
37
-
38
- def on_response(&block)
39
- @s_callbacks << block
40
- end
41
-
42
- def on_error(&block)
43
- @e_callbacks << block
44
- end
45
-
46
- def ready?
47
- @ready
48
- end
49
-
50
- def terminate
51
- @stopping = true
52
- end
53
-
54
- private
55
-
56
- def build_request(headers = {}, query_params = {})
57
- req = {
58
- head: headers,
59
- path: path,
60
- query: query_params,
61
- keepalive: true,
62
- callback: method(:on_response)
63
- }
64
- @query_params.each_pair do |k, v|
65
- req[:query][k] = v
66
- end
67
- req
68
- end
69
-
70
- def _handle_error(http, consul_index)
71
- retry_in = [600, conf.retry_duration + 2**@consecutive_errors].min
72
- STDERR.puts "[ERROR][#{path}] X-Consul-Index:#{consul_index} - #{http.error} - Retry in #{retry_in}s #{stats.body_bytes_human}"
73
- @consecutive_errors += 1
74
- http_result = HttpResponse.new(http)
75
- EventMachine.add_timer(retry_in) do
76
- yield
77
- queue.push(consul_index)
78
- end
79
- @e_callbacks.each { |c| c.call(http_result) }
80
- end
81
-
82
- def fetch
83
- options = {
84
- connect_timeout: 5, # default connection setup timeout
85
- inactivity_timeout: conf.wait_duration + 1, # default connection inactivity (post-setup) timeout
86
- }
87
- connection = EventMachine::HttpRequest.new(conf.base_url, options)
88
- cb = proc do |consul_index|
89
- http = connection.get(build_request(consul_index))
90
- http.callback do
91
- # Dirty hack, but contrary to other path, when key is not present, Consul returns 404
92
- is_kv_empty = path.start_with?('/v1/kv') && http.response_header.status == 404
93
- if !is_kv_empty && enforce_json_200 && http.response_header.status != 200 && http.response_header['Content-Type'] != 'application/json'
94
- _handle_error(http, consul_index) { connection = EventMachine::HttpRequest.new(conf.base_url, options) }
95
- else
96
- n_consul_index = find_x_consul_token(http)
97
- @consecutive_errors = 0
98
- http_result = if is_kv_empty
99
- HttpResponse.new(http, default_value)
100
- else
101
- HttpResponse.new(http)
102
- end
103
- new_content = http_result.response.freeze
104
- modified = @last_result.nil? ? true : @last_result.data != new_content
105
- if n_consul_index == consul_index || n_consul_index.nil?
106
- retry_in = modified ? conf.missing_index_retry_time_on_diff : conf.missing_index_retry_time_on_unchanged
107
- n_consul_index = consul_index
108
- else
109
- retry_in = modified ? conf.min_duration : conf.retry_on_non_diff
110
- end
111
- retry_in = 0.1 if retry_in < 0.1
112
- unless @stopping
113
- EventMachine.add_timer(retry_in) do
114
- queue.push(n_consul_index)
115
- end
116
- end
117
- result = ConsulResult.new(new_content, modified, http_result, n_consul_index, stats, retry_in)
118
- @last_result = result
119
- @ready = true
120
- @s_callbacks.each { |c| c.call(result) }
121
- end
122
- end
123
-
124
- http.errback do
125
- unless @stopping
126
- _handle_error(http, consul_index) { connection = EventMachine::HttpRequest.new(conf.base_url, options) }
127
- end
128
- end
129
- queue.pop(&cb)
130
- end
131
- queue.pop(&cb)
132
- end
133
- end