denouncer 0.3.0 → 0.4.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: 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