god 0.13.3 → 0.13.4

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.
data/Gemfile CHANGED
@@ -1,2 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
+
4
+ gem 'redcarpet', '< 3.0.0'
5
+ gem 'sanitize', '2.0.3'
@@ -1,3 +1,11 @@
1
+ == 0.13.4 / 2014-03-05
2
+ * Minor Enhancements
3
+ * Hipchat reporter (#162)
4
+ * Re-open log files on SIGUSR1 (#103)
5
+ * Bug fixes
6
+ * Send query params on webhook reporter (#160)
7
+ * Don't thow an exception when there are problems reading pid file (#164)
8
+
1
9
  == 0.13.3 / 2013-09-25
2
10
  * Minor Enhancements
3
11
  * Invoke commands for all watchers
@@ -999,6 +999,29 @@ ssl - A Boolean determining whether or not to use SSL
999
999
  (default: false).
1000
1000
  ```
1001
1001
 
1002
+ Hipchat
1003
+ ~~~~~~~~
1004
+
1005
+ Send a notice to a Hipchat room (http://hipchat.com).
1006
+
1007
+ ```ruby
1008
+ God::Contacts::Hipchat.defaults do |d|
1009
+ ...
1010
+ end
1011
+
1012
+ God.contact(:hipchat) do |c|
1013
+ ...
1014
+ end
1015
+ ```
1016
+
1017
+ ```
1018
+ token - The String token used for authentication.
1019
+ room - The String room name to which the message should be sent.
1020
+ ssl - A Boolean determining whether or not to use SSL
1021
+ (default: false).
1022
+ from - The String representing who the message should be sent as.
1023
+ ```
1024
+
1002
1025
  Email
1003
1026
  ~~~~~
1004
1027
 
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'god'
6
- s.version = '0.13.3'
7
- s.date = '2013-09-25'
6
+ s.version = '0.13.4'
7
+ s.date = '2014-03-05'
8
8
 
9
9
  s.summary = "Process monitoring framework."
10
10
  s.description = "An easy to configure, easy to extend monitoring framework written in Ruby."
@@ -83,6 +83,7 @@ Gem::Specification.new do |s|
83
83
  lib/god/contacts/airbrake.rb
84
84
  lib/god/contacts/campfire.rb
85
85
  lib/god/contacts/email.rb
86
+ lib/god/contacts/hipchat.rb
86
87
  lib/god/contacts/jabber.rb
87
88
  lib/god/contacts/prowl.rb
88
89
  lib/god/contacts/scout.rb
@@ -154,6 +155,7 @@ Gem::Specification.new do |s|
154
155
  test/test_event_handler.rb
155
156
  test/test_god.rb
156
157
  test/test_handlers_kqueue_handler.rb
158
+ test/test_hipchat.rb
157
159
  test/test_jabber.rb
158
160
  test/test_logger.rb
159
161
  test/test_metric.rb
data/lib/god.rb CHANGED
@@ -85,6 +85,7 @@ end
85
85
 
86
86
  require 'god/contact'
87
87
  load_contact(:campfire)
88
+ load_contact(:hipchat)
88
89
  load_contact(:email)
89
90
  load_contact(:jabber)
90
91
  load_contact(:prowl)
@@ -157,7 +158,7 @@ end
157
158
 
158
159
  module God
159
160
  # The String version number for this package.
160
- VERSION = '0.13.3'
161
+ VERSION = '0.13.4'
161
162
 
162
163
  # The Integer number of lines of backlog to keep for the logger.
163
164
  LOG_BUFFER_SIZE_DEFAULT = 100
@@ -83,6 +83,8 @@ module God
83
83
  def run_daemonized
84
84
  # trap and ignore SIGHUP
85
85
  Signal.trap('HUP') {}
86
+ # trap and log-reopen SIGUSR1
87
+ Signal.trap('USR1') { setup_logging }
86
88
 
87
89
  pid = fork do
88
90
  begin
@@ -0,0 +1,117 @@
1
+ # Send a notice to a Hipchat room (http://hipchat.com).
2
+ #
3
+ # token - The String token used for authentication.
4
+ # room - The String room name to which the message should be sent.
5
+ # ssl - A Boolean determining whether or not to use SSL
6
+ # (default: false).
7
+ # from - The String representing who the message should be sent as.
8
+
9
+ require 'net/http'
10
+ require 'net/https'
11
+
12
+ CONTACT_DEPS[:hipchat] = ['json']
13
+ CONTACT_DEPS[:hipchat].each do |d|
14
+ require d
15
+ end
16
+
17
+ module Marshmallow
18
+ class Connection
19
+ def initialize(options)
20
+ raise "Required option :token not set." unless options[:token]
21
+ @options = options
22
+ end
23
+
24
+ def base_url
25
+ scheme = @options[:ssl] ? 'https' : 'http'
26
+ "#{scheme}://api.hipchat.com/v1/rooms"
27
+ end
28
+
29
+ def find_room_id_by_name(room_name)
30
+ url = URI.parse("#{base_url}/list?format=json&auth_token=#{@options[:token]}")
31
+ http = Net::HTTP.new(url.host, url.port)
32
+ http.use_ssl = true if @options[:ssl]
33
+
34
+ req = Net::HTTP::Get.new(url.request_uri)
35
+ req.set_content_type('application/json')
36
+
37
+ res = http.request(req)
38
+ case res
39
+ when Net::HTTPSuccess
40
+ rooms = JSON.parse(res.body)
41
+ room = rooms['rooms'].select { |x| x['name'] == room_name }
42
+ rooms.empty? ? nil : room.first['room_id'].to_i
43
+ else
44
+ raise res.error!
45
+ end
46
+ end
47
+
48
+ def speak(room, message)
49
+ room_id = find_room_id_by_name(room)
50
+ puts "in spark: room_id = #{room_id}"
51
+ raise "No such room: #{room}." unless room_id
52
+
53
+ escaped_message = URI.escape(message)
54
+
55
+ url = URI.parse("#{base_url}/message?message_format=text&format=json&auth_token=#{@options[:token]}&from=#{@options[:from]}&room_id=#{room}&message=#{escaped_message}")
56
+
57
+ http = Net::HTTP.new(url.host, url.port)
58
+ http.use_ssl = true if @options[:ssl]
59
+
60
+ req = Net::HTTP::Post.new(url.request_uri)
61
+ req.set_content_type('application/json')
62
+ res = http.request(req)
63
+ case res
64
+ when Net::HTTPSuccess
65
+ true
66
+ else
67
+ raise res.error!
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ module God
74
+ module Contacts
75
+
76
+ class Hipchat < Contact
77
+ class << self
78
+ attr_accessor :token, :room, :ssl, :from
79
+ attr_accessor :format
80
+ end
81
+
82
+ self.ssl = false
83
+
84
+ self.format = lambda do |message, time, priority, category, host|
85
+ "[#{time.strftime('%H:%M:%S')}] #{host} - #{message}"
86
+ end
87
+
88
+ attr_accessor :token, :room, :ssl, :from
89
+
90
+ def valid?
91
+ valid = true
92
+ valid &= complain("Attribute 'token' must be specified", self) unless arg(:token)
93
+ valid &= complain("Attribute 'room' must be specified", self) unless arg(:room)
94
+ valid &= complain("Attribute 'from' must be specified", self) unless arg(:from)
95
+ valid
96
+ end
97
+
98
+ def notify(message, time, priority, category, host)
99
+ body = Hipchat.format.call(message, time, priority, category, host)
100
+
101
+ conn = Marshmallow::Connection.new(
102
+ :token => arg(:token),
103
+ :ssl => arg(:ssl),
104
+ :from => arg(:from)
105
+ )
106
+
107
+ conn.speak(arg(:room), body)
108
+
109
+ self.info = "notified hipchat: #{arg(:room)}"
110
+ rescue Object => e
111
+ applog(nil, :info, "failed to notify hipchat: #{e.message}")
112
+ applog(nil, :debug, e.backtrace.join("\n"))
113
+ end
114
+ end
115
+
116
+ end
117
+ end
@@ -47,10 +47,10 @@ module God
47
47
 
48
48
  case arg(:format)
49
49
  when :form
50
- req = Net::HTTP::Post.new(uri.path)
50
+ req = Net::HTTP::Post.new(uri.request_uri)
51
51
  req.set_form_data(data)
52
52
  when :json
53
- req = Net::HTTP::Post.new(uri.path)
53
+ req = Net::HTTP::Post.new(uri.request_uri)
54
54
  req.body = data.to_json
55
55
  end
56
56
 
@@ -63,7 +63,7 @@ module God
63
63
  self.info = "failed to send webhook to #{arg(:url)}: #{res.error!}"
64
64
  end
65
65
  rescue Object => e
66
- applog(nil, :info, "failed to send email to #{arg(:url)}: #{e.message}")
66
+ applog(nil, :info, "failed to send webhook to #{arg(:url)}: #{e.message}")
67
67
  applog(nil, :debug, e.backtrace.join("\n"))
68
68
  end
69
69
 
@@ -210,13 +210,19 @@ module God
210
210
  applog(self, :info, "#{self.name} sent SIG#{@stop_signal}")
211
211
 
212
212
  # Poll to see if it's dead
213
+ pid_not_found = false
213
214
  @stop_timeout.times do
214
- begin
215
- ::Process.kill(0, pid)
216
- rescue Errno::ESRCH
217
- # It died. Good.
218
- applog(self, :info, "#{self.name} process stopped")
219
- return
215
+ if pid
216
+ begin
217
+ ::Process.kill(0, pid)
218
+ rescue Errno::ESRCH
219
+ # It died. Good.
220
+ applog(self, :info, "#{self.name} process stopped")
221
+ return
222
+ end
223
+ else
224
+ applog(self, :warn, "#{self.name} pid not found in #{self.pid_file}") unless pid_not_found
225
+ pid_not_found = true
220
226
  end
221
227
 
222
228
  sleep 1
@@ -9,6 +9,16 @@
9
9
  # c.name = 'tom4'
10
10
  # end
11
11
 
12
+ # God::Contacts::Hipchat.defaults do |d|
13
+ # d.token = '9fb768e421975cc1c6ff3f4f8306f890cb46e24f'
14
+ # d.room = 'Notices'
15
+ # d.ssl = true
16
+ # end
17
+ #
18
+ # God.contact(:hipchat) do |c|
19
+ # c.name = 'hip1'
20
+ # end
21
+
12
22
  # God.contact(:email) do |c|
13
23
  # c.name = 'tom'
14
24
  # c.group = 'developers'
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestHipchat < Test::Unit::TestCase
4
+ def setup
5
+ @hipchat = God::Contacts::Hipchat.new
6
+ end
7
+
8
+ def test_exists
9
+ God::Contacts::Hipchat
10
+ end
11
+
12
+ def test_notify
13
+ @hipchat.token = 'ee64d6e2337310af'
14
+ @hipchat.ssl = 'true'
15
+ @hipchat.room = 'testroom'
16
+ @hipchat.from = 'test'
17
+
18
+ time = Time.now
19
+ body = "[#{time.strftime('%H:%M:%S')}] host - msg"
20
+ Marshmallow::Connection.any_instance.expects(:speak).with('testroom', body)
21
+ @hipchat.notify('msg', time, 'prio', 'cat', 'host')
22
+ end
23
+ end
@@ -12,4 +12,11 @@ class TestWebhook < Test::Unit::TestCase
12
12
  @webhook.notify('msg', Time.now, 'prio', 'cat', 'host')
13
13
  assert_equal "sent webhook to http://example.com/switch", @webhook.info
14
14
  end
15
+
16
+ def test_notify_with_url_containing_query_parameters
17
+ @webhook.url = 'http://example.com/switch?api_key=123'
18
+ Net::HTTP::Post.expects(:new).with('/switch?api_key=123')
19
+
20
+ @webhook.notify('msg', Time.now, 'prio', 'cat', 'host')
21
+ end
15
22
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: god
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 35
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 13
8
- - 3
9
- version: 0.13.3
9
+ - 4
10
+ version: 0.13.4
10
11
  platform: ruby
11
12
  authors:
12
13
  - Tom Preston-Werner
@@ -16,187 +17,214 @@ autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2013-09-25 00:00:00 -07:00
20
+ date: 2014-03-05 00:00:00 -08:00
20
21
  default_executable:
21
22
  dependencies:
22
23
  - !ruby/object:Gem::Dependency
23
- type: :development
24
24
  version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
25
26
  requirements:
26
27
  - - ~>
27
28
  - !ruby/object:Gem::Version
29
+ hash: 3
28
30
  segments:
29
31
  - 1
30
32
  - 6
31
33
  version: "1.6"
32
- name: json
33
- requirement: *id001
34
34
  prerelease: false
35
- - !ruby/object:Gem::Dependency
35
+ requirement: *id001
36
+ name: json
36
37
  type: :development
38
+ - !ruby/object:Gem::Dependency
37
39
  version_requirements: &id002 !ruby/object:Gem::Requirement
40
+ none: false
38
41
  requirements:
39
42
  - - ">="
40
43
  - !ruby/object:Gem::Version
44
+ hash: 3
41
45
  segments:
42
46
  - 0
43
47
  version: "0"
44
- name: rake
45
- requirement: *id002
46
48
  prerelease: false
47
- - !ruby/object:Gem::Dependency
49
+ requirement: *id002
50
+ name: rake
48
51
  type: :development
52
+ - !ruby/object:Gem::Dependency
49
53
  version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ none: false
50
55
  requirements:
51
56
  - - ~>
52
57
  - !ruby/object:Gem::Version
58
+ hash: 19
53
59
  segments:
54
60
  - 3
55
61
  - 10
56
62
  version: "3.10"
57
- name: rdoc
58
- requirement: *id003
59
63
  prerelease: false
60
- - !ruby/object:Gem::Dependency
64
+ requirement: *id003
65
+ name: rdoc
61
66
  type: :development
67
+ - !ruby/object:Gem::Dependency
62
68
  version_requirements: &id004 !ruby/object:Gem::Requirement
69
+ none: false
63
70
  requirements:
64
71
  - - ~>
65
72
  - !ruby/object:Gem::Version
73
+ hash: 27
66
74
  segments:
67
75
  - 4
68
76
  - 0
69
77
  version: "4.0"
70
- name: twitter
71
- requirement: *id004
72
78
  prerelease: false
73
- - !ruby/object:Gem::Dependency
79
+ requirement: *id004
80
+ name: twitter
74
81
  type: :development
82
+ - !ruby/object:Gem::Dependency
75
83
  version_requirements: &id005 !ruby/object:Gem::Requirement
84
+ none: false
76
85
  requirements:
77
86
  - - ~>
78
87
  - !ruby/object:Gem::Version
88
+ hash: 13
79
89
  segments:
80
90
  - 0
81
91
  - 3
82
92
  version: "0.3"
83
- name: prowly
84
- requirement: *id005
85
93
  prerelease: false
86
- - !ruby/object:Gem::Dependency
94
+ requirement: *id005
95
+ name: prowly
87
96
  type: :development
97
+ - !ruby/object:Gem::Dependency
88
98
  version_requirements: &id006 !ruby/object:Gem::Requirement
99
+ none: false
89
100
  requirements:
90
101
  - - ~>
91
102
  - !ruby/object:Gem::Version
103
+ hash: 1
92
104
  segments:
93
105
  - 0
94
106
  - 5
95
107
  version: "0.5"
96
- name: xmpp4r
97
- requirement: *id006
98
108
  prerelease: false
99
- - !ruby/object:Gem::Dependency
109
+ requirement: *id006
110
+ name: xmpp4r
100
111
  type: :development
112
+ - !ruby/object:Gem::Dependency
101
113
  version_requirements: &id007 !ruby/object:Gem::Requirement
114
+ none: false
102
115
  requirements:
103
116
  - - ~>
104
117
  - !ruby/object:Gem::Version
118
+ hash: 25
105
119
  segments:
106
120
  - 0
107
121
  - 0
108
122
  - 3
109
123
  version: 0.0.3
110
- name: dike
111
- requirement: *id007
112
124
  prerelease: false
113
- - !ruby/object:Gem::Dependency
125
+ requirement: *id007
126
+ name: dike
114
127
  type: :development
128
+ - !ruby/object:Gem::Dependency
115
129
  version_requirements: &id008 !ruby/object:Gem::Requirement
130
+ none: false
116
131
  requirements:
117
132
  - - ~>
118
133
  - !ruby/object:Gem::Version
134
+ hash: 25
119
135
  segments:
120
136
  - 0
121
137
  - 9
122
138
  version: "0.9"
123
- name: rcov
124
- requirement: *id008
125
139
  prerelease: false
126
- - !ruby/object:Gem::Dependency
140
+ requirement: *id008
141
+ name: rcov
127
142
  type: :development
143
+ - !ruby/object:Gem::Dependency
128
144
  version_requirements: &id009 !ruby/object:Gem::Requirement
145
+ none: false
129
146
  requirements:
130
147
  - - ~>
131
148
  - !ruby/object:Gem::Version
149
+ hash: 13
132
150
  segments:
133
151
  - 1
134
152
  - 1
135
153
  version: "1.1"
136
- name: daemons
137
- requirement: *id009
138
154
  prerelease: false
139
- - !ruby/object:Gem::Dependency
155
+ requirement: *id009
156
+ name: daemons
140
157
  type: :development
158
+ - !ruby/object:Gem::Dependency
141
159
  version_requirements: &id010 !ruby/object:Gem::Requirement
160
+ none: false
142
161
  requirements:
143
162
  - - ~>
144
163
  - !ruby/object:Gem::Version
164
+ hash: 31
145
165
  segments:
146
166
  - 0
147
167
  - 10
148
168
  version: "0.10"
149
- name: mocha
150
- requirement: *id010
151
169
  prerelease: false
152
- - !ruby/object:Gem::Dependency
170
+ requirement: *id010
171
+ name: mocha
153
172
  type: :development
173
+ - !ruby/object:Gem::Dependency
154
174
  version_requirements: &id011 !ruby/object:Gem::Requirement
175
+ none: false
155
176
  requirements:
156
177
  - - ~>
157
178
  - !ruby/object:Gem::Version
179
+ hash: 25
158
180
  segments:
159
181
  - 1
160
182
  - 3
161
183
  - 1
162
184
  version: 1.3.1
163
- name: gollum
164
- requirement: *id011
165
185
  prerelease: false
166
- - !ruby/object:Gem::Dependency
186
+ requirement: *id011
187
+ name: gollum
167
188
  type: :development
189
+ - !ruby/object:Gem::Dependency
168
190
  version_requirements: &id012 !ruby/object:Gem::Requirement
191
+ none: false
169
192
  requirements:
170
193
  - - ~>
171
194
  - !ruby/object:Gem::Version
195
+ hash: 13
172
196
  segments:
173
197
  - 3
174
198
  - 1
175
199
  - 7
176
200
  version: 3.1.7
177
- name: airbrake
178
- requirement: *id012
179
201
  prerelease: false
180
- - !ruby/object:Gem::Dependency
202
+ requirement: *id012
203
+ name: airbrake
181
204
  type: :development
205
+ - !ruby/object:Gem::Dependency
182
206
  version_requirements: &id013 !ruby/object:Gem::Requirement
207
+ none: false
183
208
  requirements:
184
209
  - - ~>
185
210
  - !ruby/object:Gem::Version
211
+ hash: 3
186
212
  segments:
187
213
  - 1
188
214
  - 5
189
215
  - 0
190
216
  version: 1.5.0
191
- name: nokogiri
192
- requirement: *id013
193
217
  prerelease: false
194
- - !ruby/object:Gem::Dependency
218
+ requirement: *id013
219
+ name: nokogiri
195
220
  type: :development
221
+ - !ruby/object:Gem::Dependency
196
222
  version_requirements: &id014 !ruby/object:Gem::Requirement
223
+ none: false
197
224
  requirements:
198
225
  - - ">="
199
226
  - !ruby/object:Gem::Version
227
+ hash: 23
200
228
  segments:
201
229
  - 2
202
230
  - 3
@@ -204,14 +232,16 @@ dependencies:
204
232
  version: 2.3.10
205
233
  - - <
206
234
  - !ruby/object:Gem::Version
235
+ hash: 63
207
236
  segments:
208
237
  - 4
209
238
  - 0
210
239
  - 0
211
240
  version: 4.0.0
212
- name: activesupport
213
- requirement: *id014
214
241
  prerelease: false
242
+ requirement: *id014
243
+ name: activesupport
244
+ type: :development
215
245
  description: An easy to configure, easy to extend monitoring framework written in Ruby.
216
246
  email: god-rb@googlegroups.com
217
247
  executables:
@@ -265,6 +295,7 @@ files:
265
295
  - lib/god/contacts/airbrake.rb
266
296
  - lib/god/contacts/campfire.rb
267
297
  - lib/god/contacts/email.rb
298
+ - lib/god/contacts/hipchat.rb
268
299
  - lib/god/contacts/jabber.rb
269
300
  - lib/god/contacts/prowl.rb
270
301
  - lib/god/contacts/scout.rb
@@ -336,6 +367,7 @@ files:
336
367
  - test/test_event_handler.rb
337
368
  - test/test_god.rb
338
369
  - test/test_handlers_kqueue_handler.rb
370
+ - test/test_hipchat.rb
339
371
  - test/test_jabber.rb
340
372
  - test/test_logger.rb
341
373
  - test/test_metric.rb
@@ -362,23 +394,27 @@ require_paths:
362
394
  - lib
363
395
  - ext
364
396
  required_ruby_version: !ruby/object:Gem::Requirement
397
+ none: false
365
398
  requirements:
366
399
  - - ">="
367
400
  - !ruby/object:Gem::Version
401
+ hash: 3
368
402
  segments:
369
403
  - 0
370
404
  version: "0"
371
405
  required_rubygems_version: !ruby/object:Gem::Requirement
406
+ none: false
372
407
  requirements:
373
408
  - - ">="
374
409
  - !ruby/object:Gem::Version
410
+ hash: 3
375
411
  segments:
376
412
  - 0
377
413
  version: "0"
378
414
  requirements: []
379
415
 
380
416
  rubyforge_project: god
381
- rubygems_version: 1.3.6
417
+ rubygems_version: 1.6.2
382
418
  signing_key:
383
419
  specification_version: 2
384
420
  summary: Process monitoring framework.
@@ -398,6 +434,7 @@ test_files:
398
434
  - test/test_event_handler.rb
399
435
  - test/test_god.rb
400
436
  - test/test_handlers_kqueue_handler.rb
437
+ - test/test_hipchat.rb
401
438
  - test/test_jabber.rb
402
439
  - test/test_logger.rb
403
440
  - test/test_metric.rb