tocsin 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/tocsin/config.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  module Tocsin
2
2
  class Config
3
- attr_accessor :logger, :queue, :recipient_groups, :from_address
3
+ attr_accessor :exception_level, :from_address, :logger, :queue, :recipient_groups
4
+
5
+ def initialize
6
+ @exception_level = StandardError
7
+ @logger = select_logger
8
+ @queue = :high
9
+ end
10
+
11
+ def select_logger
12
+ rails = defined?(Rails) && Rails.respond_to?(:logger)
13
+ rails ? Rails.logger : Logger.new($stderr)
14
+ end
4
15
 
5
16
  # notify [r1, r2], :of => filters, :by => notifier
6
17
  def notify(recipients, parameters)
@@ -14,19 +25,5 @@ module Tocsin
14
25
  :notifier => notifier}.merge(filters)
15
26
  self.recipient_groups.push(group_config)
16
27
  end
17
-
18
- def queue
19
- @queue ||= :high
20
- end
21
-
22
- def logger
23
- @logger ||= Rails.logger
24
- rescue NameError, NoMethodError => e
25
- ok = [ /^uninitialized constant .*Rails$/,
26
- /^undefined method `logger'/
27
- ].any?{|regex| e.message =~ regex }
28
- raise unless ok
29
- @logger ||= Logger.new($stderr)
30
- end
31
28
  end
32
29
  end
@@ -1,3 +1,3 @@
1
1
  module Tocsin
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/tocsin.rb CHANGED
@@ -42,7 +42,7 @@ module Tocsin
42
42
  def self.watch(options={})
43
43
  begin
44
44
  yield
45
- rescue => e
45
+ rescue exception_level => e
46
46
  raise_alert(e, options)
47
47
  end
48
48
  end
@@ -51,7 +51,7 @@ module Tocsin
51
51
  def self.watch!(options={})
52
52
  begin
53
53
  yield
54
- rescue => e
54
+ rescue exception_level => e
55
55
  raise_alert(e, options)
56
56
  raise e
57
57
  end
@@ -112,6 +112,10 @@ module Tocsin
112
112
 
113
113
  private
114
114
 
115
+ def self.exception_level
116
+ config.exception_level
117
+ end
118
+
115
119
  def self.sound(alert)
116
120
  alert = Tocsin::Alert.find(alert) unless alert.is_a?(Tocsin::Alert)
117
121
  recipients = Tocsin.recipients(alert)
@@ -120,12 +124,16 @@ module Tocsin
120
124
  notifier = Tocsin::Notifiers[notifier_key]
121
125
 
122
126
  if notifier && recipient_list.any?
123
- notifier.notify(recipient_list, alert)
124
- Tocsin.logger.info { "Notification sent to #{recipient_list.inspect} via #{notifier_key} for alert #{alert.id}." }
127
+ logger.info { "Sending notification to #{recipient_list.inspect} via #{notifier_key} for alert #{alert.id}." }
128
+ begin
129
+ notifier.notify(recipient_list, alert)
130
+ rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ENETUNREACH, Errno::ETIMEDOUT => e
131
+ logger.error { "Notification failed. #{e.to_s}:\n#{e.backtrace.join('\n')}" }
132
+ end
125
133
  elsif recipient_list.empty?
126
- Tocsin.logger.error { "No recipients associated with alert: \n #{alert.inspect}" }
134
+ logger.error { "No recipients associated with alert: \n #{alert.inspect}" }
127
135
  elsif notifier.nil?
128
- Tocsin.logger.error { "Raised alert with ID=#{alert.id} for unregistered notifier '#{notifier_key}'." }
136
+ logger.error { "Raised alert with ID=#{alert.id} for unregistered notifier '#{notifier_key}'." }
129
137
  end
130
138
  end
131
139
  end
data/spec/spec_helper.rb CHANGED
@@ -9,26 +9,23 @@ Mail.defaults do
9
9
  end
10
10
 
11
11
  class Tocsin::Alert
12
- def id
13
- 1
14
- end
15
-
16
- def category
17
- end
18
-
19
- def severity
12
+ attr_accessor :id, :exception, :backtrace, :category, :severity, :message
13
+
14
+ def initialize(args = {})
15
+ @id = 1
16
+ @backtrace = args[:backtrace]
17
+ @exception = args[:exception]
18
+ @category = args[:category]
19
+ @severity = args[:severity]
20
+ @message = args[:message]
20
21
  end
21
22
 
22
23
  def self.create(*args)
23
- self.new
24
+ self.new(*args)
24
25
  end
25
26
 
26
27
  def self.find(*args)
27
- self.new
28
- end
29
-
30
- def self.logger
31
- @logger ||= Logger.new($stdout)
28
+ self.new(*args)
32
29
  end
33
30
  end
34
31
 
data/spec/tocsin_spec.rb CHANGED
@@ -22,13 +22,13 @@ describe Tocsin do
22
22
  end
23
23
 
24
24
  context "when an exception has already been rescued" do
25
- it "raises an alert" do
26
- Tocsin::Alert.expects(:create).returns(stub("alert", :id => 1))
25
+ it "raises (and returns) an alert" do
26
+ Tocsin::Alert.expects(:create).returns(Tocsin::Alert.new)
27
27
 
28
28
  begin
29
29
  raise "Testing"
30
30
  rescue => e
31
- Tocsin.raise_alert(e, alert_options)
31
+ Tocsin.raise_alert(e, alert_options).should be_a_kind_of(Tocsin::Alert)
32
32
  end
33
33
  end
34
34
  end
@@ -44,6 +44,25 @@ describe Tocsin do
44
44
  }.should_not raise_error
45
45
  end
46
46
 
47
+ it "normally does not rescue low-level Exceptions" do
48
+ expect { Tocsin.watch(alert_options) do raise Exception.new end }.to raise_error
49
+ end
50
+
51
+ context "when configured to catch all Exceptions" do
52
+ before {
53
+ Tocsin.config.exception_level = Exception
54
+ }
55
+
56
+ it "can rescue low-level Exceptions too" do
57
+ expect { Tocsin.watch(alert_options) do raise Exception.new end }.to_not raise_error
58
+ end
59
+
60
+ it "still creates an alert when watch!-ing a block which raises an Exception" do
61
+ Tocsin.expects(:raise_alert).once
62
+ expect { Tocsin.watch!(alert_options) do raise Exception.new end }.to raise_error
63
+ end
64
+ end
65
+
47
66
  it "provides a watch! method which both send an alert and re-raises the exception" do
48
67
  Tocsin.expects(:raise_alert).with(is_a(Exception), has_entries(alert_options))
49
68
 
@@ -163,15 +182,18 @@ describe Tocsin do
163
182
  Tocsin.raise_alert(exception, alert_options)
164
183
  end
165
184
 
185
+ let(:attributes) do
186
+ { :exception => exception.to_s,
187
+ :backtrace => exception.backtrace.join("\n"),
188
+ :severity => alert_options[:severity].to_s,
189
+ :message => alert_options[:message].to_s,
190
+ :category => alert_options[:category].to_s
191
+ }
192
+ end
193
+
166
194
  describe "the created Tocsin::Alert object" do
167
195
  it "is created with appropriate fields" do
168
- Tocsin::Alert.expects(:create).with(has_entries(
169
- :exception => exception.to_s,
170
- :backtrace => exception.backtrace.join("\n"),
171
- :severity => alert_options[:severity].to_s,
172
- :message => alert_options[:message].to_s,
173
- :category => alert_options[:category].to_s
174
- )).returns(stub("alert", :id => 1))
196
+ Tocsin::Alert.expects(:create).with(has_entries(attributes)).returns(Tocsin::Alert.new)
175
197
  alert
176
198
  end
177
199
  end
@@ -198,6 +220,30 @@ describe Tocsin do
198
220
  expect { alert }.to_not raise_error
199
221
  end
200
222
 
223
+ context "common communication errors" do
224
+ before do
225
+ Tocsin.configure do |c|
226
+ c.notify ["a@b.com"], :of => { :severity => /.*/ }
227
+ c.logger = Logger.new('/dev/null')
228
+ end
229
+ end
230
+
231
+ errors = [ Timeout::Error,
232
+ Errno::EHOSTUNREACH,
233
+ Errno::ECONNREFUSED,
234
+ Errno::ENETUNREACH,
235
+ Errno::ETIMEDOUT ]
236
+
237
+ errors.each do |err|
238
+ it "logs #{err.to_s} without exploding" do
239
+ alert_options.merge!(now: true)
240
+ Mail.expects(:deliver).raises(err)
241
+ Tocsin.logger.expects(:error)
242
+ expect { alert }.to_not raise_error
243
+ end
244
+ end
245
+ end
246
+
201
247
  end
202
248
 
203
249
  describe Tocsin::NotificationJob do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tocsin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-04-09 00:00:00.000000000 Z
13
+ date: 2013-04-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec