deadman_check 0.1.11 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12920b0224825d46cdd41699ae4221770170d1de
4
- data.tar.gz: 4979ff88b6ac486c39a7fe3b8a00ace5e2567b45
3
+ metadata.gz: 60016a96e65047af901a74875d61fd0052cebf86
4
+ data.tar.gz: 08e97ecbae9e2d7cc68dc80b1dbc0153700ff9f8
5
5
  SHA512:
6
- metadata.gz: def14d2515337b1adf18abdce2f460241eb5a33a21bd2e33103cdbc2e4778644e4fbb816e12155f19ff1454b70050a5200bdd69fed857f7289a6ac38b881e1fb
7
- data.tar.gz: 9e2eb7f0f3113d4b8b6b5c11f1d21c2e8fa43516d556820b2cc76014ea444db480ea73662501ce2874eb2999bc436787f14132e371fd90dc26013ecb62fc433a
6
+ metadata.gz: 8e41ca251ccfa94ad4731b19a8b9f4ed61fbbecaae6dd9eb4d94517e15faeb640adbb867a2c7c24ef18357081718e467b2096d6406929513bddce67db1b9e129
7
+ data.tar.gz: c9b409c2cf717875c3645567dba926bc0a57ee659d6e3daebf9cfec1b896342267b8e7870ebd27dee38986ef1411f17b550d069c927f8763bad12311c81371d0
data/README.md CHANGED
@@ -89,7 +89,9 @@ job "SilverBulletPeriodic" {
89
89
  "--port",
90
90
  "8500",
91
91
  "--key",
92
- "deadman/SilverBulletPeriodicProcess"]
92
+ "deadman/SilverBulletPeriodicProcess",
93
+ "--frequency",
94
+ "700"]
93
95
  }
94
96
  resources {
95
97
  cpu = 100
@@ -99,8 +101,7 @@ job "SilverBulletPeriodic" {
99
101
  }
100
102
  }
101
103
  ```
102
-
103
- <img width="1215" alt="screen shot 2017-03-26 at 3 28 50 pm" src="https://cloud.githubusercontent.com/assets/538171/24335809/276147ec-1239-11e7-83d8-0fca95bebdc2.png">
104
+ <img width="1215" alt="screen shot 2017-04-23 at 11 14 36 pm" src="https://cloud.githubusercontent.com/assets/538171/25324439/b65541d6-287a-11e7-9b6d-4e1c9565eed2.png">
104
105
 
105
106
  Now the key, deadman/SilverBulletPeriodicProcess, at 10.0.0.1 will be updated with
106
107
  the EPOCH time for each SilverBulletPeriodic job run. If the job hangs or fails to run
@@ -126,8 +127,6 @@ job "DeadmanMonitoring" {
126
127
  "8500",
127
128
  "--key",
128
129
  "deadman/SilverBulletPeriodicProcess",
129
- "--freshness",
130
- "800",
131
130
  "--alert-to",
132
131
  "slackroom",
133
132
  "--daemon",
@@ -146,10 +145,52 @@ job "DeadmanMonitoring" {
146
145
  }
147
146
  ```
148
147
 
149
- Monitor a Consul key that contains an EPOCH time entry. Send a Slack message if EPOCH age hits given threshold
148
+ Monitor a Consul key that contains an EPOCH time entry. Send a Slack message if EPOCH age hits given frequency threshold
150
149
 
151
150
  <img width="752" alt="screen shot 2017-03-26 at 3 29 28 pm" src="https://cloud.githubusercontent.com/assets/538171/24335811/2e57eee8-1239-11e7-9fff-c8a10d956f2e.png">
152
151
 
152
+ If you have multiple periodic jobs that need to be monitored then use the ```--key-path``` argument instead of ```--key```. Be sure to ```key_set``` all under the same Consul key path.
153
+
154
+ <img width="658" alt="screen shot 2017-04-23 at 11 17 29 pm" src="https://cloud.githubusercontent.com/assets/538171/25324510/14d6e7f0-287b-11e7-9c0d-733d69e1cc94.png">
155
+
156
+ To monitor the above you would just use the ```--key-path``` argument instead of ```--key```
157
+
158
+ ```hcl
159
+ job "DeadmanMonitoring" {
160
+ datacenters = ["dc1"]
161
+ type = "service"
162
+
163
+ group "monitor" {
164
+ task "DeadmanMonitorSilverBulletPeriodicProcesses" {
165
+ driver = "docker"
166
+ config {
167
+ image = "sepulworld/deadman-check"
168
+ command = "switch_monitor"
169
+ args = [
170
+ "--host",
171
+ "10.0.0.1",
172
+ "--port",
173
+ "8500",
174
+ "--key-path",
175
+ "deadman/",
176
+ "--alert-to",
177
+ "slackroom",
178
+ "--daemon",
179
+ "--daemon-sleep",
180
+ "900"]
181
+ }
182
+ resources {
183
+ cpu = 100
184
+ memory = 256
185
+ }
186
+ env {
187
+ SLACK_API_TOKEN = "YourSlackApiToken"
188
+ }
189
+ }
190
+ }
191
+ }
192
+ ```
193
+
153
194
  # Non-Nomad Use:
154
195
 
155
196
  ## Local system installation
@@ -185,8 +226,7 @@ $ deadman-check -h
185
226
 
186
227
  DESCRIPTION:
187
228
 
188
- Monitor a Consul key that contains an EPOCH time entry.
189
- Send a Slack message if EPOCH age hits given threshold
229
+ Monitor a Consul key or key-path that contains an EPOCH time entry and frequency. Send Slack message if EPOCH age is greater than given frequency
190
230
 
191
231
  COMMANDS:
192
232
 
@@ -221,12 +261,12 @@ $ deadman-check key_set -h
221
261
 
222
262
  DESCRIPTION:
223
263
 
224
-
264
+ key_set will set a consul key that contains the current epoch and time frequency that job should be running at, example key {"epoch":1493010437,"frequency":"300"}
225
265
 
226
266
  EXAMPLES:
227
267
 
228
268
  # Update a Consul key deadman/myservice, with current EPOCH time
229
- deadman-check key_set --host 127.0.0.1 --port 8500 --key deadman/myservice
269
+ deadman-check key_set --host 127.0.0.1 --port 8500 --key deadman/myservice --frequency 300
230
270
 
231
271
  OPTIONS:
232
272
 
@@ -237,7 +277,10 @@ $ deadman-check key_set -h
237
277
  port Consul is listening on
238
278
 
239
279
  --key KEY
240
- Consul key to monitor
280
+ Consul key to report EPOCH time and frequency for service
281
+
282
+ --frequency FREQUENCY
283
+ Frequency at which this key should be updated in seconds
241
284
  ```
242
285
 
243
286
  ### Usage for switch_monitor command
@@ -255,18 +298,15 @@ $ deadman-check switch_monitor -h
255
298
 
256
299
  DESCRIPTION:
257
300
 
258
-
301
+ switch_monitor will monitor either a given key which contains a services last epoch checkin and frequency, or a series of services that set keys under a given key-path in Consul
259
302
 
260
303
  EXAMPLES:
261
304
 
262
- # Target a Consul key deadman/myservice, and this key has an EPOCH
263
- value to check looking to alert on 500 second or greater freshness
264
- deadman-check switch_monitor \
265
- --host 127.0.0.1 \
266
- --port 8500 \
267
- --key deadman/myservice \
268
- --freshness 500 \
269
- --alert-to slackroom
305
+ # Target a Consul key deadman/myservice, and this key has an EPOCH value to check looking to alert
306
+ deadman-check switch_monitor --host 127.0.0.1 --port 8500 --key deadman/myservice --alert-to monitoroom
307
+
308
+ # Target a Consul key path deadman/, which contains 2 or more service keys to monitor, i.e. deadman/myservice1, deadman/myservice2, deadmman/myservice3 all fall under the path deadman/
309
+ deadman-check switch_monitor --host 127.0.0.1 --port 8500 --key-path deadman/ --alert-to monitoroom
270
310
 
271
311
  OPTIONS:
272
312
 
@@ -276,15 +316,14 @@ $ deadman-check switch_monitor -h
276
316
  --port PORT
277
317
  port Consul is listening on
278
318
 
279
- --key KEY
280
- Consul key to monitor
319
+ --key-path KEYPATH
320
+ Consul key path to monitor, performs a recursive key lookup at given path.
281
321
 
282
- --freshness SECONDS
283
- The value in seconds to alert on when the recorded
284
- EPOCH value exceeds current EPOCH
322
+ --key KEY
323
+ Consul key to monitor, provide this or --key-path if you have multiple keys in a given path.
285
324
 
286
325
  --alert-to SLACKROOM
287
- Slackroom to alert to, don't include the # tag in name
326
+ Slackroom to send alert, don't include the # tag in name
288
327
 
289
328
  --daemon
290
329
  Run as a daemon, otherwise will run check just once
data/bin/deadman-check CHANGED
@@ -7,26 +7,37 @@ require 'daemons'
7
7
 
8
8
  program :name, 'deadman-check'
9
9
  program :version, DeadmanCheck::VERSION
10
- program :description, %q{Monitor a Consul key that contains an EPOCH time entry. Send email if EPOCH age hits given threshold}
10
+ program :description, %q{Monitor a Consul key or key-path that contains an EPOCH time entry and frequency. Send Slack message if EPOCH age is greater than given frequency}
11
11
 
12
12
  command :switch_monitor do |c|
13
13
  c.syntax = 'deadman-check switch_monitor [options]'
14
14
  c.summary = 'Target a Consul key to monitor'
15
- c.description = ''
16
- c.example %q{Target a Consul key deadman/myservice, and this key has an EPOCH value to check looking to alert on 500 second or greater freshness},
17
- %q{deadman-check switch_monitor --host 127.0.0.1 --port 8500 --key deadman/myservice --freshness 500 --alert-to ops@mycomany.tld --alert-from ops-no-reply-email@mycomany.tld}
15
+ c.description = 'switch_monitor will monitor either a given key which contains a services last epoch checkin and frequency, or a series of services that set keys under a given key-path in Consul'
16
+ c.example %q{Target a Consul key deadman/myservice, and this key has an EPOCH value to check looking to alert},
17
+ %q{deadman-check switch_monitor --host 127.0.0.1 --port 8500 --key deadman/myservice --alert-to monitoroom}
18
+ c.example %q{Target a Consul key path deadman/, which contains 2 or more service keys to monitor, i.e. deadman/myservice1, deadman/myservice2, deadmman/myservice3 all fall under the path deadman/},
19
+ %q{deadman-check switch_monitor --host 127.0.0.1 --port 8500 --key-path deadman/ --alert-to monitoroom}
18
20
  c.option '--host HOST', String, 'IP address or hostname of Consul system'
19
21
  c.option '--port PORT', String, 'port Consul is listening on'
20
- c.option '--key KEY', String, 'Consul key to monitor'
21
- c.option '--freshness SECONDS', String, %q{The value in seconds to alert on when the recorded
22
- EPOCH value exceeds current EPOCH}
23
- c.option '--alert-to SLACKROOM', String, 'Slackroom to alert to'
22
+ c.option '--key-path KEYPATH', String, 'Consul key path to monitor, performs a recursive key lookup at given path.'
23
+ c.option '--key KEY', String, 'Consul key to monitor, provide this or --key-path if you have multiple keys in a given path.'
24
+ c.option '--alert-to SLACKROOM', String, 'Slackroom to send alert, don\'t include the # tag in name'
24
25
  c.option '--daemon', 'Run as a daemon, otherwise will run check just once'
25
26
  c.option '--daemon-sleep SECONDS', String, 'Set the number of seconds to sleep in between switch checks, default 300'
26
27
  c.action do |args, options|
27
28
  options.default :daemon_sleep => 300
29
+ if options.key_path && options.key
30
+ abort("Specify --key-path or --key, don't specify both")
31
+ end
32
+ if options.key
33
+ target = options.key
34
+ recurse = false
35
+ else
36
+ target = options.key_path
37
+ recurse = true
38
+ end
28
39
  switch_monitor = DeadmanCheck::SwitchMonitor.new(options.host, options.port,
29
- options.key, options.freshness, options.alert_to, options.daemon_sleep)
40
+ target, options.alert_to, recurse, options.daemon_sleep)
30
41
  if options.daemon
31
42
  Daemons.run(switch_monitor.run_check_daemon)
32
43
  else
@@ -38,15 +49,16 @@ end
38
49
  command :key_set do |c|
39
50
  c.syntax = 'deadman-check key_set [options]'
40
51
  c.summary = 'Update a given Consul key with current EPOCH'
41
- c.description = ''
52
+ c.description = 'key_set will set a consul key that contains the current epoch and time frequency for which the job being monitored runs at, example key {"epoch":1493010437,"frequency":"300"}'
42
53
  c.example %q{Update a Consul key deadman/myservice, with current EPOCH time},
43
- %q{deadman-check key_set --host 127.0.0.1 --port 8500 --key deadman/myservice}
54
+ %q{deadman-check key_set --host 127.0.0.1 --port 8500 --key deadman/myservice --frequency 300}
44
55
  c.option '--host HOST', String, 'IP address or hostname of Consul system'
45
56
  c.option '--port PORT', String, 'port Consul is listening on'
46
- c.option '--key KEY', String, 'Consul key to report EPOCH time to'
57
+ c.option '--key KEY', String, 'Consul key to report EPOCH time and frequency for service'
58
+ c.option '--frequency FREQUENCY', String, 'Frequency at which this key should be updated in seconds'
47
59
  c.action do |args, options|
48
- key_set = DeadmanCheck::KeySet.new(options.host, options.port,
49
- options.key)
60
+ key_set = DeadmanCheck::KeySet.new(options.host, options.port, options.key,
61
+ options.frequency)
50
62
  key_set.run_consul_key_update
51
63
  end
52
64
  end
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency "bundler", "~> 1.13"
34
34
  spec.add_development_dependency "rake", "~> 10.0"
35
35
  spec.add_development_dependency "minitest", "~> 5.0"
36
+ spec.add_development_dependency "webmock", "~> 3.0"
36
37
 
37
38
  spec.add_dependency 'commander', '~> 4.4', '>= 4.4.3'
38
39
  spec.add_dependency 'diplomat', '~> 1.2', '>= 1.2.0'
@@ -1,3 +1,3 @@
1
1
  module DeadmanCheck
2
- VERSION = "0.1.11"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,33 +1,35 @@
1
1
  require 'deadman_check/version'
2
2
  require 'deadman_check_global'
3
3
  require 'diplomat'
4
+ require 'json'
4
5
 
5
6
  module DeadmanCheck
6
7
  # KeySet Class
7
8
  class KeySet
8
- attr_accessor :host, :port, :key
9
+ attr_accessor :host, :port, :key, :frequency
9
10
 
10
- def initialize(host, port, key)
11
+ def initialize(host, port, key, frequency)
11
12
  @host = host
12
13
  @port = port
13
14
  @key = key
15
+ @frequency = frequency
14
16
  end
15
17
 
16
- def _configure_diplomat(host, port)
17
- Diplomat.configure do |config|
18
- config.url = "http://#{host}:#{port}"
19
- end
18
+ def run_consul_key_update
19
+ update_consul_key(@host, @port, @key, @frequency)
20
20
  end
21
21
 
22
- def _update_consul_key(host, port, key)
23
- DeadmanCheck::DeadmanCheckGlobal.new.configure_diplomat(host, port)
24
- epoch_time_now = DeadmanCheck::DeadmanCheckGlobal.new.get_epoch_time
25
- Diplomat::Kv.put(key, "#{epoch_time_now}")
26
- puts "Consul key #{key} updated EPOCH to #{epoch_time_now}"
27
- end
22
+ private
23
+ def generate_json(epoch, frequency)
24
+ consul_key = { :epoch => epoch, :frequency => frequency }
25
+ consul_key.to_json
26
+ end
28
27
 
29
- def run_consul_key_update
30
- _update_consul_key(@host, @port, @key)
31
- end
28
+ def update_consul_key(host, port, key, frequency)
29
+ DeadmanCheck::DeadmanCheckGlobal.new.configure_diplomat(host, port)
30
+ epoch_time_now = DeadmanCheck::DeadmanCheckGlobal.new.get_epoch_time
31
+ Diplomat::Kv.put(key, "#{generate_json(epoch_time_now, frequency)}")
32
+ puts "Consul key #{key} updated EPOCH to #{epoch_time_now}"
33
+ end
32
34
  end
33
35
  end
@@ -2,18 +2,19 @@ require 'deadman_check/version'
2
2
  require 'deadman_check_global'
3
3
  require 'diplomat'
4
4
  require 'slack-ruby-client'
5
+ require 'json'
5
6
 
6
7
  module DeadmanCheck
7
8
  # Switch class
8
9
  class SwitchMonitor
9
- attr_accessor :host, :port, :key, :freshness, :alert_to, :daemon_sleep
10
+ attr_accessor :host, :port, :target, :alert_to, :recurse, :daemon_sleep
10
11
 
11
- def initialize(host, port, key, freshness, alert_to, daemon_sleep)
12
+ def initialize(host, port, target, alert_to, recurse, daemon_sleep)
12
13
  @host = host
13
14
  @port = port
14
- @key = key
15
- @freshness = freshness.to_i
15
+ @target = target
16
16
  @alert_to = alert_to
17
+ @recurse = recurse
17
18
  @daemon_sleep = daemon_sleep.to_i
18
19
  end
19
20
 
@@ -21,39 +22,74 @@ module DeadmanCheck
21
22
  config.token = ENV['SLACK_API_TOKEN']
22
23
  end
23
24
 
24
- def _diff_epoc(current_epoch, recorded_epoch)
25
- epoch_difference = current_epoch - recorded_epoch
26
- return epoch_difference
27
- end
28
-
29
- def _get_recorded_epoch(host, port, key)
30
- DeadmanCheck::DeadmanCheckGlobal.new.configure_diplomat(host, port)
31
- recorded_epoch = Diplomat::Kv.get(key)
32
- return recorded_epoch
33
- end
34
-
35
- def slack_alert(alert_to, key, epoch_diff)
36
- client = Slack::Web::Client.new
37
- client.chat_postMessage(channel: "\##{alert_to}", text: "Alert: Deadman Switch
38
- Triggered for #{key}, with #{epoch_diff} seconds since last run",
39
- username: 'deadman')
40
- end
41
-
42
25
  def run_check_once
43
- recorded_epoch = _get_recorded_epoch(@host, @port, @key).to_i
26
+ recorded_epochs = get_recorded_epochs(@host, @port, @target, @recurse)
44
27
  current_epoch = DeadmanCheck::DeadmanCheckGlobal.new.get_epoch_time.to_i
45
- epoch_diff = _diff_epoc(current_epoch, recorded_epoch)
46
- if epoch_diff > @freshness
47
- slack_alert(@alert_to, @key, epoch_diff)
28
+ if @recurse
29
+ check_recursive_recorded_epochs(recorded_epochs, current_epoch)
30
+ else
31
+ record = parse_recorded_epoch(recorded_epochs)
32
+ check_recorded_epoch(record, current_epoch)
48
33
  end
49
34
  end
50
35
 
51
36
  def run_check_daemon
52
37
  loop do
53
- run_check_once
38
+ run_check_once(target, recurse)
54
39
  sleep(@daemon_sleep)
55
40
  end
56
41
  end
57
42
 
43
+ private
44
+ def diff_epoch(current_epoch, recorded_epoch)
45
+ epoch_difference = current_epoch - recorded_epoch
46
+ return epoch_difference
47
+ end
48
+
49
+ def get_recorded_epochs(host, port, target, recurse)
50
+ DeadmanCheck::DeadmanCheckGlobal.new.configure_diplomat(host, port)
51
+ recorded_epochs = Diplomat::Kv.get(target, recurse: recurse)
52
+ return recorded_epochs
53
+ end
54
+
55
+ def parse_recorded_epoch(recorded_epochs)
56
+ # {"epoch":1493000501,"frequency":"300"}
57
+ value_json = JSON.parse(recorded_epochs)
58
+ frequency = value_json["frequency"].to_i
59
+ epoch = value_json["epoch"].to_i
60
+ return epoch, frequency
61
+ end
62
+
63
+ def alert_if_epoch_greater_than_frequency(epoch_diff, target, frequency)
64
+ if epoch_diff > frequency
65
+ slack_alert(@alert_to, target, epoch_diff)
66
+ end
67
+ end
68
+
69
+ def check_recorded_epoch(parse_recorded_epoch, current_epoch)
70
+ recorded_epoch = parse_recorded_epoch[0].to_i
71
+ frequency = parse_recorded_epoch[1].to_i
72
+ epoch_diff = diff_epoch(current_epoch, recorded_epoch)
73
+ alert_if_epoch_greater_than_frequency(epoch_diff, @target, frequency)
74
+ end
75
+
76
+ def check_recursive_recorded_epochs(recorded_epochs, current_epoch)
77
+ recorded_epochs.each do |recorded_service|
78
+ value_json = JSON.parse(recorded_service[:value])
79
+ frequency = value_json["frequency"].to_i
80
+ epoch = value_json["epoch"].to_i
81
+ epoch_diff = diff_epoch(current_epoch, epoch)
82
+ alert_if_epoch_greater_than_frequency(epoch_diff,
83
+ recorded_service[:key],
84
+ frequency)
85
+ end
86
+ end
87
+
88
+ def slack_alert(alert_to, target, epoch_diff)
89
+ client = Slack::Web::Client.new
90
+ client.chat_postMessage(channel: "\##{alert_to}", text: "Alert: Deadman Switch
91
+ Triggered for #{target}, with #{epoch_diff} seconds since last run",
92
+ username: 'deadman')
93
+ end
58
94
  end
59
95
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deadman_check
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.11
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-13 00:00:00.000000000 Z
11
+ date: 2017-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: commander
57
71
  requirement: !ruby/object:Gem::Requirement