god 0.13.3 → 0.13.4

Sign up to get free protection for your applications and to get access to all the features.
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