exception_notification 4.1.2 → 4.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +8 -0
- data/README.md +116 -147
- data/exception_notification.gemspec +3 -3
- data/lib/exception_notifier.rb +1 -0
- data/lib/exception_notifier/base_notifier.rb +25 -0
- data/lib/exception_notifier/campfire_notifier.rb +5 -2
- data/lib/exception_notifier/email_notifier.rb +20 -6
- data/lib/exception_notifier/hipchat_notifier.rb +5 -2
- data/lib/exception_notifier/irc_notifier.rb +7 -2
- data/lib/exception_notifier/slack_notifier.rb +7 -2
- data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_request.text.erb +2 -2
- data/lib/exception_notifier/webhook_notifier.rb +6 -4
- data/test/dummy/config/environment.rb +3 -1
- data/test/exception_notifier/campfire_notifier_test.rb +24 -0
- data/test/exception_notifier/email_notifier_test.rb +25 -0
- data/test/exception_notifier/hipchat_notifier_test.rb +18 -0
- data/test/exception_notifier/irc_notifier_test.rb +19 -0
- data/test/exception_notifier/slack_notifier_test.rb +29 -0
- data/test/exception_notifier/webhook_notifier_test.rb +6 -0
- data/test/exception_notifier_test.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3696eecc7d4afcf68b5458d570f811a595b2e912
|
4
|
+
data.tar.gz: 1a5d379db9e9e9dff3d4e15c1b9e3f435daa41f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bde0dd2960675f710e0073d38f2f4e75bc7b783de92ea337337b83e67ce39a7650911a182743c2cd2200082b74fb113c0619e453e3817e2fa52b0796b841f3dd
|
7
|
+
data.tar.gz: 6caf354673c7e63c800fa9417d5bf9df72220257a891895326bbae110aaa4879770d87fb30113e555014b691094f9f4e47a7968bc619f3d6e18a60a3b09a3eae
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== undefined
|
2
|
+
|
3
|
+
* enhancements
|
4
|
+
* Add a way to have a backtrace callback on notifiers (by @pcboy)
|
5
|
+
|
6
|
+
* bug fixes
|
7
|
+
* Fix incompatible character encodings error (by @san650)
|
8
|
+
|
1
9
|
== 4.1.2
|
2
10
|
* enhancements
|
3
11
|
* Change format of Slack notifications (by @eldano)
|
data/README.md
CHANGED
@@ -7,26 +7,21 @@
|
|
7
7
|
|
8
8
|
**THIS README IS FOR THE MASTER BRANCH AND REFLECTS THE WORK CURRENTLY EXISTING ON THE MASTER BRANCH. IF YOU ARE WISHING TO USE A NON-MASTER BRANCH OF EXCEPTION NOTIFICATION, PLEASE CONSULT THAT BRANCH'S README AND NOT THIS ONE.**
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
The Exception Notification gem provides a set of [notifiers](#notifiers) for sending notifications when errors occur in a Rack/Rails application.
|
13
|
-
|
14
|
-
The built-in notifiers can deliver notifications by [email](#email-notifier), [campfire rooms](#campfire-notifier) or via [webhooks](#webhook-notifier).
|
10
|
+
---
|
15
11
|
|
12
|
+
The Exception Notification gem provides a set of [notifiers](#notifiers) for sending notifications when errors occur in a Rack/Rails application. The built-in notifiers can deliver notifications by [email](#email-notifier), [Campfire](#campfire-notifier), [HipChat](#hipchat-notifier), [Slack](#slack-notifier), [IRC](#irc-notifier) or via custom [WebHooks](#webhook-notifier).
|
16
13
|
|
17
14
|
There's a great [Railscast about Exception Notification](http://railscasts.com/episodes/104-exception-notifications-revised) you can see that may help you getting started.
|
18
15
|
|
19
16
|
[Follow us on Twitter](https://twitter.com/exception_notif) to get updates and notices about new releases.
|
20
17
|
|
21
|
-
|
22
18
|
## Requirements
|
23
19
|
|
24
|
-
* Ruby
|
25
|
-
* Rails
|
20
|
+
* Ruby 2.0 or greater
|
21
|
+
* Rails 4.0 or greater, Sinatra or another Rack-based application.
|
26
22
|
|
27
23
|
For previous releases, please checkout [this](#versions).
|
28
24
|
|
29
|
-
|
30
25
|
## Getting Started
|
31
26
|
|
32
27
|
Add the following line to your application's Gemfile:
|
@@ -35,7 +30,9 @@ Add the following line to your application's Gemfile:
|
|
35
30
|
gem 'exception_notification'
|
36
31
|
```
|
37
32
|
|
38
|
-
|
33
|
+
### Rails
|
34
|
+
|
35
|
+
ExceptionNotification is used as a rack middleware, or in the environment you want it to run. In most cases you would want ExceptionNotification to run on production. Thus, you can make it work by putting the following lines in your `config/environments/production.rb`:
|
39
36
|
|
40
37
|
```ruby
|
41
38
|
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
@@ -46,24 +43,38 @@ Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
46
43
|
}
|
47
44
|
```
|
48
45
|
|
49
|
-
|
46
|
+
**Note**: In order to enable delivery notifications by email make sure you have [ActionMailer configured](#actionmailer-configuration).
|
50
47
|
|
48
|
+
### Rack/Sinatra
|
51
49
|
|
52
50
|
In order to use ExceptionNotification with Sinatra, please take a look in the [example application](https://github.com/smartinez87/exception_notification/tree/master/examples/sinatra).
|
53
51
|
|
52
|
+
## Notifiers
|
53
|
+
|
54
|
+
ExceptionNotification relies on notifiers to deliver notifications when errors occur in your applications. By default, six notifiers are available:
|
54
55
|
|
55
|
-
|
56
|
+
* [Campfire notifier](#campfire-notifier)
|
57
|
+
* [Email notifier](#email-notifier)
|
58
|
+
* [HipChat notifier](#hipchat-notifier)
|
59
|
+
* [IRC notifier](#irc-notifier)
|
60
|
+
* [Slack notifier](#slack-notifier)
|
61
|
+
* [WebHook notifier](#webhook-notifier)
|
56
62
|
|
57
|
-
|
63
|
+
But, you also can easily implement your own [custom notifier](#custom-notifier).
|
64
|
+
|
65
|
+
### Campfire notifier
|
66
|
+
|
67
|
+
This notifier sends notifications to your Campfire room.
|
68
|
+
|
69
|
+
#### Usage
|
70
|
+
|
71
|
+
Just add the [tinder](https://github.com/collectiveidea/tinder) gem to your `Gemfile`:
|
58
72
|
|
59
73
|
```ruby
|
60
|
-
|
61
|
-
:email_prefix => "[PREFIX] ",
|
62
|
-
:sender_address => %{"notifier" <notifier@example.com>},
|
63
|
-
:exception_recipients => %w{exceptions@example.com}
|
74
|
+
gem 'tinder'
|
64
75
|
```
|
65
76
|
|
66
|
-
|
77
|
+
To configure it, you need to set the `subdomain`, `token` and `room_name` options, like this:
|
67
78
|
|
68
79
|
```ruby
|
69
80
|
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
@@ -71,21 +82,42 @@ Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
71
82
|
:email_prefix => "[PREFIX] ",
|
72
83
|
:sender_address => %{"notifier" <notifier@example.com>},
|
73
84
|
:exception_recipients => %w{exceptions@example.com}
|
85
|
+
},
|
86
|
+
:campfire => {
|
87
|
+
:subdomain => 'my_subdomain',
|
88
|
+
:token => 'my_token',
|
89
|
+
:room_name => 'my_room'
|
74
90
|
}
|
75
91
|
```
|
76
92
|
|
77
|
-
|
93
|
+
#### Options
|
78
94
|
|
79
|
-
|
95
|
+
##### subdomain
|
80
96
|
|
81
|
-
|
97
|
+
*String, required*
|
82
98
|
|
99
|
+
Your subdomain at Campfire.
|
100
|
+
|
101
|
+
##### room_name
|
102
|
+
|
103
|
+
*String, required*
|
104
|
+
|
105
|
+
The Campfire room where the notifications must be published to.
|
106
|
+
|
107
|
+
##### token
|
108
|
+
|
109
|
+
*String, required*
|
110
|
+
|
111
|
+
The API token to allow access to your Campfire account.
|
112
|
+
|
113
|
+
|
114
|
+
For more options to set Campfire, like _ssl_, check [here](https://github.com/collectiveidea/tinder/blob/master/lib/tinder/campfire.rb#L17).
|
83
115
|
|
84
116
|
### Email notifier
|
85
117
|
|
86
118
|
The Email notifier sends notifications by email. The notifications/emails sent includes information about the current request, session, and environment, and also gives a backtrace of the exception.
|
87
119
|
|
88
|
-
After an exception notification has been delivered the rack environment variable
|
120
|
+
After an exception notification has been delivered the rack environment variable `exception_notifier.delivered` will be set to true.
|
89
121
|
|
90
122
|
#### ActionMailer configuration
|
91
123
|
|
@@ -110,21 +142,18 @@ config.action_mailer.raise_delivery_errors = true
|
|
110
142
|
|
111
143
|
Who the message is from.
|
112
144
|
|
113
|
-
|
114
145
|
##### exception_recipients
|
115
146
|
|
116
147
|
*String/Array of strings, default: []*
|
117
148
|
|
118
149
|
Who the message is destined for, can be a string of addresses, or an array of addresses.
|
119
150
|
|
120
|
-
|
121
151
|
##### email_prefix
|
122
152
|
|
123
153
|
*String, default: [ERROR]*
|
124
154
|
|
125
155
|
The subject's prefix of the message.
|
126
156
|
|
127
|
-
|
128
157
|
##### sections
|
129
158
|
|
130
159
|
*Array of strings, default: %w(request session environment backtrace)*
|
@@ -174,7 +203,6 @@ end
|
|
174
203
|
|
175
204
|
In the above case, `@document` and `@person` would be made available to the email renderer, allowing your new section(s) to access and display them. See the existing sections defined by the plugin for examples of how to write your own.
|
176
205
|
|
177
|
-
|
178
206
|
##### background_sections
|
179
207
|
|
180
208
|
*Array of strings, default: %w(backtrace data)*
|
@@ -191,7 +219,6 @@ Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
191
219
|
}
|
192
220
|
```
|
193
221
|
|
194
|
-
|
195
222
|
##### email_headers
|
196
223
|
|
197
224
|
*Hash of strings, default: {}*
|
@@ -208,28 +235,24 @@ Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
208
235
|
}
|
209
236
|
```
|
210
237
|
|
211
|
-
|
212
238
|
##### verbose_subject
|
213
239
|
|
214
240
|
*Boolean, default: true*
|
215
241
|
|
216
242
|
If enabled, include the exception message in the subject. Use `:verbose_subject => false` to exclude it.
|
217
243
|
|
218
|
-
|
219
244
|
##### normalize_subject
|
220
245
|
|
221
246
|
*Boolean, default: false*
|
222
247
|
|
223
248
|
If enabled, remove numbers from subject so they thread as a single one. Use `:normalize_subject => true` to enable it.
|
224
249
|
|
225
|
-
|
226
250
|
##### email_format
|
227
251
|
|
228
252
|
*Symbol, default: :text*
|
229
253
|
|
230
254
|
By default, ExceptionNotification sends emails in plain text, in order to sends multipart notifications (aka HTML emails) use `:email_format => :html`.
|
231
255
|
|
232
|
-
|
233
256
|
##### delivery_method
|
234
257
|
|
235
258
|
*Symbol, default: :smtp*
|
@@ -267,73 +290,18 @@ Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
267
290
|
|
268
291
|
A complete list of `smtp_settings` options can be found in the [ActionMailer Configuration documentation](http://api.rubyonrails.org/classes/ActionMailer/Base.html#class-ActionMailer::Base-label-Configuration+options).
|
269
292
|
|
270
|
-
|
271
293
|
##### mailer_parent
|
272
294
|
|
273
295
|
*String, default: ActionMailer::Base*
|
274
296
|
|
275
297
|
The parent mailer which ExceptionNotification mailer inherit from.
|
276
298
|
|
277
|
-
|
278
299
|
##### deliver_with
|
279
300
|
|
280
301
|
*Symbol, default: :deliver_now
|
281
302
|
|
282
303
|
The method name to send emalis using ActionMailer.
|
283
304
|
|
284
|
-
|
285
|
-
### Campfire notifier
|
286
|
-
|
287
|
-
This notifier sends notifications to your Campfire room.
|
288
|
-
|
289
|
-
#### Usage
|
290
|
-
|
291
|
-
Just add the [tinder](https://github.com/collectiveidea/tinder) gem to your `Gemfile`:
|
292
|
-
|
293
|
-
```ruby
|
294
|
-
gem 'tinder'
|
295
|
-
```
|
296
|
-
|
297
|
-
To configure it, you need to set the `subdomain`, `token` and `room_name` options, like this:
|
298
|
-
|
299
|
-
```ruby
|
300
|
-
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
301
|
-
:email => {
|
302
|
-
:email_prefix => "[PREFIX] ",
|
303
|
-
:sender_address => %{"notifier" <notifier@example.com>},
|
304
|
-
:exception_recipients => %w{exceptions@example.com}
|
305
|
-
},
|
306
|
-
:campfire => {
|
307
|
-
:subdomain => 'my_subdomain',
|
308
|
-
:token => 'my_token',
|
309
|
-
:room_name => 'my_room'
|
310
|
-
}
|
311
|
-
```
|
312
|
-
|
313
|
-
#### Options
|
314
|
-
|
315
|
-
##### subdomain
|
316
|
-
|
317
|
-
*String, required*
|
318
|
-
|
319
|
-
Your subdomain at Campfire.
|
320
|
-
|
321
|
-
##### room_name
|
322
|
-
|
323
|
-
*String, required*
|
324
|
-
|
325
|
-
The Campfire room where the notifications must be published to.
|
326
|
-
|
327
|
-
##### token
|
328
|
-
|
329
|
-
*String, required*
|
330
|
-
|
331
|
-
The API token to allow access to your Campfire account.
|
332
|
-
|
333
|
-
|
334
|
-
For more options to set Campfire, like _ssl_, check [here](https://github.com/collectiveidea/tinder/blob/master/lib/tinder/campfire.rb#L17).
|
335
|
-
|
336
|
-
|
337
305
|
### HipChat notifier
|
338
306
|
|
339
307
|
This notifier sends notifications to your Hipchat room.
|
@@ -395,67 +363,6 @@ Message will appear from this nickname. Default : 'Exception'.
|
|
395
363
|
|
396
364
|
For all options & possible values see [Hipchat API](https://www.hipchat.com/docs/api/method/rooms/message).
|
397
365
|
|
398
|
-
### Webhook notifier
|
399
|
-
|
400
|
-
This notifier ships notifications over the HTTP protocol.
|
401
|
-
|
402
|
-
#### Usage
|
403
|
-
|
404
|
-
Just add the [HTTParty](https://github.com/jnunemaker/httparty) gem to your `Gemfile`:
|
405
|
-
|
406
|
-
```ruby
|
407
|
-
gem 'httparty'
|
408
|
-
```
|
409
|
-
|
410
|
-
To configure it, you need to set the `url` option, like this:
|
411
|
-
|
412
|
-
```ruby
|
413
|
-
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
414
|
-
:email => {
|
415
|
-
:email_prefix => "[PREFIX] ",
|
416
|
-
:sender_address => %{"notifier" <notifier@example.com>},
|
417
|
-
:exception_recipients => %w{exceptions@example.com}
|
418
|
-
},
|
419
|
-
:webhook => {
|
420
|
-
:url => 'http://domain.com:5555/hubot/path'
|
421
|
-
}
|
422
|
-
```
|
423
|
-
|
424
|
-
By default, the WebhookNotifier will call the URLs using the POST method. But, you can change this using the `http_method` option.
|
425
|
-
|
426
|
-
```ruby
|
427
|
-
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
428
|
-
:email => {
|
429
|
-
:email_prefix => "[PREFIX] ",
|
430
|
-
:sender_address => %{"notifier" <notifier@example.com>},
|
431
|
-
:exception_recipients => %w{exceptions@example.com}
|
432
|
-
},
|
433
|
-
:webhook => {
|
434
|
-
:url => 'http://domain.com:5555/hubot/path',
|
435
|
-
:http_method => :get
|
436
|
-
}
|
437
|
-
```
|
438
|
-
|
439
|
-
Besides the `url` and `http_method` options, all the other options are passed directly to HTTParty. Thus, if the HTTP server requires authentication, you can include the following options:
|
440
|
-
|
441
|
-
```ruby
|
442
|
-
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
443
|
-
:email => {
|
444
|
-
:email_prefix => "[PREFIX] ",
|
445
|
-
:sender_address => %{"notifier" <notifier@example.com>},
|
446
|
-
:exception_recipients => %w{exceptions@example.com}
|
447
|
-
},
|
448
|
-
:webhook => {
|
449
|
-
:url => 'http://domain.com:5555/hubot/path',
|
450
|
-
:basic_auth => {
|
451
|
-
:username => 'alice',
|
452
|
-
:password => 'password'
|
453
|
-
}
|
454
|
-
}
|
455
|
-
```
|
456
|
-
|
457
|
-
For more HTTParty options, check out the [documentation](https://github.com/jnunemaker/httparty).
|
458
|
-
|
459
366
|
### IRC notifier
|
460
367
|
|
461
368
|
This notifier sends notifications to an IRC channel using the carrier-pigeon gem.
|
@@ -638,6 +545,68 @@ more information. Default: 'incoming-webhook'
|
|
638
545
|
|
639
546
|
Contains additional payload for a message (e.g avatar, attachments, etc). See [slack-notifier](https://github.com/stevenosloan/slack-notifier#additional-parameters) for more information.. Default: '{}'
|
640
547
|
|
548
|
+
|
549
|
+
### WebHook notifier
|
550
|
+
|
551
|
+
This notifier ships notifications over the HTTP protocol.
|
552
|
+
|
553
|
+
#### Usage
|
554
|
+
|
555
|
+
Just add the [HTTParty](https://github.com/jnunemaker/httparty) gem to your `Gemfile`:
|
556
|
+
|
557
|
+
```ruby
|
558
|
+
gem 'httparty'
|
559
|
+
```
|
560
|
+
|
561
|
+
To configure it, you need to set the `url` option, like this:
|
562
|
+
|
563
|
+
```ruby
|
564
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
565
|
+
:email => {
|
566
|
+
:email_prefix => "[PREFIX] ",
|
567
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
568
|
+
:exception_recipients => %w{exceptions@example.com}
|
569
|
+
},
|
570
|
+
:webhook => {
|
571
|
+
:url => 'http://domain.com:5555/hubot/path'
|
572
|
+
}
|
573
|
+
```
|
574
|
+
|
575
|
+
By default, the WebhookNotifier will call the URLs using the POST method. But, you can change this using the `http_method` option.
|
576
|
+
|
577
|
+
```ruby
|
578
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
579
|
+
:email => {
|
580
|
+
:email_prefix => "[PREFIX] ",
|
581
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
582
|
+
:exception_recipients => %w{exceptions@example.com}
|
583
|
+
},
|
584
|
+
:webhook => {
|
585
|
+
:url => 'http://domain.com:5555/hubot/path',
|
586
|
+
:http_method => :get
|
587
|
+
}
|
588
|
+
```
|
589
|
+
|
590
|
+
Besides the `url` and `http_method` options, all the other options are passed directly to HTTParty. Thus, if the HTTP server requires authentication, you can include the following options:
|
591
|
+
|
592
|
+
```ruby
|
593
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
594
|
+
:email => {
|
595
|
+
:email_prefix => "[PREFIX] ",
|
596
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
597
|
+
:exception_recipients => %w{exceptions@example.com}
|
598
|
+
},
|
599
|
+
:webhook => {
|
600
|
+
:url => 'http://domain.com:5555/hubot/path',
|
601
|
+
:basic_auth => {
|
602
|
+
:username => 'alice',
|
603
|
+
:password => 'password'
|
604
|
+
}
|
605
|
+
}
|
606
|
+
```
|
607
|
+
|
608
|
+
For more HTTParty options, check out the [documentation](https://github.com/jnunemaker/httparty).
|
609
|
+
|
641
610
|
### Custom notifier
|
642
611
|
|
643
612
|
Simply put, notifiers are objects which respond to `#call(exception, options)` method. Thus, a lambda can be used as a notifier as follow:
|
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'exception_notification'
|
3
|
-
s.version = '4.1.
|
3
|
+
s.version = '4.1.3'
|
4
4
|
s.authors = ["Jamis Buck", "Josh Peek"]
|
5
|
-
s.date = %q{2015-12-
|
5
|
+
s.date = %q{2015-12-22}
|
6
6
|
s.summary = "Exception notification for Rails apps"
|
7
7
|
s.homepage = "http://smartinez87.github.com/exception_notification"
|
8
8
|
s.email = "smartinez87@gmail.com"
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.add_development_dependency "rails", "~> 4.0"
|
23
23
|
s.add_development_dependency "resque", "~> 1.2.0"
|
24
|
-
# Sidekiq 3.2.2 does not support Ruby 1.9.
|
24
|
+
# Sidekiq 3.2.2 does not support Ruby 1.9.
|
25
25
|
s.add_development_dependency "sidekiq", "~> 3.0.0", "< 3.2.2"
|
26
26
|
s.add_development_dependency "tinder", "~> 1.8"
|
27
27
|
s.add_development_dependency "httparty", "~> 0.10.2"
|
data/lib/exception_notifier.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module ExceptionNotifier
|
2
|
+
class BaseNotifier
|
3
|
+
attr_accessor :base_options
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
@base_options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_notice(exception, options, message, message_opts=nil)
|
10
|
+
_pre_callback(exception, options, message, message_opts)
|
11
|
+
result = yield(message, message_opts)
|
12
|
+
_post_callback(exception, options, message, message_opts)
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
def _pre_callback(exception, options, message, message_opts)
|
17
|
+
@base_options[:pre_callback].call(base_options, self, exception.backtrace, message, message_opts) if @base_options[:pre_callback].respond_to?(:call)
|
18
|
+
end
|
19
|
+
|
20
|
+
def _post_callback(exception, options, message, message_opts)
|
21
|
+
@base_options[:post_callback].call(base_options, self, exception.backtrace, message, message_opts) if @base_options[:post_callback].respond_to?(:call)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module ExceptionNotifier
|
2
|
-
class CampfireNotifier
|
2
|
+
class CampfireNotifier < BaseNotifier
|
3
3
|
|
4
4
|
attr_accessor :subdomain
|
5
5
|
attr_accessor :token
|
6
6
|
attr_accessor :room
|
7
7
|
|
8
8
|
def initialize(options)
|
9
|
+
super
|
9
10
|
begin
|
10
11
|
subdomain = options.delete(:subdomain)
|
11
12
|
room_name = options.delete(:room_name)
|
@@ -20,7 +21,9 @@ module ExceptionNotifier
|
|
20
21
|
if active?
|
21
22
|
message = "A new exception occurred: '#{exception.message}'"
|
22
23
|
message += " on '#{exception.backtrace.first}'" if exception.backtrace
|
23
|
-
|
24
|
+
send_notice(exception, options, message) do |msg, _|
|
25
|
+
@room.paste msg
|
26
|
+
end
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
@@ -4,7 +4,9 @@ require 'action_dispatch'
|
|
4
4
|
require 'pp'
|
5
5
|
|
6
6
|
module ExceptionNotifier
|
7
|
-
class EmailNotifier <
|
7
|
+
class EmailNotifier < BaseNotifier
|
8
|
+
attr_accessor(:sender_address, :exception_recipients,
|
9
|
+
:pre_callback, :post_callback,
|
8
10
|
:email_prefix, :email_format, :sections, :background_sections,
|
9
11
|
:verbose_subject, :normalize_subject, :delivery_method, :mailer_settings,
|
10
12
|
:email_headers, :mailer_parent, :template_path, :deliver_with)
|
@@ -78,6 +80,12 @@ module ExceptionNotifier
|
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
83
|
+
helper_method :safe_encode
|
84
|
+
|
85
|
+
def safe_encode(value)
|
86
|
+
value.encode("utf-8", invalid: :replace, undef: :replace, replace: "_")
|
87
|
+
end
|
88
|
+
|
81
89
|
def html_mail?
|
82
90
|
@options[:email_format] == :html
|
83
91
|
end
|
@@ -115,20 +123,22 @@ module ExceptionNotifier
|
|
115
123
|
end
|
116
124
|
|
117
125
|
def initialize(options)
|
126
|
+
super
|
118
127
|
delivery_method = (options[:delivery_method] || :smtp)
|
119
128
|
mailer_settings_key = "#{delivery_method}_settings".to_sym
|
120
129
|
options[:mailer_settings] = options.delete(mailer_settings_key)
|
121
130
|
|
122
|
-
|
131
|
+
options.reverse_merge(EmailNotifier.default_options).select{|k,v|[
|
123
132
|
:sender_address, :exception_recipients,
|
133
|
+
:pre_callback, :post_callback,
|
124
134
|
:email_prefix, :email_format, :sections, :background_sections,
|
125
135
|
:verbose_subject, :normalize_subject, :delivery_method, :mailer_settings,
|
126
|
-
:email_headers, :mailer_parent, :template_path, :deliver_with))
|
136
|
+
:email_headers, :mailer_parent, :template_path, :deliver_with].include?(k)}.each{|k,v| send("#{k}=", v)}
|
127
137
|
end
|
128
138
|
|
129
139
|
def options
|
130
140
|
@options ||= {}.tap do |opts|
|
131
|
-
|
141
|
+
self.instance_variables.each { |var| opts[var[1..-1].to_sym] = self.instance_variable_get(var) }
|
132
142
|
end
|
133
143
|
end
|
134
144
|
|
@@ -147,9 +157,13 @@ module ExceptionNotifier
|
|
147
157
|
env = options[:env]
|
148
158
|
default_options = self.options
|
149
159
|
if env.nil?
|
150
|
-
|
160
|
+
send_notice(exception, options, nil, default_options) do |_, default_opts|
|
161
|
+
mailer.background_exception_notification(exception, options, default_opts)
|
162
|
+
end
|
151
163
|
else
|
152
|
-
|
164
|
+
send_notice(exception, options, nil, default_options) do |_, default_opts|
|
165
|
+
mailer.exception_notification(env, exception, options, default_opts)
|
166
|
+
end
|
153
167
|
end
|
154
168
|
end
|
155
169
|
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module ExceptionNotifier
|
2
|
-
class HipchatNotifier
|
2
|
+
class HipchatNotifier < BaseNotifier
|
3
3
|
|
4
4
|
attr_accessor :from
|
5
5
|
attr_accessor :room
|
6
6
|
attr_accessor :message_options
|
7
7
|
|
8
8
|
def initialize(options)
|
9
|
+
super
|
9
10
|
begin
|
10
11
|
api_token = options.delete(:api_token)
|
11
12
|
room_name = options.delete(:room_name)
|
@@ -30,7 +31,9 @@ module ExceptionNotifier
|
|
30
31
|
return if !active?
|
31
32
|
|
32
33
|
message = @message_template.call(exception)
|
33
|
-
|
34
|
+
send_notice(exception, options, message, @message_options) do |msg, message_opts|
|
35
|
+
@room.send(@from, msg, message_opts)
|
36
|
+
end
|
34
37
|
end
|
35
38
|
|
36
39
|
private
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module ExceptionNotifier
|
2
|
-
class IrcNotifier
|
2
|
+
class IrcNotifier < BaseNotifier
|
3
3
|
def initialize(options)
|
4
|
+
super
|
4
5
|
@config = OpenStruct.new
|
5
6
|
parse_options(options)
|
6
7
|
end
|
@@ -8,7 +9,11 @@ module ExceptionNotifier
|
|
8
9
|
def call(exception, options={})
|
9
10
|
message = "'#{exception.message}'"
|
10
11
|
message += " on '#{exception.backtrace.first}'" if exception.backtrace
|
11
|
-
|
12
|
+
if active?
|
13
|
+
send_notice(exception, options, message) do |msg, _|
|
14
|
+
send_message([*@config.prefix, *msg].join(' '))
|
15
|
+
end
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
def send_message(message)
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module ExceptionNotifier
|
2
|
-
class SlackNotifier
|
2
|
+
class SlackNotifier < BaseNotifier
|
3
3
|
include ExceptionNotifier::BacktraceCleaner
|
4
4
|
|
5
5
|
attr_accessor :notifier
|
6
6
|
|
7
7
|
def initialize(options)
|
8
|
+
super
|
8
9
|
begin
|
9
10
|
@ignore_data_if = options[:ignore_data_if]
|
10
11
|
|
@@ -38,7 +39,11 @@ module ExceptionNotifier
|
|
38
39
|
|
39
40
|
attchs = [color: 'danger', text: text, fields: fields, mrkdwn_in: %w(text fields)]
|
40
41
|
|
41
|
-
|
42
|
+
if valid?
|
43
|
+
send_notice(exception, options, clean_message, @message_opts.merge(attachments: attchs)) do |msg, message_opts|
|
44
|
+
@notifier.ping '', message_opts
|
45
|
+
end
|
46
|
+
end
|
42
47
|
end
|
43
48
|
|
44
49
|
protected
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% filtered_env = @request.filtered_env -%>
|
2
2
|
<% max = filtered_env.keys.map(&:to_s).max { |a, b| a.length <=> b.length } -%>
|
3
3
|
<% filtered_env.keys.map(&:to_s).sort.each do |key| -%>
|
4
|
-
* <%= raw("%-*s: %s" % [max.length, key, inspect_object(filtered_env[key])]) %>
|
4
|
+
* <%= raw safe_encode("%-*s: %s" % [max.length, key, inspect_object(filtered_env[key])]) %>
|
5
5
|
<% end -%>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
* URL : <%= raw @request.url %>
|
1
|
+
* URL : <%= raw safe_encode @request.url %>
|
2
2
|
* HTTP Method: <%= raw @request.request_method %>
|
3
3
|
* IP address : <%= raw @request.remote_ip %>
|
4
|
-
* Parameters : <%= raw @request.filtered_parameters.inspect %>
|
4
|
+
* Parameters : <%= raw safe_encode @request.filtered_parameters.inspect %>
|
5
5
|
* Timestamp : <%= raw Time.current %>
|
6
6
|
* Server : <%= raw Socket.gethostname %>
|
7
7
|
<% if defined?(Rails) && Rails.respond_to?(:root) %>
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'action_dispatch'
|
2
2
|
|
3
3
|
module ExceptionNotifier
|
4
|
-
class WebhookNotifier
|
4
|
+
class WebhookNotifier < BaseNotifier
|
5
5
|
|
6
6
|
def initialize(options)
|
7
|
+
super
|
7
8
|
@default_options = options
|
8
9
|
end
|
9
10
|
|
@@ -23,7 +24,7 @@ module ExceptionNotifier
|
|
23
24
|
options[:body][:exception] = {:error_class => exception.class.to_s,
|
24
25
|
:message => exception.message.inspect,
|
25
26
|
:backtrace => exception.backtrace}
|
26
|
-
options[:body][:data] = (env['exception_notifier.exception_data'] || {}).merge(options[:data] || {})
|
27
|
+
options[:body][:data] = (env && env['exception_notifier.exception_data'] || {}).merge(options[:data] || {})
|
27
28
|
|
28
29
|
unless env.nil?
|
29
30
|
request = ActionDispatch::Request.new(env)
|
@@ -38,8 +39,9 @@ module ExceptionNotifier
|
|
38
39
|
options[:body][:session] = request.session
|
39
40
|
options[:body][:environment] = request.filtered_env
|
40
41
|
end
|
41
|
-
|
42
|
-
|
42
|
+
send_notice(exception, options, nil, @default_options) do |msg, opts|
|
43
|
+
HTTParty.send(http_method, url, opts)
|
44
|
+
end
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
@@ -8,7 +8,9 @@ Dummy::Application.config.middleware.use ExceptionNotification::Rack,
|
|
8
8
|
:exception_recipients => %w{dummyexceptions@example.com},
|
9
9
|
:email_headers => { "X-Custom-Header" => "foobar" },
|
10
10
|
:sections => ['new_section', 'request', 'session', 'environment', 'backtrace'],
|
11
|
-
:background_sections => %w(new_bkg_section backtrace data)
|
11
|
+
:background_sections => %w(new_bkg_section backtrace data),
|
12
|
+
:pre_callback => proc { |opts, notifier, backtrace, message, message_opts| message_opts[:pre_callback_called] = 1 },
|
13
|
+
:post_callback => proc { |opts, notifier, backtrace, message, message_opts| message_opts[:post_callback_called] = 1 }
|
12
14
|
}
|
13
15
|
|
14
16
|
# Initialize the rails application
|
@@ -46,6 +46,30 @@ class CampfireNotifierTest < ActiveSupport::TestCase
|
|
46
46
|
assert_nil campfire.call(fake_exception)
|
47
47
|
end
|
48
48
|
|
49
|
+
test "should call pre/post_callback if specified" do
|
50
|
+
pre_callback_called, post_callback_called = 0,0
|
51
|
+
Tinder::Campfire.stubs(:new).returns(Object.new)
|
52
|
+
|
53
|
+
campfire = ExceptionNotifier::CampfireNotifier.new(
|
54
|
+
{
|
55
|
+
:subdomain => 'test',
|
56
|
+
:token => 'test_token',
|
57
|
+
:room_name => 'test_room',
|
58
|
+
:pre_callback => proc { |opts, notifier, backtrace, message, message_opts|
|
59
|
+
pre_callback_called += 1
|
60
|
+
},
|
61
|
+
:post_callback => proc { |opts, notifier, backtrace, message, message_opts|
|
62
|
+
post_callback_called += 1
|
63
|
+
}
|
64
|
+
}
|
65
|
+
)
|
66
|
+
campfire.room = Object.new
|
67
|
+
campfire.room.stubs(:paste).returns(fake_notification)
|
68
|
+
campfire.call(fake_exception)
|
69
|
+
assert_equal(1, pre_callback_called)
|
70
|
+
assert_equal(1, post_callback_called)
|
71
|
+
end
|
72
|
+
|
49
73
|
private
|
50
74
|
|
51
75
|
def fake_notification
|
@@ -13,6 +13,11 @@ class EmailNotifierTest < ActiveSupport::TestCase
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
test "should call pre/post_callback if specified" do
|
17
|
+
assert_equal @email_notifier.options[:pre_callback_called], 1
|
18
|
+
assert_equal @email_notifier.options[:post_callback_called], 1
|
19
|
+
end
|
20
|
+
|
16
21
|
test "should have default sender address overridden" do
|
17
22
|
assert_equal @email_notifier.sender_address, %("Dummy Notifier" <dummynotifier@example.com>)
|
18
23
|
end
|
@@ -150,6 +155,26 @@ class EmailNotifierTest < ActiveSupport::TestCase
|
|
150
155
|
assert_nil @ignored_mail
|
151
156
|
end
|
152
157
|
|
158
|
+
test "should encode environment strings" do
|
159
|
+
email_notifier = ExceptionNotifier::EmailNotifier.new(
|
160
|
+
:sender_address => "<dummynotifier@example.com>",
|
161
|
+
:exception_recipients => %w{dummyexceptions@example.com},
|
162
|
+
:deliver_with => :deliver_now
|
163
|
+
)
|
164
|
+
|
165
|
+
mail = email_notifier.create_email(
|
166
|
+
@exception,
|
167
|
+
:env => {
|
168
|
+
"REQUEST_METHOD" => "GET",
|
169
|
+
"rack.input" => "",
|
170
|
+
"invalid_encoding" => "R\xC3\xA9sum\xC3\xA9".force_encoding(Encoding::ASCII),
|
171
|
+
},
|
172
|
+
:email_format => :text
|
173
|
+
)
|
174
|
+
|
175
|
+
assert_match /invalid_encoding\s+: R__sum__/, mail.encoded
|
176
|
+
end
|
177
|
+
|
153
178
|
if defined?(Rails) && ('4.2'...'5.0').cover?(Rails.version)
|
154
179
|
test "should be able to specify ActionMailer::MessageDelivery method" do
|
155
180
|
email_notifier = ExceptionNotifier::EmailNotifier.new(
|
@@ -16,6 +16,24 @@ class HipchatNotifierTest < ActiveSupport::TestCase
|
|
16
16
|
hipchat.call(fake_exception)
|
17
17
|
end
|
18
18
|
|
19
|
+
test "should call pre/post_callback if specified" do
|
20
|
+
pre_callback_called, post_callback_called = 0,0
|
21
|
+
options = {
|
22
|
+
:api_token => 'good_token',
|
23
|
+
:room_name => 'room_name',
|
24
|
+
:color => 'yellow',
|
25
|
+
:pre_callback => proc { |*| pre_callback_called += 1},
|
26
|
+
:post_callback => proc { |*| post_callback_called += 1}
|
27
|
+
}
|
28
|
+
|
29
|
+
HipChat::Room.any_instance.expects(:send).with('Exception', fake_body, { :color => 'yellow' }.merge(options.except(:api_token, :room_name)))
|
30
|
+
|
31
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
32
|
+
hipchat.call(fake_exception)
|
33
|
+
assert_equal(1, pre_callback_called)
|
34
|
+
assert_equal(1, post_callback_called)
|
35
|
+
end
|
36
|
+
|
19
37
|
test "should send hipchat notification without backtrace info if properly configured" do
|
20
38
|
options = {
|
21
39
|
:api_token => 'good_token',
|
@@ -16,6 +16,25 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
16
16
|
irc.call(fake_exception)
|
17
17
|
end
|
18
18
|
|
19
|
+
test "should call pre/post_callback if specified" do
|
20
|
+
pre_callback_called, post_callback_called = 0,0
|
21
|
+
|
22
|
+
options = {
|
23
|
+
:domain => 'irc.example.com',
|
24
|
+
:pre_callback => proc { |*| pre_callback_called += 1},
|
25
|
+
:post_callback => proc { |*| post_callback_called += 1}
|
26
|
+
}
|
27
|
+
|
28
|
+
CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
|
29
|
+
/divided by 0/.match(v[:message])
|
30
|
+
end
|
31
|
+
|
32
|
+
irc = ExceptionNotifier::IrcNotifier.new(options)
|
33
|
+
irc.call(fake_exception)
|
34
|
+
assert_equal(1, pre_callback_called)
|
35
|
+
assert_equal(1, post_callback_called)
|
36
|
+
end
|
37
|
+
|
19
38
|
test "should send irc notification without backtrace info if properly configured" do
|
20
39
|
options = {
|
21
40
|
:domain => 'irc.example.com'
|
@@ -110,6 +110,35 @@ class SlackNotifierTest < ActiveSupport::TestCase
|
|
110
110
|
slack_notifier.call(@exception, notification_options)
|
111
111
|
end
|
112
112
|
|
113
|
+
test "should call pre/post_callback proc if specified" do
|
114
|
+
post_callback_called = 0
|
115
|
+
options = {
|
116
|
+
webhook_url: "http://slack.webhook.url",
|
117
|
+
username: "test",
|
118
|
+
custom_hook: "hook",
|
119
|
+
:pre_callback => proc { |opts, notifier, backtrace, message, message_opts|
|
120
|
+
(message_opts[:attachments] = []) << { text: "#{backtrace.join("\n")}", color: 'danger' }
|
121
|
+
},
|
122
|
+
:post_callback => proc { |opts, notifier, backtrace, message, message_opts|
|
123
|
+
post_callback_called = 1
|
124
|
+
},
|
125
|
+
additional_parameters: {
|
126
|
+
icon_url: "icon",
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
Slack::Notifier.any_instance.expects(:ping).with('',
|
131
|
+
{:icon_url => 'icon',
|
132
|
+
:attachments => [
|
133
|
+
{:text => "backtrace line 1\nbacktrace line 2",
|
134
|
+
:color => 'danger'}
|
135
|
+
]})
|
136
|
+
|
137
|
+
slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
|
138
|
+
slack_notifier.call(@exception)
|
139
|
+
assert_equal(post_callback_called, 1)
|
140
|
+
end
|
141
|
+
|
113
142
|
private
|
114
143
|
|
115
144
|
def fake_exception
|
@@ -25,6 +25,12 @@ class WebhookNotifierTest < ActiveSupport::TestCase
|
|
25
25
|
assert response[:body][:data][:extra_data].has_key?(:data_item1)
|
26
26
|
end
|
27
27
|
|
28
|
+
test "should call pre/post_callback if specified" do
|
29
|
+
HTTParty.stubs(:send).returns(fake_response)
|
30
|
+
webhook = ExceptionNotifier::WebhookNotifier.new({:url => 'http://localhost:8000'})
|
31
|
+
webhook.call(fake_exception)
|
32
|
+
end
|
33
|
+
|
28
34
|
private
|
29
35
|
|
30
36
|
def fake_response
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_notification
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamis Buck
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-12-
|
12
|
+
date: 2015-12-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionmailer
|
@@ -242,6 +242,7 @@ files:
|
|
242
242
|
- lib/exception_notification/resque.rb
|
243
243
|
- lib/exception_notification/sidekiq.rb
|
244
244
|
- lib/exception_notifier.rb
|
245
|
+
- lib/exception_notifier/base_notifier.rb
|
245
246
|
- lib/exception_notifier/campfire_notifier.rb
|
246
247
|
- lib/exception_notifier/email_notifier.rb
|
247
248
|
- lib/exception_notifier/hipchat_notifier.rb
|
@@ -353,7 +354,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
353
354
|
version: 1.8.11
|
354
355
|
requirements: []
|
355
356
|
rubyforge_project:
|
356
|
-
rubygems_version: 2.4.5
|
357
|
+
rubygems_version: 2.4.5.1
|
357
358
|
signing_key:
|
358
359
|
specification_version: 4
|
359
360
|
summary: Exception notification for Rails apps
|