upstreamstatus 0.1.4 → 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: 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: