denouncer 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dd7818d5f9f193ace4fca1390ba000808403fefe
4
- data.tar.gz: 33a1d7791e3d04a59f62115e11eb1ff94e98f65b
3
+ metadata.gz: 435f952054638a12c1528c1a3efd126b3e37d932
4
+ data.tar.gz: 69e8ea1f3e5fde186106dee702b8d5d798f717d1
5
5
  SHA512:
6
- metadata.gz: f764ae4755bc8985a99cee4a19d2e0242c456b78be51b84d9ebbe74bab2b48e21eaf071dcb720a359bf295c728f556718062e6912f5cb02ac0c822100fddcab2
7
- data.tar.gz: c601d4730d465d00eb6b4b76fd6d2e8d07b133062a7a43d7e56ea674e6bc404534c4ef124a0d3b0d1cc9812847cc48522d4217b837c3915290dbda5ff228ea87
6
+ metadata.gz: 34984f10a1b5f47d759cc9e5d1d2d112319738967bf08a4b8fbd3bd19bad55c285ee48d31154a0e004beb1fa7f285f7a08a178bfc9ed7957dc61495a1dfdb5e4
7
+ data.tar.gz: 1115a5fa4739c36e6b6da776ef9b8d5042cde82a0613821f3906a6709bc7f3e4decf51ab98257969142eb346dddcb361d6315950b648fd3ba99adae72957b896
data/README.md CHANGED
@@ -121,6 +121,37 @@ Configuration variables are:
121
121
  message_queue: "my_app.errors"
122
122
  )
123
123
 
124
+ #### Multiple notifier configuration
125
+
126
+ Since version 0.4.0 denouncer supports parallel usage of multiple notifiers.
127
+ All exception notifications will be send to all configured notifiers.
128
+ The example below configures the amqp and smtp notifiers in parallel.
129
+
130
+ require 'denouncer'
131
+
132
+ Denouncer.configure(
133
+ {
134
+ application_name: "my_app",
135
+ notifiers: [:smtp, :amqp],
136
+ configurations: {
137
+ smtp: {
138
+ port: 1025,
139
+ server: "localhost",
140
+ sender: "noreply@example.com",
141
+ recipients: ['usera@example.com', 'userb@example.com']
142
+ },
143
+ amqp: {
144
+ port: 5672,
145
+ server: "localhost",
146
+ vhost: "/",
147
+ username: "guest",
148
+ password: "guest",
149
+ message_queue: "my_app.errors"
150
+ }
151
+ }
152
+ }
153
+ )
154
+
124
155
  ## Usage
125
156
 
126
157
  The example below shows a basic usage pattern for denouncer notifications.
@@ -5,34 +5,49 @@ module Denouncer
5
5
 
6
6
  DEFAULT_NOTIFIER = :smtp
7
7
 
8
- @@notifier = nil
8
+ @@notifiers = nil
9
9
 
10
10
  # Configures denouncer using the specified configuration hash.
11
11
  #
12
12
  # @param options [Hash] a configuration hash
13
13
  def self.configure(options)
14
14
  check_base_configuration! options
15
- if options[:notifier].nil?
15
+ if options[:notifier].nil? && options[:notifiers].nil?
16
16
  options[:notifier] = DEFAULT_NOTIFIER
17
- else
18
- options[:notifier] = options[:notifier].to_sym
19
17
  end
20
- initialize_notifier options
18
+
19
+ unless options[:notifiers].nil?
20
+ options[:notifiers] = options[:notifiers].map { |n| n.to_sym }
21
+ end
22
+
23
+ initialize_notifiers options
21
24
  options
22
25
  end
23
26
 
24
27
  def self.reset_configuration
25
- @@notifier = nil
28
+ @@notifiers = nil
26
29
  end
27
30
 
28
31
  def self.is_configured?
29
- !notifier.nil?
32
+ !notifiers.nil?
30
33
  end
31
34
 
32
35
  # Returns the current notifier's config or nil if not configured.
33
36
  def self.config
34
37
  return nil unless is_configured?
35
- notifier.config
38
+ if notifiers.count == 1
39
+ notifiers.first.config
40
+ else
41
+ conf = {}
42
+ conf[:application_name] = notifiers.first.config[:application_name]
43
+ conf[:notifiers] = Array.new
44
+ conf[:configurations] = {}
45
+ notifiers.each do |notif|
46
+ conf[:notifiers] << notif.name.to_sym
47
+ conf[:configurations][notif.name.to_sym] = notif.config
48
+ end
49
+ conf
50
+ end
36
51
  end
37
52
 
38
53
  # Sends a notification using the configured notifier.
@@ -44,41 +59,97 @@ module Denouncer
44
59
  # ATTENTION: this ensures that no exceptions are lost when denouncer is not working as expected!!!
45
60
  # This is worth the downside of denouncer debugging thougths.
46
61
  begin
47
- notifier.notify error, metadata
62
+ notifiers.each do |notif|
63
+ notif.notify error, metadata
64
+ end
48
65
  return true
49
66
  rescue => err
50
- puts "An error occured while sending an exception notification via denouncer!"
51
- raise error
67
+ puts "An error occured while sending an exception notification via denouncer! Error: #{err.message}, Backtrace: #{err.backtrace}"
52
68
  end
53
69
  else
54
70
  return false
55
71
  end
56
72
  end
57
73
 
74
+ # Sends a notification and raises the given error on return
75
+ #
76
+ # @param error [StandardError]
77
+ # @param metadata [Hash]
78
+ # @raise [StandardError] the given error
58
79
  def self.notify!(error, metadata = nil)
59
80
  if is_configured?
60
- notifier.notify! error, metadata
81
+ notifiers.each do |notif|
82
+ notif.notify error, metadata
83
+ end
61
84
  end
85
+ rescue => err
86
+ puts "An error occured while sending an exception notification via denouncer! Error: #{err.message}, Backtrace: #{err.backtrace}"
87
+ ensure
88
+ raise error
62
89
  end
63
90
 
64
91
  private
65
92
 
66
- def self.notifier
67
- return @@notifier
93
+ def self.notifiers
94
+ return @@notifiers
68
95
  end
69
96
 
70
97
  def self.check_base_configuration!(options)
71
98
  raise "Invalid configuration hash: nil" if options.nil?
72
- raise "Invalid configuration hash: no hash or subclass of hash given" unless options.is_a? Hash
99
+ raise "Invalid configuration hash: No hash or subclass of hash given" unless options.is_a? Hash
100
+ raise "Invalid configuration hash: No :application_name setting given" if options[:application_name].nil?
101
+
102
+ if !options[:notifier].nil? && !options[:notifiers].nil?
103
+ raise "Invalid configuration hash: Can't use :notifiers and :notifier setting in conjunction"
104
+ end
73
105
  end
74
106
 
75
- def self.initialize_notifier(options)
76
- case options[:notifier]
77
- when :smtp then @@notifier = ::Denouncer::Notifiers::SmtpNotifier.new options
78
- when :console then @@notifier = ::Denouncer::Notifiers::ConsoleNotifier.new options
79
- when :amqp then @@notifier = ::Denouncer::Notifiers::AmqpNotifier.new options
107
+ def self.initialize_notifiers(options)
108
+ @@notifiers = Array.new
109
+ unless options[:notifiers].nil?
110
+ intialize_multiple_notifiers options
111
+ else
112
+ initialize_single_notifier options[:notifier], options
113
+ end
114
+ rescue => err
115
+ @@notifiers = nil
116
+ raise err
117
+ end
118
+
119
+ def self.intialize_multiple_notifiers(options)
120
+ raise "No :configurations hash given" if options[:configurations].nil?
121
+ options[:notifiers].each do |notif_symbol|
122
+ notif_symbol = notif_symbol.to_sym
123
+ notifier_class = get_notifier_class notif_symbol
124
+
125
+ notifier_opts = {
126
+ application_name: options[:application_name],
127
+ }
128
+
129
+ notifier_opts.merge!(options[:configurations][notif_symbol])
130
+ @@notifiers << notifier_class.new(notifier_opts)
131
+ end
132
+ end
133
+
134
+ def self.initialize_single_notifier(notifier_symbol, options)
135
+ notifier_class = get_notifier_class notifier_symbol
136
+ @@notifiers << notifier_class.new(options)
137
+ end
138
+
139
+ def self.get_notifier_class(notifier_symbol)
140
+ notifier_class = nil
141
+
142
+ case notifier_symbol
143
+ when :smtp then
144
+ notifier_class = ::Denouncer::Notifiers::SmtpNotifier
145
+ when :console then
146
+ notifier_class = ::Denouncer::Notifiers::ConsoleNotifier
147
+ when :amqp then
148
+ notifier_class = ::Denouncer::Notifiers::AmqpNotifier
80
149
  else
81
150
  raise "Invalid notifier configuration: #{options} is not a valid :notifier setting!"
82
151
  end
152
+
153
+ return notifier_class
83
154
  end
84
155
  end
@@ -10,11 +10,15 @@ module Denouncer
10
10
  DEFAULT_USERNAME = 'guest'
11
11
  DEFAULT_PASSWORD = 'guest'
12
12
 
13
- # @raise [StandardError] if the configuration is invalid
13
+ # @return [String]
14
+ def name
15
+ 'amqp'
16
+ end
17
+
14
18
  def set_configuration!(options)
15
- require 'bunny'
16
19
  raise "Configuration error: :application_name is not set!" if options[:application_name].nil?
17
-
20
+ require 'bunny'
21
+
18
22
  options[:server] = DEFAULT_SERVER if options[:server].nil?
19
23
  options[:port] = DEFAULT_PORT if options[:port].nil?
20
24
  options[:vhost] = DEFAULT_VHOST if options[:vhost].nil?
@@ -27,6 +27,11 @@ module Denouncer
27
27
  end
28
28
  end
29
29
 
30
+ # @return [String] the name for the notifier
31
+ def name
32
+ raise NotImplementedException("This method needs to be implemented in a sub-class!")
33
+ end
34
+
30
35
  def set_configuration!(options)
31
36
  raise NotImplementedException("This method needs to be implemented in a sub-class!")
32
37
  end
@@ -38,17 +43,6 @@ module Denouncer
38
43
  def notify(error, metadata = nil)
39
44
  raise NotImplementedException("This method needs to be implemented in a sub-class!")
40
45
  end
41
-
42
- # Sends a notification
43
- # raises the given error after notifying using the configured adapter
44
- #
45
- # @param error [StandardError]
46
- # @param metadata [Hash]
47
- # @raise [StandardError]
48
- def notify!(error, metadata = nil)
49
- notify error, metadata
50
- raise error
51
- end
52
46
  end
53
47
  end
54
48
  end
@@ -1,6 +1,11 @@
1
1
  module Denouncer
2
2
  module Notifiers
3
3
  class ConsoleNotifier < BaseNotifier
4
+
5
+ # @return [String]
6
+ def name
7
+ 'console'
8
+ end
4
9
 
5
10
  def set_configuration!(options)
6
11
  return options
@@ -9,6 +9,11 @@ module Denouncer
9
9
  DEFAULT_SERVER = 'localhost'
10
10
  DEFAULT_DOMAIN = 'localhost'
11
11
 
12
+ # @return [String]
13
+ def name
14
+ 'smtp'
15
+ end
16
+
12
17
  # @raise [StandardError] if the configuration is invalid
13
18
  def set_configuration!(options)
14
19
  raise "Configuration error: :application_name is not set!" if options[:application_name].nil?
@@ -1,3 +1,3 @@
1
1
  module Denouncer
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,9 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Denouncer do
4
+ let(:app_name) { "MyApplication" }
4
5
  let(:notifier_configuration) do
5
- { application_name: "MyApplication", notifier: :console }
6
+ { application_name: app_name, notifier: :console }
6
7
  end
8
+
9
+ let(:multiple_notifier_configuration) do
10
+ {
11
+ application_name: app_name,
12
+ notifiers: [:console, :console],
13
+ configurations: {
14
+ console: {
15
+ }
16
+ }
17
+ }
18
+ end
19
+
7
20
  let(:error) do
8
21
  StandardError.new("Test")
9
22
  end
@@ -30,9 +43,10 @@ describe Denouncer do
30
43
  expect(Denouncer.config).to eq new_configuration
31
44
  end
32
45
 
33
- it "should initialize a notifier" do
46
+ it "should initialize notifiers" do
34
47
  Denouncer.configure new_configuration
35
- expect(Denouncer.send(:notifier)).not_to be_nil
48
+ expect(Denouncer.send(:notifiers)).not_to be_nil
49
+ expect(Denouncer.send(:notifiers)).to be_instance_of Array
36
50
  end
37
51
  end
38
52
 
@@ -42,9 +56,10 @@ describe Denouncer do
42
56
  expect(Denouncer.config).to eq new_configuration
43
57
  end
44
58
 
45
- it "should initialize a notifier" do
59
+ it "should initialize notifiers" do
46
60
  Denouncer.configure new_configuration
47
- expect(Denouncer.send(:notifier)).not_to be_nil
61
+ expect(Denouncer.send(:notifiers)).not_to be_nil
62
+ expect(Denouncer.send(:notifiers)).to be_instance_of Array
48
63
  end
49
64
  end
50
65
 
@@ -85,6 +100,51 @@ describe Denouncer do
85
100
  end
86
101
  end
87
102
  end
103
+
104
+ context 'multiple notifiers' do
105
+ context 'unconfigured' do
106
+ it 'should initialize the configuration' do
107
+ Denouncer.configure multiple_notifier_configuration
108
+ expect(Denouncer.config).not_to be_nil
109
+ end
110
+
111
+ it "should initialize notifiers" do
112
+ Denouncer.configure multiple_notifier_configuration
113
+ expect(Denouncer.send(:notifiers)).to be_instance_of Array
114
+ expect(Denouncer.send(:notifiers).count).to eq multiple_notifier_configuration[:notifiers].count
115
+ end
116
+ end
117
+
118
+ context 'invalid settings hash' do
119
+ context ':notifier and :notifiers setting provided' do
120
+ let(:invalid) do
121
+ {
122
+ application_name: "TestAppThing",
123
+ notifier: :amqp,
124
+ notifiers: [:amqp,:smtp]
125
+ }
126
+ end
127
+
128
+ it 'should raise an error' do
129
+ expect { Denouncer.configure invalid }.to raise_error
130
+ end
131
+ end
132
+
133
+ context 'without :configurations sub-hash' do
134
+ let(:invalid) do
135
+ {
136
+ application_name: "TestAppThing",
137
+ notifiers: [:amqp,:smtp]
138
+ }
139
+ end
140
+
141
+ it 'should raise an error' do
142
+ expect { Denouncer.configure invalid }.to raise_error
143
+ end
144
+ end
145
+
146
+ end
147
+ end
88
148
  end
89
149
 
90
150
  describe ".is_configured?" do
@@ -110,7 +170,7 @@ describe Denouncer do
110
170
  Denouncer.configure notifier_configuration
111
171
  end
112
172
 
113
- it "should set the notifier to nil" do
173
+ it "should set the configuration to nil" do
114
174
  Denouncer.reset_configuration
115
175
  expect(Denouncer.config).to be_nil
116
176
  expect(Denouncer.is_configured?).to be_falsey
@@ -119,13 +179,34 @@ describe Denouncer do
119
179
 
120
180
  describe ".config" do
121
181
  context "configured" do
122
- before do
123
- Denouncer.configure notifier_configuration
182
+ context "single notifier" do
183
+ before do
184
+ Denouncer.configure notifier_configuration
185
+ end
186
+
187
+ it "should return the notifier's configuration" do
188
+ notifier = Denouncer.send(:notifiers).first
189
+ expect(Denouncer.config).to eq notifier.config
190
+ end
124
191
  end
125
192
 
126
- it "should return the notifier's configuration" do
127
- notifier = Denouncer.send(:notifier)
128
- expect(Denouncer.config).to eq notifier.config
193
+ context 'multiple notifiers' do
194
+ before do
195
+ Denouncer.configure multiple_notifier_configuration
196
+ end
197
+
198
+ it "should return a hash of configurations" do
199
+ notifiers = Denouncer.send(:notifiers)
200
+ notifier_symbols = notifiers.map { |n| n.name.to_sym }
201
+ expected_config = {
202
+ application_name: app_name,
203
+ notifiers: notifier_symbols,
204
+ configurations: {
205
+ console: notifiers.first.config
206
+ }
207
+ }
208
+ expect(Denouncer.config).to eq expected_config
209
+ end
129
210
  end
130
211
  end
131
212
 
@@ -136,26 +217,78 @@ describe Denouncer do
136
217
  end
137
218
  end
138
219
 
139
- describe ".notify" do
140
- context "configured" do
220
+ describe ".notify!" do
221
+ context "single notifier" do
141
222
  before do
142
223
  Denouncer.configure notifier_configuration
143
224
  end
144
225
 
145
- it "should call it's notifiers notify method" do
146
- notifier = Denouncer.send(:notifier)
147
- expect(notifier).to receive(:notify).with(error, metadata)
148
- Denouncer.notify error, metadata
226
+ it "should call it's notifier's notify method and raise the given error" do
227
+ notifiers = Denouncer.send(:notifiers)
228
+ notifiers.each do |notif|
229
+ expect(notif).to receive(:notify).with(error, metadata)
230
+ end
231
+ expect { Denouncer.notify! error, metadata }.to raise_error error
232
+ end
233
+ end
234
+
235
+ context "multiple notifiers" do
236
+ before do
237
+ Denouncer.configure multiple_notifier_configuration
149
238
  end
150
239
 
151
- it "should return true" do
152
- expect(Denouncer.notify error).to be_truthy
240
+ it "should call it's notifier's notify method and raise the given error" do
241
+ notifiers = Denouncer.send(:notifiers)
242
+ notifiers.each do |notif|
243
+ expect(notif).to receive(:notify).with(error, metadata)
244
+ end
245
+ expect { Denouncer.notify! error, metadata }.to raise_error error
153
246
  end
154
247
  end
248
+ end
155
249
 
156
- context "unconfigured" do
157
- it "should return false" do
158
- expect(Denouncer.notify error).to be_falsey
250
+ describe ".notify" do
251
+ context "single notifier configured" do
252
+ context "configured" do
253
+ before do
254
+ Denouncer.configure notifier_configuration
255
+ end
256
+
257
+ it "should call it's notifier's notify method" do
258
+ notifiers = Denouncer.send(:notifiers)
259
+ notifiers.each do |notif|
260
+ expect(notif).to receive(:notify).with(error, metadata)
261
+ end
262
+ Denouncer.notify error, metadata
263
+ end
264
+
265
+ it "should return true" do
266
+ expect(Denouncer.notify error).to be_truthy
267
+ end
268
+ end
269
+
270
+ context "unconfigured" do
271
+ it "should return false" do
272
+ expect(Denouncer.notify error).to be_falsey
273
+ end
274
+ end
275
+ end
276
+
277
+ context "multiple notifiers configured" do
278
+ before do
279
+ Denouncer.configure multiple_notifier_configuration
280
+ end
281
+
282
+ it "should call all configured notifiers' notify method" do
283
+ notifiers = Denouncer.send(:notifiers)
284
+ notifiers.each do |notif|
285
+ expect(notif).to receive(:notify).with(error, metadata)
286
+ end
287
+ Denouncer.notify error, metadata
288
+ end
289
+
290
+ it "should return true" do
291
+ expect(Denouncer.notify error).to be_truthy
159
292
  end
160
293
  end
161
294
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: denouncer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Weber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-25 00:00:00.000000000 Z
11
+ date: 2015-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler