Commit 5344a29850c3b68fa248630d08a2c84f57d75cdc
Exists in
master
and in
1 other branch
Merge branch 'master' of https://github.com/errbit/errbit into adding_support_for_bitbucket_issues
Conflicts: Gemfile
Showing
13 changed files
with
143 additions
and
47 deletions
Show diff stats
Gemfile
| @@ -34,8 +34,8 @@ gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data | @@ -34,8 +34,8 @@ gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data | ||
| 34 | gem 'rails_autolink', '~> 1.0.9' | 34 | gem 'rails_autolink', '~> 1.0.9' |
| 35 | gem 'campy' | 35 | gem 'campy' |
| 36 | gem 'xmpp4r' | 36 | gem 'xmpp4r' |
| 37 | -gem 'hipchat-api' | ||
| 38 | gem 'bitbucket_rest_api' | 37 | gem 'bitbucket_rest_api' |
| 38 | +gem 'hipchat' | ||
| 39 | 39 | ||
| 40 | # Please don't update this to airbrake - We override the send_notice method | 40 | # Please don't update this to airbrake - We override the send_notice method |
| 41 | # to handle internal errors. | 41 | # to handle internal errors. |
Gemfile.lock
| @@ -104,10 +104,15 @@ GEM | @@ -104,10 +104,15 @@ GEM | ||
| 104 | hashie (1.2.0) | 104 | hashie (1.2.0) |
| 105 | highline (1.6.13) | 105 | highline (1.6.13) |
| 106 | hike (1.2.1) | 106 | hike (1.2.1) |
| 107 | + hipchat (0.4.1) | ||
| 108 | + httparty | ||
| 107 | hoptoad_notifier (2.4.11) | 109 | hoptoad_notifier (2.4.11) |
| 108 | activesupport | 110 | activesupport |
| 109 | builder | 111 | builder |
| 110 | htmlentities (4.3.1) | 112 | htmlentities (4.3.1) |
| 113 | + httparty (0.9.0) | ||
| 114 | + multi_json (~> 1.0) | ||
| 115 | + multi_xml | ||
| 111 | httpauth (0.1) | 116 | httpauth (0.1) |
| 112 | i18n (0.6.1) | 117 | i18n (0.6.1) |
| 113 | inherited_resources (1.3.1) | 118 | inherited_resources (1.3.1) |
| @@ -151,6 +156,7 @@ GEM | @@ -151,6 +156,7 @@ GEM | ||
| 151 | rails (>= 3.0.0) | 156 | rails (>= 3.0.0) |
| 152 | railties (>= 3.0.0) | 157 | railties (>= 3.0.0) |
| 153 | multi_json (1.3.6) | 158 | multi_json (1.3.6) |
| 159 | + multi_xml (0.5.1) | ||
| 154 | multipart-post (1.1.5) | 160 | multipart-post (1.1.5) |
| 155 | net-scp (1.0.4) | 161 | net-scp (1.0.4) |
| 156 | net-ssh (>= 1.99.1) | 162 | net-ssh (>= 1.99.1) |
| @@ -318,6 +324,7 @@ DEPENDENCIES | @@ -318,6 +324,7 @@ DEPENDENCIES | ||
| 318 | execjs | 324 | execjs |
| 319 | fabrication (~> 1.3.0) | 325 | fabrication (~> 1.3.0) |
| 320 | haml | 326 | haml |
| 327 | + hipchat | ||
| 321 | hoptoad_notifier (~> 2.4) | 328 | hoptoad_notifier (~> 2.4) |
| 322 | htmlentities (~> 4.3.0) | 329 | htmlentities (~> 4.3.0) |
| 323 | inherited_resources | 330 | inherited_resources |
README.md
| @@ -150,9 +150,6 @@ git clone http://github.com/errbit/errbit.git | @@ -150,9 +150,6 @@ git clone http://github.com/errbit/errbit.git | ||
| 150 | gem install heroku | 150 | gem install heroku |
| 151 | heroku create example-errbit --stack cedar | 151 | heroku create example-errbit --stack cedar |
| 152 | heroku addons:add mongolab:starter | 152 | heroku addons:add mongolab:starter |
| 153 | -cp -f config/mongoid.mongolab.yml config/mongoid.yml | ||
| 154 | -git add -f config/mongoid.yml | ||
| 155 | -git commit -m "Added mongoid config for Mongolab" | ||
| 156 | heroku addons:add sendgrid:starter | 153 | heroku addons:add sendgrid:starter |
| 157 | heroku config:add HEROKU=true | 154 | heroku config:add HEROKU=true |
| 158 | heroku config:add ERRBIT_HOST=some-hostname.example.com | 155 | heroku config:add ERRBIT_HOST=some-hostname.example.com |
2.05 KB
2.05 KB
1.16 KB
app/models/notice_observer.rb
| @@ -2,13 +2,13 @@ class NoticeObserver < Mongoid::Observer | @@ -2,13 +2,13 @@ class NoticeObserver < Mongoid::Observer | ||
| 2 | observe :notice | 2 | observe :notice |
| 3 | 3 | ||
| 4 | def after_create notice | 4 | def after_create notice |
| 5 | - return unless should_notify? notice | ||
| 6 | - | ||
| 7 | - # if the app has a notficiation service, fire it off | ||
| 8 | - unless notice.app.notification_service.nil? | 5 | + # if the app has a notification service, fire it off |
| 6 | + if notice.app.notification_service_configured? | ||
| 9 | notice.app.notification_service.create_notification(notice.problem) | 7 | notice.app.notification_service.create_notification(notice.problem) |
| 10 | end | 8 | end |
| 11 | 9 | ||
| 10 | + return unless should_notify? notice | ||
| 11 | + | ||
| 12 | Mailer.err_notification(notice).deliver | 12 | Mailer.err_notification(notice).deliver |
| 13 | end | 13 | end |
| 14 | 14 |
app/models/notification_service.rb
| 1 | class NotificationService | 1 | class NotificationService |
| 2 | include Mongoid::Document | 2 | include Mongoid::Document |
| 3 | 3 | ||
| 4 | + include Rails.application.routes.url_helpers | ||
| 5 | + default_url_options[:host] = ActionMailer::Base.default_url_options[:host] | ||
| 6 | + | ||
| 4 | field :room_id, :type => String | 7 | field :room_id, :type => String |
| 5 | field :api_token, :type => String | 8 | field :api_token, :type => String |
| 6 | field :subdomain, :type => String | 9 | field :subdomain, :type => String |
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +class NotificationServices::HipchatService < NotificationService | ||
| 2 | + Label = 'hipchat' | ||
| 3 | + Fields = [ | ||
| 4 | + [:api_token, { | ||
| 5 | + :placeholder => "API Token" | ||
| 6 | + }], | ||
| 7 | + [:room_id, { | ||
| 8 | + :placeholder => "Room ID", | ||
| 9 | + :label => "Room ID" | ||
| 10 | + }], | ||
| 11 | + ] | ||
| 12 | + | ||
| 13 | + def check_params | ||
| 14 | + if Fields.any? { |f, _| self[f].blank? } | ||
| 15 | + errors.add :base, 'You must specify your Hipchat API token and Room ID' | ||
| 16 | + end | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + def create_notification(problem) | ||
| 20 | + url = app_err_url problem.app, problem | ||
| 21 | + message = <<-MSG.strip_heredoc | ||
| 22 | + [#{ERB::Util.html_escape problem.app.name}]#{ERB::Util.html_escape notification_description(problem)}<br> | ||
| 23 | + <a href="#{url}">#{url}</a> | ||
| 24 | + MSG | ||
| 25 | + | ||
| 26 | + client = HipChat::Client.new(api_token) | ||
| 27 | + client[room_id].send('Errbit', message, :color => 'red') | ||
| 28 | + end | ||
| 29 | +end |
app/views/apps/_configuration_instructions.html.haml
| 1 | %pre | 1 | %pre |
| 2 | - %code | ||
| 3 | - :preserve | ||
| 4 | - # Require the hoptoad_notifier gem in your App. | ||
| 5 | - # --------------------------------------------- | ||
| 6 | - # | ||
| 7 | - # Rails 3 - In your Gemfile | ||
| 8 | - # gem 'airbrake' | ||
| 9 | - # | ||
| 10 | - # Rails 2 - In environment.rb | ||
| 11 | - # config.gem 'airbrake' | ||
| 12 | - # | ||
| 13 | - # Then add the following to config/initializers/errbit.rb | ||
| 14 | - # ------------------------------------------------------- | 2 | + %code |
| 3 | + :preserve | ||
| 4 | + # Require the hoptoad_notifier gem in your App. | ||
| 5 | + # --------------------------------------------- | ||
| 6 | + # | ||
| 7 | + # Rails 3 - In your Gemfile | ||
| 8 | + # gem 'airbrake' | ||
| 9 | + # | ||
| 10 | + # Rails 2 - In environment.rb | ||
| 11 | + # config.gem 'airbrake' | ||
| 12 | + # | ||
| 13 | + # Then add the following to config/initializers/errbit.rb | ||
| 14 | + # ------------------------------------------------------- | ||
| 15 | 15 | ||
| 16 | - Airbrake.configure do |config| | ||
| 17 | - config.api_key = '#{app.api_key}' | ||
| 18 | - config.host = '#{request.host}' | ||
| 19 | - config.port = #{request.port} | ||
| 20 | - config.secure = config.port == 443 | ||
| 21 | - end | 16 | + Airbrake.configure do |config| |
| 17 | + config.api_key = '#{app.api_key}' | ||
| 18 | + config.host = '#{request.host}' | ||
| 19 | + config.port = #{request.port} | ||
| 20 | + config.secure = config.port == 443 | ||
| 21 | + end | ||
| 22 | 22 | ||
| 23 | - # Set up Javascript notifications | ||
| 24 | - # ------------------------------- | ||
| 25 | - # | ||
| 26 | - # To receive notifications for javascript errors, | ||
| 27 | - # you should add <%= airbrake_javascript_notifier %> to the top of your layouts. | ||
| 28 | - # | ||
| 29 | - # Testing | ||
| 30 | - # ------- | ||
| 31 | - # | ||
| 32 | - # Rails 2 - you'll need to vendor airbrake to get the rake tasks | ||
| 33 | - # rake gems:unpack GEM=airbrake | ||
| 34 | - # | ||
| 35 | - # Run: | ||
| 36 | - # rake airbrake:test | ||
| 37 | - # refresh this page | 23 | + # Set up Javascript notifications |
| 24 | + # ------------------------------- | ||
| 25 | + # | ||
| 26 | + # To receive notifications for javascript errors, | ||
| 27 | + # you should add <%= airbrake_javascript_notifier %> to the top of your layouts. | ||
| 28 | + # | ||
| 29 | + # Testing | ||
| 30 | + # ------- | ||
| 31 | + # | ||
| 32 | + # Rails 2 - you'll need to vendor airbrake to get the rake tasks | ||
| 33 | + # rake gems:unpack GEM=airbrake | ||
| 34 | + # | ||
| 35 | + # Run: | ||
| 36 | + # rake airbrake:test | ||
| 37 | + # refresh this page | ||
| 38 | 38 |
spec/fabricators/notification_service_fabricator.rb
| @@ -5,6 +5,6 @@ Fabricator :notification_service do | @@ -5,6 +5,6 @@ Fabricator :notification_service do | ||
| 5 | subdomain { sequence :word } | 5 | subdomain { sequence :word } |
| 6 | end | 6 | end |
| 7 | 7 | ||
| 8 | -%w(campfire).each do |t| | 8 | +%w(campfire hipchat).each do |t| |
| 9 | Fabricator "#{t}_notification_service".to_sym, :from => :notification_service, :class_name => "NotificationService::#{t.camelcase}Service" | 9 | Fabricator "#{t}_notification_service".to_sym, :from => :notification_service, :class_name => "NotificationService::#{t.camelcase}Service" |
| 10 | end | 10 | end |
spec/models/notice_observer_spec.rb
| @@ -44,7 +44,7 @@ describe NoticeObserver do | @@ -44,7 +44,7 @@ describe NoticeObserver do | ||
| 44 | end | 44 | end |
| 45 | 45 | ||
| 46 | describe "should send a notification if a notification service is configured" do | 46 | describe "should send a notification if a notification service is configured" do |
| 47 | - let(:app) { app = Fabricate(:app, :email_at_notices => [1], :notification_service => Fabricate(:campfire_notification_service))} | 47 | + let(:app) { Fabricate(:app, :email_at_notices => [1], :notification_service => Fabricate(:campfire_notification_service))} |
| 48 | let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :notices_count => 100)) } | 48 | let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :notices_count => 100)) } |
| 49 | 49 | ||
| 50 | before do | 50 | before do |
| @@ -56,9 +56,6 @@ describe NoticeObserver do | @@ -56,9 +56,6 @@ describe NoticeObserver do | ||
| 56 | end | 56 | end |
| 57 | 57 | ||
| 58 | it "should create a campfire notification" do | 58 | it "should create a campfire notification" do |
| 59 | - err.problem.stub(:notices_count) { 1 } | ||
| 60 | - app.notification_service.stub!(:create_notification).and_return(true) | ||
| 61 | - app.stub!(:notification_recipients => %w('ryan@system88.com')) | ||
| 62 | app.notification_service.should_receive(:create_notification) | 59 | app.notification_service.should_receive(:create_notification) |
| 63 | 60 | ||
| 64 | Notice.create!(:err => err, :message => 'FooError: Too Much Bar', :server_environment => {'environment-name' => 'production'}, | 61 | Notice.create!(:err => err, :message => 'FooError: Too Much Bar', :server_environment => {'environment-name' => 'production'}, |
| @@ -66,4 +63,42 @@ describe NoticeObserver do | @@ -66,4 +63,42 @@ describe NoticeObserver do | ||
| 66 | end | 63 | end |
| 67 | end | 64 | end |
| 68 | 65 | ||
| 66 | + describe "should not send a notification if a notification service is not configured" do | ||
| 67 | + let(:app) { Fabricate(:app, :email_at_notices => [1], :notification_service => Fabricate(:notification_service))} | ||
| 68 | + let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :notices_count => 100)) } | ||
| 69 | + | ||
| 70 | + before do | ||
| 71 | + Errbit::Config.per_app_email_at_notices = true | ||
| 72 | + end | ||
| 73 | + | ||
| 74 | + after do | ||
| 75 | + Errbit::Config.per_app_email_at_notices = false | ||
| 76 | + end | ||
| 77 | + | ||
| 78 | + it "should not create a campfire notification" do | ||
| 79 | + app.notification_service.should_not_receive(:create_notification) | ||
| 80 | + | ||
| 81 | + Notice.create!(:err => err, :message => 'FooError: Too Much Bar', :server_environment => {'environment-name' => 'production'}, | ||
| 82 | + :backtrace => [{ :error => 'Le Broken' }], :notifier => { 'name' => 'Notifier', 'version' => '1', 'url' => 'http://toad.com' }) | ||
| 83 | + end | ||
| 84 | + end | ||
| 85 | + | ||
| 86 | + describe 'hipcat notifications' do | ||
| 87 | + let(:app) { Fabricate(:app, :email_at_notices => [1], :notification_service => Fabricate(:hipchat_notification_service))} | ||
| 88 | + let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :notices_count => 100)) } | ||
| 89 | + | ||
| 90 | + before do | ||
| 91 | + Errbit::Config.per_app_email_at_notices = true | ||
| 92 | + end | ||
| 93 | + | ||
| 94 | + after do | ||
| 95 | + Errbit::Config.per_app_email_at_notices = false | ||
| 96 | + end | ||
| 97 | + | ||
| 98 | + it 'creates a hipchat notification' do | ||
| 99 | + app.notification_service.should_receive(:create_notification) | ||
| 100 | + | ||
| 101 | + Fabricate(:notice, :err => err) | ||
| 102 | + end | ||
| 103 | + end | ||
| 69 | end | 104 | end |
spec/models/notification_service/hipchat_service_spec.rb
0 → 100644
| @@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
| 1 | +require 'spec_helper' | ||
| 2 | + | ||
| 3 | +describe NotificationServices::HipchatService do | ||
| 4 | + let(:service) { Fabricate.build(:hipchat_notification_service) } | ||
| 5 | + let(:problem) { Fabricate(:problem) } | ||
| 6 | + let(:room) { double } | ||
| 7 | + | ||
| 8 | + before do | ||
| 9 | + HipChat::Client.any_instance.stub(:[] => room) | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + it 'sends message' do | ||
| 13 | + room.should_receive(:send) | ||
| 14 | + service.create_notification(problem) | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + it 'escapes html in message' do | ||
| 18 | + service.stub(:notification_description => '<3') | ||
| 19 | + room.should_receive(:send) do |_, message| | ||
| 20 | + message.should_not include('<3') | ||
| 21 | + message.should include('<3') | ||
| 22 | + end | ||
| 23 | + service.create_notification(problem) | ||
| 24 | + end | ||
| 25 | +end |