upstreamstatus 0.2.6 → 0.3.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: bd0f5883836782fed4233bd0ace4cd5154c4bc31
4
- data.tar.gz: c6711826ac9880fafeec8503830d65a8450b59ab
3
+ metadata.gz: 551dd8502211ecb555bed1af238fdbb134bb822e
4
+ data.tar.gz: 6f898adcff62a5ea936973848173d6dd12ebbefc
5
5
  SHA512:
6
- metadata.gz: 9219c273817d132304dca8cfe47403d2f41d2cb5c55af3df67ed16fb7429b69d14a224ff312b7df56110e0af1de392b4cb0739ef41670f008185dc5d46e34024
7
- data.tar.gz: 83c547e71abdc2a041d4cdad1b26c37980b51af03c4148bab8db16766e60282e00910d8b603fdb614cdcb61f6106f15f8f62a62502046d26941801beba953fc8
6
+ metadata.gz: 68d220a9b70a101755492030c8b001fb1aee2fbb0b5f3b9258b3a08a2484b7f04f1cbf30b84f09783c0c17c685d8d9f9188a72d39de0edf401b2286f467d953e
7
+ data.tar.gz: f46a8d49bfbc90aa324036894b3cc0a9b75bbb291407da17e6fbb0f10f22e023983e2e11ad685b4e8ea29fb10105200d99a2ac67589cd9efe951a5345531ab06
@@ -1,3 +1,3 @@
1
1
  class Upstreamstatus
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -9,6 +9,8 @@ require 'json'
9
9
  require 'sentry-raven'
10
10
  require 'pagerduty'
11
11
  require 'time'
12
+ require 'socket'
13
+ require 'byebug'
12
14
 
13
15
  class Upstreamstatus
14
16
  extend Forwardable
@@ -48,24 +50,26 @@ class Upstreamstatus
48
50
  end
49
51
  end
50
52
 
53
+ def down_hosts
54
+ current_status['servers']['server'].select { |s| s['status'] != 'up' }
55
+ end
56
+
51
57
  def run
52
- down_hosts =
53
- current_status['servers']['server'].select { |s| s['status'] != 'up' }
58
+ clear_active_alerts
54
59
 
55
- if down_hosts.empty?
56
- clear_active_alerts!
57
- exit 0
58
- end
60
+ exit 0 if down_hosts.empty?
59
61
 
60
62
  puts "Detected down hosts:\n"
61
63
  print_hosts down_hosts
62
64
  logger.info "Detected down hosts: #{down_hosts.to_json}"
63
65
 
64
66
  if opts[:notify]
65
- notify(
66
- 'One or more API upstream hosts listed as down',
67
- JSON.pretty_generate(down_hosts)
68
- )
67
+ down_hosts.each do |host|
68
+ notify(
69
+ "Upstream host #{host['upstream']} listed as down",
70
+ host
71
+ )
72
+ end
69
73
  end
70
74
  exit 1
71
75
  rescue Interrupt => e
@@ -84,73 +88,71 @@ class Upstreamstatus
84
88
  end
85
89
 
86
90
  def current_status
87
- return fake_response if opts[:simulate]
91
+ @current_status ||= begin
92
+ return fake_response if opts[:simulate]
88
93
 
89
- r = Unirest.get status_check_url
94
+ r = Unirest.get status_check_url
90
95
 
91
- unless (200..299).include?(r.code)
92
- fail "Error code: #{r.code}\n" \
93
- "Headers: #{r.headers}" \
94
- "Body: #{r.body}"
95
- end
96
+ unless (200..299).include?(r.code)
97
+ fail "Error code: #{r.code}\n" \
98
+ "Headers: #{r.headers}" \
99
+ "Body: #{r.body}"
100
+ end
96
101
 
97
- r.body
102
+ r.body
103
+ end
98
104
  end
99
105
 
100
106
  private
101
107
 
102
- def pd_incidents
103
- @pd_incidents ||= begin
104
- r = Unirest.get(
105
- "#{pagerduty_api_url}/incidents",
106
- parameters: { service: pagerduty_service_id }
108
+ def notify(msg, host)
109
+ if active_alert?(host['upstream'])
110
+ puts "Already an active alert. Not sending anything (message: #{msg})"
111
+ else
112
+ puts "Notifying PagerDuty (message: #{msg})"
113
+ pagerduty.trigger(
114
+ msg,
115
+ incident_key: "upstreamstatus #{Socket.gethostname} #{host['upstream']}",
116
+ client: Socket.gethostname,
117
+ details: host
107
118
  )
108
- fail "Result: #{r.inspect}" unless (200..299).include?(r.code)
109
- r.body['incidents']
110
119
  end
111
120
  end
112
121
 
113
- def fake_response
114
- {
115
- 'servers' => {
116
- 'total' => 2,
117
- 'generation' => 99,
118
- 'server' => [
119
- {
120
- 'index' => 0,
121
- 'upstream' => 'testupstream',
122
- 'name' => '10.0.0.1 =>8080',
123
- 'status' => 'up',
124
- 'rise' => 10_459,
125
- 'fall' => 0,
126
- 'type' => 'http',
127
- 'port' => 0
128
- },
129
- {
130
- 'index' => 1,
131
- 'upstream' => 'testupstream',
132
- 'name' => '10.0.0.2 =>8080',
133
- 'status' => 'down',
134
- 'rise' => 10_029,
135
- 'fall' => 0,
136
- 'type' => 'http',
137
- 'port' => 0
138
- }
139
- ]
122
+ def active_alert?(host)
123
+ active_alerts.find do |a|
124
+ a['incident_key'] == "upstreamstatus #{Socket.gethostname} #{host['upstream']}"
125
+ end
126
+ end
127
+
128
+ def active_alerts
129
+ @active_alerts ||= active_alerts_paged
130
+ end
131
+
132
+ def active_alerts_paged(offset = 0)
133
+ r = Unirest.get(
134
+ "#{pagerduty_api_url}/incidents",
135
+ parameters: {
136
+ service: pagerduty_service_id,
137
+ status: 'triggered,acknowledged',
138
+ offset: offset
140
139
  }
141
- }
140
+ )
141
+ fail "Result: #{r.inspect}" unless (200..299).include?(r.code)
142
+ pointer = r.body['limit'] + offset
143
+ r.body['incidents'] + (pointer < r.body['total'] ? active_alerts_paged(pointer) : [])
142
144
  end
143
145
 
144
- def clear_active_alerts!
146
+ def clear_active_alerts
145
147
  return unless opts[:notify]
146
- pd_incidents.each do |i|
147
- resolve_incident i['incident_key'] unless i['status'] == 'resolved'
148
+ active_alerts.reject { |a| down_hosts_incident_keys.include? a['incident_key'] }.each do |a|
149
+ puts "Resolving incident: #{a['incident_key']}"
150
+ pagerduty.get_incident(a['incident_key']).resolve
148
151
  end
149
152
  end
150
153
 
151
- def resolve_incident(incident_key)
152
- puts "Resolving incident: #{incident_key}"
153
- pagerduty.get_incident(incident_key).resolve
154
+ def down_hosts_incident_keys
155
+ down_hosts.map { |host| "upstreamstatus #{Socket.gethostname} #{host['upstream']}" }
154
156
  end
155
157
 
156
158
  def logger
@@ -161,39 +163,6 @@ class Upstreamstatus
161
163
  @pagerduty ||= Pagerduty.new pagerduty_api_key
162
164
  end
163
165
 
164
- def notify(msg, details)
165
- if active_alert?(msg)
166
- puts "Already an active alert. Not sending anything (message: #{msg})"
167
- else
168
- puts "Notifying PagerDuty (message: #{msg})"
169
- pd = pagerduty.trigger(
170
- msg,
171
- client: ENV['hostname'],
172
- details: details
173
- )
174
-
175
- # You may have noticed that this will overwrite any previously active
176
- # alerts, regardless of whether they are the "same" alert. This is a known
177
- # limitation.
178
-
179
- File.write(
180
- '/var/run/active_upstream_alert',
181
- {
182
- 'Incident Key' => pd.incident_key,
183
- 'Message' => msg,
184
- 'Details' => details
185
- }.to_json
186
- )
187
- end
188
- end
189
-
190
- def active_alert?(msg)
191
- pd_incidents.find do |incident|
192
- incident['status'] != 'resolved' &&
193
- incident['trigger_summary_data']['description'] == msg
194
- end
195
- end
196
-
197
166
  def opts
198
167
  @opts ||= Trollop.options do
199
168
  opt :notify,
@@ -223,4 +192,45 @@ class Upstreamstatus
223
192
  def defaults
224
193
  { 'status_check_url' => 'http://localhost:8069/status?format=json' }
225
194
  end
195
+
196
+ def fake_response
197
+ {
198
+ 'servers' => {
199
+ 'total' => 2,
200
+ 'generation' => 99,
201
+ 'server' => [
202
+ {
203
+ 'index' => 0,
204
+ 'upstream' => 'testupstream0',
205
+ 'name' => '10.0.0.1 =>8080',
206
+ 'status' => 'up',
207
+ 'rise' => 10_459,
208
+ 'fall' => 0,
209
+ 'type' => 'http',
210
+ 'port' => 0
211
+ },
212
+ {
213
+ 'index' => 1,
214
+ 'upstream' => 'testupstream1',
215
+ 'name' => '10.0.0.2 =>8080',
216
+ 'status' => 'down',
217
+ 'rise' => 10_029,
218
+ 'fall' => 0,
219
+ 'type' => 'http',
220
+ 'port' => 0
221
+ },
222
+ {
223
+ 'index' => 2,
224
+ 'upstream' => 'testupstream2',
225
+ 'name' => '10.0.0.2 =>8080',
226
+ 'status' => 'down',
227
+ 'rise' => 10_029,
228
+ 'fall' => 0,
229
+ 'type' => 'http',
230
+ 'port' => 0
231
+ }
232
+ ]
233
+ }
234
+ }
235
+ end
226
236
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upstreamstatus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.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: 2016-07-12 00:00:00.000000000 Z
11
+ date: 2016-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: unirest
@@ -179,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
179
  version: '0'
180
180
  requirements: []
181
181
  rubyforge_project:
182
- rubygems_version: 2.4.5
182
+ rubygems_version: 2.5.1
183
183
  signing_key:
184
184
  specification_version: 4
185
185
  summary: Parse the output of the Nginx Upstream Check plugin