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 +4 -4
- data/README.md +31 -0
- data/lib/denouncer.rb +91 -20
- data/lib/denouncer/notifiers/amqp_notifier.rb +7 -3
- data/lib/denouncer/notifiers/base_notifier.rb +5 -11
- data/lib/denouncer/notifiers/console_notifier.rb +5 -0
- data/lib/denouncer/notifiers/smtp_notifier.rb +5 -0
- data/lib/denouncer/version.rb +1 -1
- data/spec/lib/denouncer/denouncer_spec.rb +155 -22
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 435f952054638a12c1528c1a3efd126b3e37d932
|
4
|
+
data.tar.gz: 69e8ea1f3e5fde186106dee702b8d5d798f717d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/denouncer.rb
CHANGED
@@ -5,34 +5,49 @@ module Denouncer
|
|
5
5
|
|
6
6
|
DEFAULT_NOTIFIER = :smtp
|
7
7
|
|
8
|
-
@@
|
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
|
-
|
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
|
-
@@
|
28
|
+
@@notifiers = nil
|
26
29
|
end
|
27
30
|
|
28
31
|
def self.is_configured?
|
29
|
-
!
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
67
|
-
return @@
|
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:
|
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.
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
# @
|
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
|
@@ -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?
|
data/lib/denouncer/version.rb
CHANGED
@@ -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:
|
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
|
46
|
+
it "should initialize notifiers" do
|
34
47
|
Denouncer.configure new_configuration
|
35
|
-
expect(Denouncer.send(:
|
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
|
59
|
+
it "should initialize notifiers" do
|
46
60
|
Denouncer.configure new_configuration
|
47
|
-
expect(Denouncer.send(:
|
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
|
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
|
-
|
123
|
-
|
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
|
-
|
127
|
-
|
128
|
-
|
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 "
|
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
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|
152
|
-
|
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
|
-
|
157
|
-
|
158
|
-
|
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.
|
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-
|
11
|
+
date: 2015-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|