exception_notification 4.3.0 → 4.5.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 +5 -5
- data/Appraisals +4 -2
- data/CHANGELOG.rdoc +47 -0
- data/CONTRIBUTING.md +18 -0
- data/Gemfile +3 -1
- data/README.md +97 -945
- data/Rakefile +4 -2
- data/docs/notifiers/campfire.md +50 -0
- data/docs/notifiers/custom.md +42 -0
- data/docs/notifiers/datadog.md +51 -0
- data/docs/notifiers/email.md +195 -0
- data/docs/notifiers/google_chat.md +31 -0
- data/docs/notifiers/hipchat.md +66 -0
- data/docs/notifiers/irc.md +97 -0
- data/docs/notifiers/mattermost.md +115 -0
- data/docs/notifiers/slack.md +161 -0
- data/docs/notifiers/sns.md +37 -0
- data/docs/notifiers/teams.md +54 -0
- data/docs/notifiers/webhook.md +60 -0
- data/examples/sample_app.rb +56 -0
- data/examples/sinatra/Gemfile +8 -6
- data/examples/sinatra/config.ru +3 -1
- data/examples/sinatra/sinatra_app.rb +19 -11
- data/exception_notification.gemspec +30 -24
- data/gemfiles/{rails4_0.gemfile → rails5_2.gemfile} +2 -2
- data/gemfiles/{rails4_1.gemfile → rails6_0.gemfile} +2 -2
- data/gemfiles/{rails4_2.gemfile → rails6_1.gemfile} +2 -2
- data/gemfiles/{rails5_0.gemfile → rails7_0.gemfile} +2 -2
- data/lib/exception_notification/rack.rb +28 -30
- data/lib/exception_notification/rails.rb +2 -0
- data/lib/exception_notification/resque.rb +10 -10
- data/lib/exception_notification/sidekiq.rb +10 -12
- data/lib/exception_notification/version.rb +5 -0
- data/lib/exception_notification.rb +3 -0
- data/lib/exception_notifier/base_notifier.rb +10 -5
- data/lib/exception_notifier/datadog_notifier.rb +156 -0
- data/lib/exception_notifier/email_notifier.rb +73 -88
- data/lib/exception_notifier/google_chat_notifier.rb +27 -119
- data/lib/exception_notifier/hipchat_notifier.rb +13 -12
- data/lib/exception_notifier/irc_notifier.rb +36 -33
- data/lib/exception_notifier/mattermost_notifier.rb +54 -137
- data/lib/exception_notifier/modules/backtrace_cleaner.rb +2 -2
- data/lib/exception_notifier/modules/error_grouping.rb +24 -13
- data/lib/exception_notifier/modules/formatter.rb +125 -0
- data/lib/exception_notifier/notifier.rb +9 -6
- data/lib/exception_notifier/slack_notifier.rb +65 -40
- data/lib/exception_notifier/sns_notifier.rb +23 -13
- data/lib/exception_notifier/teams_notifier.rb +67 -46
- data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_request.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +2 -2
- data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +2 -2
- data/lib/exception_notifier/webhook_notifier.rb +17 -14
- data/lib/exception_notifier.rb +65 -10
- data/lib/generators/exception_notification/install_generator.rb +11 -5
- data/lib/generators/exception_notification/templates/{exception_notification.rb → exception_notification.rb.erb} +13 -11
- data/test/exception_notification/rack_test.rb +75 -13
- data/test/exception_notification/resque_test.rb +54 -0
- data/test/exception_notifier/datadog_notifier_test.rb +153 -0
- data/test/exception_notifier/email_notifier_test.rb +275 -153
- data/test/exception_notifier/google_chat_notifier_test.rb +158 -101
- data/test/exception_notifier/hipchat_notifier_test.rb +84 -81
- data/test/exception_notifier/irc_notifier_test.rb +36 -34
- data/test/exception_notifier/mattermost_notifier_test.rb +213 -67
- data/test/exception_notifier/modules/error_grouping_test.rb +41 -40
- data/test/exception_notifier/modules/formatter_test.rb +152 -0
- data/test/exception_notifier/sidekiq_test.rb +9 -17
- data/test/exception_notifier/slack_notifier_test.rb +66 -63
- data/test/exception_notifier/sns_notifier_test.rb +84 -32
- data/test/exception_notifier/teams_notifier_test.rb +25 -26
- data/test/exception_notifier/webhook_notifier_test.rb +52 -48
- data/test/exception_notifier_test.rb +150 -41
- data/test/support/exception_notifier_helper.rb +14 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.html.erb +0 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.text.erb +0 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_section.html.erb +0 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_section.text.erb +0 -0
- data/test/test_helper.rb +14 -13
- metadata +134 -175
- data/gemfiles/rails5_1.gemfile +0 -7
- data/lib/exception_notifier/campfire_notifier.rb +0 -40
- data/test/dummy/.gitignore +0 -4
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/controllers/posts_controller.rb +0 -30
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/helpers/posts_helper.rb +0 -2
- data/test/dummy/app/models/post.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/app/views/posts/_form.html.erb +0 -0
- data/test/dummy/app/views/posts/new.html.erb +0 -0
- data/test/dummy/app/views/posts/show.html.erb +0 -0
- data/test/dummy/config/application.rb +0 -42
- data/test/dummy/config/boot.rb +0 -6
- data/test/dummy/config/database.yml +0 -22
- data/test/dummy/config/environment.rb +0 -17
- data/test/dummy/config/environments/development.rb +0 -25
- data/test/dummy/config/environments/production.rb +0 -50
- data/test/dummy/config/environments/test.rb +0 -35
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -10
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -8
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -3
- data/test/dummy/config.ru +0 -4
- data/test/dummy/db/migrate/20110729022608_create_posts.rb +0 -15
- data/test/dummy/db/schema.rb +0 -24
- data/test/dummy/db/seeds.rb +0 -7
- data/test/dummy/lib/tasks/.gitkeep +0 -0
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -26
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/images/rails.png +0 -0
- data/test/dummy/public/index.html +0 -239
- data/test/dummy/public/javascripts/application.js +0 -2
- data/test/dummy/public/javascripts/controls.js +0 -965
- data/test/dummy/public/javascripts/dragdrop.js +0 -974
- data/test/dummy/public/javascripts/effects.js +0 -1123
- data/test/dummy/public/javascripts/prototype.js +0 -6001
- data/test/dummy/public/javascripts/rails.js +0 -191
- data/test/dummy/public/robots.txt +0 -5
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/dummy/public/stylesheets/scaffold.css +0 -56
- data/test/dummy/script/rails +0 -6
- data/test/dummy/test/functional/posts_controller_test.rb +0 -237
- data/test/dummy/test/test_helper.rb +0 -7
- data/test/exception_notifier/campfire_notifier_test.rb +0 -120
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
### Slack notifier
|
|
2
|
+
|
|
3
|
+
This notifier sends notifications to a slack channel using the slack-notifier gem.
|
|
4
|
+
|
|
5
|
+
#### Usage
|
|
6
|
+
|
|
7
|
+
Just add the [slack-notifier](https://github.com/stevenosloan/slack-notifier) gem to your `Gemfile`:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'slack-notifier'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To configure it, you need to set at least the 'webhook_url' option, like this:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
17
|
+
email: {
|
|
18
|
+
email_prefix: '[PREFIX] ',
|
|
19
|
+
sender_address: %{"notifier" <notifier@example.com>},
|
|
20
|
+
exception_recipients: %w{exceptions@example.com}
|
|
21
|
+
},
|
|
22
|
+
slack: {
|
|
23
|
+
webhook_url: '[Your webhook url]',
|
|
24
|
+
channel: '#exceptions',
|
|
25
|
+
additional_parameters: {
|
|
26
|
+
icon_url: 'http://image.jpg',
|
|
27
|
+
mrkdwn: true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The slack notification will include any data saved under `env['exception_notifier.exception_data']`.
|
|
33
|
+
|
|
34
|
+
An example of how to send the server name to Slack in Rails (put this code in application_controller.rb):
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
before_action :set_notification
|
|
38
|
+
|
|
39
|
+
def set_notification
|
|
40
|
+
request.env['exception_notifier.exception_data'] = { 'server' => request.env['SERVER_NAME'] }
|
|
41
|
+
# can be any key-value pairs
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
If you find this too verbose, you can determine to exclude certain information by doing the following:
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
49
|
+
slack: {
|
|
50
|
+
webhook_url: '[Your webhook url]',
|
|
51
|
+
channel: '#exceptions',
|
|
52
|
+
additional_parameters: {
|
|
53
|
+
icon_url: 'http://image.jpg',
|
|
54
|
+
mrkdwn: true
|
|
55
|
+
},
|
|
56
|
+
ignore_data_if: lambda {|key, value|
|
|
57
|
+
"#{key}" == 'key_to_ignore' || value.is_a?(ClassToBeIgnored)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Any evaluation to `true` will cause the key / value pair not be be sent along to Slack.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
the `slack-notifier` gem allows to override the channel default value, if you ever
|
|
66
|
+
need to send a notification to a different slack channel. Simply add the
|
|
67
|
+
`channel` option when calling `.notify_exception`
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
ExceptionNotifier.notify_exception(
|
|
71
|
+
exception,
|
|
72
|
+
env: request.env,
|
|
73
|
+
channel: '#my-custom-channel', # Make sure the channel name starts with `#`
|
|
74
|
+
data: {
|
|
75
|
+
error: error_variable,
|
|
76
|
+
server: server_name
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If you ever need to add more `slack-notifier` specific options, and
|
|
82
|
+
particularly to the `#ping` method of the slack notifier, you can use
|
|
83
|
+
the `pre_callback` option when defining the middleware.
|
|
84
|
+
```ruby
|
|
85
|
+
pre_callback: proc { |opts, _notifier, _backtrace, _message, message_opts|
|
|
86
|
+
message_opts[:channel] = opts[:channel] if opts.key?(:channel)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
- `message_opts` is the hash you want to append to if you need to add an option.
|
|
91
|
+
- `options` is the hash containing the values when you call
|
|
92
|
+
`ExceptionNotification.notify_exception`
|
|
93
|
+
|
|
94
|
+
An example implementation would be:
|
|
95
|
+
```ruby
|
|
96
|
+
config.middleware.use ExceptionNotification::Rack,
|
|
97
|
+
slack: {
|
|
98
|
+
webhook_url: '[Your webhook url]',
|
|
99
|
+
pre_callback: proc { |opts, _notifier, _backtrace, _message, message_opts|
|
|
100
|
+
message_opts[:ping_option] = opts[:ping_option] if
|
|
101
|
+
opts.key?(:ping_option)
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
error_grouping: true
|
|
105
|
+
```
|
|
106
|
+
Then when calling from within your application code:
|
|
107
|
+
```ruby
|
|
108
|
+
ExceptionNotifier.notify_exception(
|
|
109
|
+
exception,
|
|
110
|
+
env: request.env,
|
|
111
|
+
ping_option: 'value',
|
|
112
|
+
# this will be passed to the slack notifier's `#ping`
|
|
113
|
+
# method, as a parameter. The `:pre_callback` hook will catch it
|
|
114
|
+
# and do that for you.
|
|
115
|
+
# Helpful, if the API evolves, you only need to update
|
|
116
|
+
# the `slack-notifier` gem
|
|
117
|
+
data: {
|
|
118
|
+
error: error_variable,
|
|
119
|
+
server: server_name
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
#### Options
|
|
125
|
+
|
|
126
|
+
##### webhook_url
|
|
127
|
+
|
|
128
|
+
*String, required*
|
|
129
|
+
|
|
130
|
+
The Incoming WebHook URL on slack.
|
|
131
|
+
|
|
132
|
+
##### channel
|
|
133
|
+
|
|
134
|
+
*String, optional*
|
|
135
|
+
|
|
136
|
+
Message will appear in this channel. Defaults to the channel you set as such on slack.
|
|
137
|
+
|
|
138
|
+
##### username
|
|
139
|
+
|
|
140
|
+
*String, optional*
|
|
141
|
+
|
|
142
|
+
Username of the bot. Defaults to the name you set as such on slack
|
|
143
|
+
|
|
144
|
+
##### custom_hook
|
|
145
|
+
|
|
146
|
+
*String, optional*
|
|
147
|
+
|
|
148
|
+
Custom hook name. See [slack-notifier](https://github.com/stevenosloan/slack-notifier#custom-hook-name) for
|
|
149
|
+
more information. Default: 'incoming-webhook'
|
|
150
|
+
|
|
151
|
+
##### additional_parameters
|
|
152
|
+
|
|
153
|
+
*Hash of strings, optional*
|
|
154
|
+
|
|
155
|
+
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: '{}'
|
|
156
|
+
|
|
157
|
+
##### additional_fields
|
|
158
|
+
|
|
159
|
+
*Array of Hashes, optional*
|
|
160
|
+
|
|
161
|
+
Contains additional fields that will be added to the attachement. See [Slack documentation](https://api.slack.com/docs/message-attachments).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
### Amazon SNS Notifier
|
|
2
|
+
|
|
3
|
+
Notify all exceptions Amazon - Simple Notification Service: [SNS](https://aws.amazon.com/sns/).
|
|
4
|
+
|
|
5
|
+
#### Usage
|
|
6
|
+
|
|
7
|
+
Add the [aws-sdk-sns](https://github.com/aws/aws-sdk-ruby/tree/master/gems/aws-sdk-sns) gem to your `Gemfile`:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'aws-sdk-sns', '~> 1.5'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To configure it, you **need** to set 3 required options for aws: `region`, `access_key_id` and `secret_access_key`, and one more option for sns: `topic_arn`.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
17
|
+
sns: {
|
|
18
|
+
region: 'us-east-x',
|
|
19
|
+
access_key_id: 'access_key_id',
|
|
20
|
+
secret_access_key: 'secret_access_key',
|
|
21
|
+
topic_arn: 'arn:aws:sns:us-east-x:XXXX:my-topic'
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
##### sns_prefix
|
|
26
|
+
*String, optional *
|
|
27
|
+
|
|
28
|
+
Prefix in the notification subject, by default: "[Error]"
|
|
29
|
+
|
|
30
|
+
##### backtrace_lines
|
|
31
|
+
*Integer, optional *
|
|
32
|
+
|
|
33
|
+
Number of backtrace lines to be displayed in the notification message. By default: 10
|
|
34
|
+
|
|
35
|
+
#### Note:
|
|
36
|
+
* You may need to update your previous `aws-sdk-*` gems in order to setup `aws-sdk-sns` correctly.
|
|
37
|
+
* If you need any further information about the available regions or any other SNS related topic consider: [SNS faqs](https://aws.amazon.com/sns/faqs/)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
### Teams notifier
|
|
2
|
+
|
|
3
|
+
Post notification in a Microsoft Teams channel via [Incoming Webhook Connector](https://docs.microsoft.com/en-us/outlook/actionable-messages/actionable-messages-via-connectors)
|
|
4
|
+
Just add the [HTTParty](https://github.com/jnunemaker/httparty) gem to your `Gemfile`:
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
gem 'httparty'
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
To configure it, you **need** to set the `webhook_url` option.
|
|
11
|
+
If you are using GitLab for issue tracking, you can specify `git_url` as follows to add a *Create issue* button in your notification.
|
|
12
|
+
By default this will use your Rails application name to match the git repository. If yours differs, you can specify `app_name`.
|
|
13
|
+
By that same notion, you may also set a `jira_url` to get a button that will send you to the New Issue screen in Jira.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
17
|
+
email: {
|
|
18
|
+
email_prefix: "[PREFIX] ",
|
|
19
|
+
sender_address: %{"notifier" <notifier@example.com>},
|
|
20
|
+
exception_recipients: %w{exceptions@example.com}
|
|
21
|
+
},
|
|
22
|
+
teams: {
|
|
23
|
+
webhook_url: 'https://outlook.office.com/webhook/your-guid/IncomingWebhook/team-guid',
|
|
24
|
+
git_url: 'https://your-gitlab.com/Group/Project',
|
|
25
|
+
jira_url: 'https://your-jira.com'
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
#### Options
|
|
30
|
+
|
|
31
|
+
##### webhook_url
|
|
32
|
+
|
|
33
|
+
*String, required*
|
|
34
|
+
|
|
35
|
+
The Incoming WebHook URL on Teams.
|
|
36
|
+
|
|
37
|
+
##### git_url
|
|
38
|
+
|
|
39
|
+
*String, optional*
|
|
40
|
+
|
|
41
|
+
Url of your gitlab or github with your organisation name for issue creation link (Eg: `github.com/aschen`). Defaults to nil and doesn't add link to the notification.
|
|
42
|
+
|
|
43
|
+
##### jira_url
|
|
44
|
+
|
|
45
|
+
*String, optional*
|
|
46
|
+
|
|
47
|
+
Url of your Jira instance, adds button for Create Issue screen. Defaults to nil and doesn't add a button to the card.
|
|
48
|
+
|
|
49
|
+
##### app_name
|
|
50
|
+
|
|
51
|
+
*String, optional*
|
|
52
|
+
|
|
53
|
+
Your application name used for git issue creation link. Defaults to `Rails.application.class.module_parent_name.underscore` for Rails versions >= 6;
|
|
54
|
+
`Rails.application.class.parent_name.underscore` otherwise.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
### WebHook notifier
|
|
2
|
+
|
|
3
|
+
This notifier ships notifications over the HTTP protocol.
|
|
4
|
+
|
|
5
|
+
#### Usage
|
|
6
|
+
|
|
7
|
+
Just add the [HTTParty](https://github.com/jnunemaker/httparty) gem to your `Gemfile`:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'httparty'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To configure it, you need to set the `url` option, like this:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
17
|
+
email: {
|
|
18
|
+
email_prefix: '[PREFIX] ',
|
|
19
|
+
sender_address: %{"notifier" <notifier@example.com>},
|
|
20
|
+
exception_recipients: %w{exceptions@example.com}
|
|
21
|
+
},
|
|
22
|
+
webhook: {
|
|
23
|
+
url: 'http://domain.com:5555/hubot/path'
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
By default, the WebhookNotifier will call the URLs using the POST method. But, you can change this using the `http_method` option.
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
31
|
+
email: {
|
|
32
|
+
email_prefix: '[PREFIX] ',
|
|
33
|
+
sender_address: %{"notifier" <notifier@example.com>},
|
|
34
|
+
exception_recipients: %w{exceptions@example.com}
|
|
35
|
+
},
|
|
36
|
+
webhook: {
|
|
37
|
+
url: 'http://domain.com:5555/hubot/path',
|
|
38
|
+
http_method: :get
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
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:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
Rails.application.config.middleware.use ExceptionNotification::Rack,
|
|
46
|
+
email: {
|
|
47
|
+
email_prefix: '[PREFIX] ',
|
|
48
|
+
sender_address: %{"notifier" <notifier@example.com>},
|
|
49
|
+
exception_recipients: %w{exceptions@example.com}
|
|
50
|
+
},
|
|
51
|
+
webhook: {
|
|
52
|
+
url: 'http://domain.com:5555/hubot/path',
|
|
53
|
+
basic_auth: {
|
|
54
|
+
username: 'alice',
|
|
55
|
+
password: 'password'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
For more HTTParty options, check out the [documentation](https://github.com/jnunemaker/httparty).
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# -------------------------------------------
|
|
4
|
+
# To run the application: ruby examples/sample_app.rb
|
|
5
|
+
# -------------------------------------------
|
|
6
|
+
|
|
7
|
+
require 'bundler/inline'
|
|
8
|
+
|
|
9
|
+
gemfile do
|
|
10
|
+
source 'https://rubygems.org'
|
|
11
|
+
|
|
12
|
+
gem 'rails', '5.0.0'
|
|
13
|
+
gem 'exception_notification', '4.3.0'
|
|
14
|
+
gem 'httparty', '0.15.7'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class SampleApp < Rails::Application
|
|
18
|
+
config.middleware.use ExceptionNotification::Rack,
|
|
19
|
+
webhook: {
|
|
20
|
+
url: 'http://example.com'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
config.secret_key_base = 'my secret key base'
|
|
24
|
+
|
|
25
|
+
Rails.logger = Logger.new($stdout)
|
|
26
|
+
|
|
27
|
+
routes.draw do
|
|
28
|
+
get '/', to: 'exceptions#index'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
require 'action_controller/railtie'
|
|
33
|
+
|
|
34
|
+
class ExceptionsController < ActionController::Base
|
|
35
|
+
def index
|
|
36
|
+
raise 'Sample exception raised, you should receive a notification!'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
require 'minitest/autorun'
|
|
41
|
+
|
|
42
|
+
class Test < Minitest::Test
|
|
43
|
+
include Rack::Test::Methods
|
|
44
|
+
|
|
45
|
+
def test_raise_exception
|
|
46
|
+
get '/'
|
|
47
|
+
|
|
48
|
+
assert last_response.server_error?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def app
|
|
54
|
+
Rails.application
|
|
55
|
+
end
|
|
56
|
+
end
|
data/examples/sinatra/Gemfile
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
|
-
gem
|
|
6
|
-
|
|
7
|
-
gem
|
|
8
|
-
gem
|
|
5
|
+
gem 'exception_notification', path: '../../'
|
|
6
|
+
|
|
7
|
+
gem 'foreman'
|
|
8
|
+
gem 'mailcatcher'
|
|
9
|
+
gem 'sinatra', '~> 1.3.5'
|
|
10
|
+
gem 'thin', '~> 1.5.1'
|
data/examples/sinatra/config.ru
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'rubygems'
|
|
2
4
|
require 'bundler/setup'
|
|
3
5
|
require 'sinatra/base'
|
|
@@ -5,27 +7,33 @@ require 'exception_notification'
|
|
|
5
7
|
|
|
6
8
|
class SinatraApp < Sinatra::Base
|
|
7
9
|
use Rack::Config do |env|
|
|
8
|
-
|
|
10
|
+
# This is highly recommended. It will prevent the ExceptionNotification email from including your users' passwords
|
|
11
|
+
env['action_dispatch.parameter_filter'] = [:password]
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
use ExceptionNotification::Rack,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
email: {
|
|
16
|
+
email_prefix: '[Example] ',
|
|
17
|
+
sender_address: %("notifier" <notifier@example.com>),
|
|
18
|
+
exception_recipients: %w[exceptions@example.com],
|
|
19
|
+
smtp_settings: {
|
|
20
|
+
address: 'localhost',
|
|
21
|
+
port: 1025
|
|
22
|
+
}
|
|
23
|
+
}
|
|
18
24
|
|
|
19
25
|
get '/' do
|
|
20
26
|
raise StandardError, "ERROR: #{params[:error]}" unless params[:error].blank?
|
|
21
|
-
|
|
27
|
+
|
|
28
|
+
'Everything is fine! Now, lets break things clicking <a href="/?error=ops"> here </a>.' \
|
|
29
|
+
'Dont forget to see the emails at <a href="http://localhost:1080">mailcatcher</a> !'
|
|
22
30
|
end
|
|
23
31
|
|
|
24
32
|
get '/background_notification' do
|
|
25
33
|
begin
|
|
26
|
-
1/0
|
|
27
|
-
rescue
|
|
28
|
-
ExceptionNotifier.notify_exception(e, :
|
|
34
|
+
1 / 0
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
ExceptionNotifier.notify_exception(e, data: { msg: 'Cannot divide by zero!' })
|
|
29
37
|
end
|
|
30
38
|
'Check email at <a href="http://localhost:1080">mailcatcher</a>.'
|
|
31
39
|
end
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require File.expand_path('lib/exception_notification/version', __dir__)
|
|
4
|
+
|
|
1
5
|
Gem::Specification.new do |s|
|
|
2
6
|
s.name = 'exception_notification'
|
|
3
|
-
s.version =
|
|
4
|
-
s.authors = [
|
|
5
|
-
s.date =
|
|
6
|
-
s.summary =
|
|
7
|
-
s.homepage =
|
|
8
|
-
s.email =
|
|
9
|
-
s.license =
|
|
7
|
+
s.version = ExceptionNotification::VERSION
|
|
8
|
+
s.authors = ['Jamis Buck', 'Josh Peek']
|
|
9
|
+
s.date = '2022-01-20'
|
|
10
|
+
s.summary = 'Exception notification for Rails apps'
|
|
11
|
+
s.homepage = 'https://smartinez87.github.io/exception_notification/'
|
|
12
|
+
s.email = 'smartinez87@gmail.com'
|
|
13
|
+
s.license = 'MIT'
|
|
10
14
|
|
|
11
|
-
s.required_ruby_version = '>= 2.
|
|
15
|
+
s.required_ruby_version = '>= 2.3'
|
|
12
16
|
s.required_rubygems_version = '>= 1.8.11'
|
|
13
17
|
|
|
14
18
|
s.files = `git ls-files`.split("\n")
|
|
@@ -16,21 +20,23 @@ Gem::Specification.new do |s|
|
|
|
16
20
|
s.test_files = `git ls-files -- test`.split("\n")
|
|
17
21
|
s.require_path = 'lib'
|
|
18
22
|
|
|
19
|
-
s.add_dependency(
|
|
20
|
-
s.add_dependency(
|
|
23
|
+
s.add_dependency('actionmailer', '>= 5.2', '< 8')
|
|
24
|
+
s.add_dependency('activesupport', '>= 5.2', '< 8')
|
|
21
25
|
|
|
22
|
-
s.add_development_dependency
|
|
23
|
-
s.add_development_dependency
|
|
24
|
-
|
|
25
|
-
s.add_development_dependency
|
|
26
|
-
s.add_development_dependency
|
|
27
|
-
s.add_development_dependency
|
|
28
|
-
s.add_development_dependency
|
|
29
|
-
s.add_development_dependency
|
|
30
|
-
s.add_development_dependency
|
|
31
|
-
s.add_development_dependency
|
|
32
|
-
s.add_development_dependency
|
|
33
|
-
s.add_development_dependency
|
|
34
|
-
s.add_development_dependency
|
|
35
|
-
s.add_development_dependency
|
|
26
|
+
s.add_development_dependency 'appraisal', '~> 2.2.0'
|
|
27
|
+
s.add_development_dependency 'aws-sdk-sns', '~> 1'
|
|
28
|
+
s.add_development_dependency 'carrier-pigeon', '>= 0.7.0'
|
|
29
|
+
s.add_development_dependency 'coveralls', '~> 0.8.2'
|
|
30
|
+
s.add_development_dependency 'dogapi', '>= 1.23.0'
|
|
31
|
+
s.add_development_dependency 'hipchat', '>= 1.0.0'
|
|
32
|
+
s.add_development_dependency 'httparty', '~> 0.10.2'
|
|
33
|
+
s.add_development_dependency 'mocha', '>= 0.13.0'
|
|
34
|
+
s.add_development_dependency 'mock_redis', '~> 0.19.0'
|
|
35
|
+
s.add_development_dependency 'net-smtp'
|
|
36
|
+
s.add_development_dependency 'rails', '>= 5.2', '< 8'
|
|
37
|
+
s.add_development_dependency 'resque', '~> 1.8.0'
|
|
38
|
+
s.add_development_dependency 'rubocop', '0.78.0'
|
|
39
|
+
s.add_development_dependency 'sidekiq', '>= 5.0.4'
|
|
40
|
+
s.add_development_dependency 'slack-notifier', '>= 1.0.0'
|
|
41
|
+
s.add_development_dependency 'timecop', '~> 0.9.0'
|
|
36
42
|
end
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ExceptionNotification
|
|
2
4
|
class Rack
|
|
3
|
-
class CascadePassException <
|
|
5
|
+
class CascadePassException < RuntimeError; end
|
|
4
6
|
|
|
5
7
|
def initialize(app, options = {})
|
|
6
8
|
@app = app
|
|
7
9
|
|
|
8
|
-
ExceptionNotifier.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
ExceptionNotifier.tap do |en|
|
|
11
|
+
en.ignored_exceptions = options.delete(:ignore_exceptions) if options.key?(:ignore_exceptions)
|
|
12
|
+
en.error_grouping = options.delete(:error_grouping) if options.key?(:error_grouping)
|
|
13
|
+
en.error_grouping_period = options.delete(:error_grouping_period) if options.key?(:error_grouping_period)
|
|
14
|
+
en.notification_trigger = options.delete(:notification_trigger) if options.key?(:notification_trigger)
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
if options.key?(:error_grouping_cache)
|
|
17
|
+
en.error_grouping_cache = options.delete(:error_grouping_cache)
|
|
18
|
+
elsif defined?(Rails) && Rails.respond_to?(:cache)
|
|
19
|
+
en.error_grouping_cache = Rails.cache
|
|
20
|
+
end
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
if options.key?(:ignore_if)
|
|
@@ -23,13 +27,17 @@ module ExceptionNotification
|
|
|
23
27
|
end
|
|
24
28
|
end
|
|
25
29
|
|
|
26
|
-
if options.key?(:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
if options.key?(:ignore_notifier_if)
|
|
31
|
+
rack_ignore_by_notifier = options.delete(:ignore_notifier_if)
|
|
32
|
+
rack_ignore_by_notifier.each do |notifier, proc|
|
|
33
|
+
ExceptionNotifier.ignore_notifier_if(notifier) do |exception, opts|
|
|
34
|
+
opts.key?(:env) && proc.call(opts[:env], exception)
|
|
35
|
+
end
|
|
30
36
|
end
|
|
31
37
|
end
|
|
32
38
|
|
|
39
|
+
ExceptionNotifier.ignore_crawlers(options.delete(:ignore_crawlers)) if options.key?(:ignore_crawlers)
|
|
40
|
+
|
|
33
41
|
@ignore_cascade_pass = options.delete(:ignore_cascade_pass) { true }
|
|
34
42
|
|
|
35
43
|
options.each do |notifier_name, opts|
|
|
@@ -38,31 +46,21 @@ module ExceptionNotification
|
|
|
38
46
|
end
|
|
39
47
|
|
|
40
48
|
def call(env)
|
|
41
|
-
_, headers,
|
|
49
|
+
_, headers, = response = @app.call(env)
|
|
42
50
|
|
|
43
51
|
if !@ignore_cascade_pass && headers['X-Cascade'] == 'pass'
|
|
44
|
-
msg = "This exception means that the preceding Rack middleware set the 'X-Cascade' header to 'pass' -- in "
|
|
45
|
-
|
|
52
|
+
msg = "This exception means that the preceding Rack middleware set the 'X-Cascade' header to 'pass' -- in " \
|
|
53
|
+
'Rails, this often means that the route was not found (404 error).'
|
|
46
54
|
raise CascadePassException, msg
|
|
47
55
|
end
|
|
48
56
|
|
|
49
57
|
response
|
|
50
|
-
rescue Exception =>
|
|
51
|
-
if ExceptionNotifier.notify_exception(
|
|
52
|
-
env['exception_notifier.delivered'] = true
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
raise exception unless exception.is_a?(CascadePassException)
|
|
56
|
-
response
|
|
57
|
-
end
|
|
58
|
+
rescue Exception => e
|
|
59
|
+
env['exception_notifier.delivered'] = true if ExceptionNotifier.notify_exception(e, env: env)
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
raise e unless e.is_a?(CascadePassException)
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
agent = env['HTTP_USER_AGENT']
|
|
63
|
-
Array(ignored_crawlers).any? do |crawler|
|
|
64
|
-
agent =~ Regexp.new(crawler)
|
|
65
|
-
end
|
|
63
|
+
response
|
|
66
64
|
end
|
|
67
65
|
end
|
|
68
66
|
end
|