upstreamstatus 0.1.4 → 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: 77442bcb1fb35809ba4dee0d9fa664d4ce79ff28
4
- data.tar.gz: 13690ddf6d8131802c59664653149e0f84d5a068
3
+ metadata.gz: ef04d1acd6a3a3cb9ffe50803011ed4c8e28c34f
4
+ data.tar.gz: 2067f08c7ab6969c6da022733b74d868172e5f43
5
5
  SHA512:
6
- metadata.gz: 3896631fe98a0a3e63bedfab3be758c705a70cd0ff571fd9e37e1a53658840bf0668130a531b25ad77fea4f3f87d85e9f776d214ae56cae10a74e00e70ebc0d0
7
- data.tar.gz: ba245144166e2bc2b9c63f4a15b58df22de0ea9313e77f29ff8a0a4fa48dfdbf64a8c4a55c19914c477589bc3a1ad564c49406556186358829125addabfcf02c
6
+ metadata.gz: daaa2d4b7efdad135ef9f57cc93c5a902a714940e372d780f8c4150abaca911b609eef31f3ca6ee16a1c7c358795b59579c6008224e3301d234852d7f4c84eeb
7
+ data.tar.gz: fc49aeaec02b4f040e6f80c781f5c718773484224d6c48d161a25b0cce15c4578619139b02089bdc42eaeb0aa9f597d6c03382527620fcdf2de9d5de77308da0
@@ -1,3 +1,3 @@
1
1
  class Upstreamstatus
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -2,34 +2,50 @@ require 'upstreamstatus/version'
2
2
  require 'unirest'
3
3
  require 'yaml'
4
4
  require 'ostruct'
5
+ require 'trollop'
5
6
  require 'forwardable'
7
+ require 'json'
6
8
 
7
9
  class Upstreamstatus
8
10
  extend Forwardable
9
11
 
10
12
  def_delegators :@conf,
11
- :status_check_url
13
+ :status_check_url,
14
+ :sentry_dsn,
15
+ :pagerduty_api_key
16
+
17
+ attr_reader :conf
12
18
 
13
19
  def initialize
14
20
  @conf = OpenStruct.new load_conf
21
+
22
+ return unless opts[:notify] && sentry_dsn
23
+ Raven.configure do |config|
24
+ config.dsn = sentry_dsn
25
+ config.logger = logger
26
+ end
15
27
  end
16
28
 
17
29
  def run
18
30
  down_hosts =
19
31
  current_status['servers']['server'].select { |s| s['status'] != 'up' }
20
32
 
21
- exit 0 if down_hosts.empty?
22
- print_hosts down_hosts
23
- exit 1
24
- end
33
+ if down_hosts.empty?
34
+ clear_active_alerts!
35
+ exit 0
36
+ end
25
37
 
26
- private
38
+ print_hosts down_hosts
39
+ logger.notice "Detected down hosts: #{down_hosts.to_json}"
27
40
 
28
- def print_hosts(hosts)
29
- hosts.each do |host|
30
- host.each { |k, v| puts "#{k}: #{v}" }
31
- puts
41
+ if opts[:notify]
42
+ puts 'Sending notifications'
43
+ notify(
44
+ 'One or more API upstream hosts listed as down',
45
+ JSON.pretty_generate(down_hosts)
46
+ )
32
47
  end
48
+ exit 1
33
49
  end
34
50
 
35
51
  def current_status
@@ -44,6 +60,68 @@ class Upstreamstatus
44
60
  r.body
45
61
  end
46
62
 
63
+ private
64
+
65
+ def clear_active_alerts!
66
+ return unless File.exist? '/var/run/active_upstream_alert'
67
+ File.delete('/var/run/active_upstream_alert')
68
+ end
69
+
70
+ def logger
71
+ @logger ||= Logger.new(conf['log']).tap { |l| l.progname = 'upstreamstatus' }
72
+ end
73
+
74
+ def pagerduty
75
+ @pagerduty ||= Pagerduty.new pagerduty_api_key
76
+ end
77
+
78
+ def notify(msg, details)
79
+ unless active_alert?(msg)
80
+ pd = pagerduty.trigger(
81
+ msg,
82
+ client: ENV['hostname'],
83
+ details: details
84
+ )
85
+
86
+ # You may have noticed that this will overwrite any previously active
87
+ # alerts, regardless of whether they are the "same" alert. This is a known
88
+ # limitation.
89
+
90
+ File.write(
91
+ '/var/run/active_upstream_alert',
92
+ {
93
+ 'Incident Key' => pd.incident_key,
94
+ 'Message' => msg,
95
+ 'Details' => details
96
+ }.to_json
97
+ )
98
+ end
99
+
100
+ Raven.capture_exception(e) if sentry_dsn
101
+ end
102
+
103
+ def active_alert?(msg)
104
+ File.exist?('/var/run/active_upstream_alert') &&
105
+ (Time.now - File.ctime('/var/run/active_upstream_alert')) < 3600 &&
106
+ JSON.parse(File.read('/var/run/active_upstream_alert'))['msg'] == msg
107
+ end
108
+
109
+ def opts
110
+ @opts ||= Trollop.options do
111
+ opt :notify,
112
+ 'Notify alert service on failure',
113
+ short: '-n',
114
+ default: false
115
+ end
116
+ end
117
+
118
+ def print_hosts(hosts)
119
+ hosts.each do |host|
120
+ host.each { |k, v| puts "#{k}: #{v}" }
121
+ puts
122
+ end
123
+ end
124
+
47
125
  def load_conf
48
126
  conf_file = '/etc/upstreamstatus.yml'
49
127
  yaml_conf = File.exist?(conf_file) ? YAML.load_file(conf_file) : {}
@@ -51,8 +129,6 @@ class Upstreamstatus
51
129
  end
52
130
 
53
131
  def defaults
54
- {
55
- 'status_check_url' => 'http://localhost:8069/status?format=json'
56
- }
132
+ { 'status_check_url' => 'http://localhost:8069/status?format=json' }
57
133
  end
58
134
  end
@@ -27,9 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
- spec.add_dependency 'unirest'
30
+ spec.add_dependency 'unirest', '~> 1.1'
31
+ spec.add_dependency 'trollop', '~> 2.1'
31
32
 
32
33
  spec.add_development_dependency 'bundler', '~> 1.10'
33
34
  spec.add_development_dependency 'rake', '~> 10.0'
34
35
  spec.add_development_dependency 'rspec'
36
+ spec.add_development_dependency 'byebug'
35
37
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upstreamstatus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Herot
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-21 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: unirest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: trollop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description: Parse the output of the Nginx Upstream Check plugin
70
98
  email:
71
99
  - eric.github@herot.com
@@ -114,4 +142,3 @@ signing_key:
114
142
  specification_version: 4
115
143
  summary: Parse the output of the Nginx Upstream Check plugin
116
144
  test_files: []
117
- has_rdoc: