deadman_check 0.1.11 → 0.2.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
  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