Commit 5633d2ede1dccf411329c3674c1dd14b782de2fe

Authored by Shuky Dvir
2 parents d99b857e 35cdcd35
Exists in master and in 1 other branch production

Merge branch 'master' of https://github.com/errbit/errbit

Conflicts:
	Gemfile
	app/models/notice_observer.rb
	spec/fabricators/notification_service_fabricator.rb
Gemfile
... ... @@ -34,6 +34,7 @@ gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data
34 34 gem 'rails_autolink', '~> 1.0.9'
35 35 gem 'campy'
36 36 gem 'xmpp4r'
  37 +gem 'hipchat'
37 38  
38 39 # Please don't update this to airbrake - We override the send_notice method
39 40 # to handle internal errors.
... ...
Gemfile.lock
... ... @@ -97,10 +97,15 @@ GEM
97 97 hashie (1.2.0)
98 98 highline (1.6.13)
99 99 hike (1.2.1)
  100 + hipchat (0.4.1)
  101 + httparty
100 102 hoptoad_notifier (2.4.11)
101 103 activesupport
102 104 builder
103 105 htmlentities (4.3.1)
  106 + httparty (0.9.0)
  107 + multi_json (~> 1.0)
  108 + multi_xml
104 109 httpauth (0.1)
105 110 i18n (0.6.1)
106 111 inherited_resources (1.3.1)
... ... @@ -144,6 +149,7 @@ GEM
144 149 rails (>= 3.0.0)
145 150 railties (>= 3.0.0)
146 151 multi_json (1.3.6)
  152 + multi_xml (0.5.1)
147 153 multipart-post (1.1.5)
148 154 net-scp (1.0.4)
149 155 net-ssh (>= 1.99.1)
... ... @@ -310,6 +316,7 @@ DEPENDENCIES
310 316 execjs
311 317 fabrication (~> 1.3.0)
312 318 haml
  319 + hipchat
313 320 hoptoad_notifier (~> 2.4)
314 321 htmlentities (~> 4.3.0)
315 322 inherited_resources
... ...
README.md
... ... @@ -150,9 +150,6 @@ git clone http://github.com/errbit/errbit.git
150 150 gem install heroku
151 151 heroku create example-errbit --stack cedar
152 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 153 heroku addons:add sendgrid:starter
157 154 heroku config:add HEROKU=true
158 155 heroku config:add ERRBIT_HOST=some-hostname.example.com
... ...
app/assets/images/hipchat_create.png 0 → 100644

2.05 KB

app/assets/images/hipchat_goto.png 0 → 100644

2.05 KB

app/assets/images/hipchat_inactive.png 0 → 100644

1.16 KB

app/models/notice_observer.rb
... ... @@ -2,10 +2,8 @@ class NoticeObserver < Mongoid::Observer
2 2 observe :notice
3 3  
4 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 7 notice.app.notification_service.create_notification(notice.problem)
10 8 end
11 9  
... ...
app/models/notification_service.rb
1 1 class NotificationService
2 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 7 field :room_id, :type => String
5 8 field :api_token, :type => String
6 9 field :subdomain, :type => String
... ...
app/models/notification_services/hipchat_service.rb 0 → 100644
... ... @@ -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 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 5 subdomain { sequence :word }
6 6 end
7 7  
8   -%w(campfire gtalk).each do |t|
  8 +%w(campfire gtalk hipchat).each do |t|
9 9 Fabricator "#{t}_notification_service".to_sym, :from => :notification_service, :class_name => "NotificationService::#{t.camelcase}Service"
10 10 end
... ...
spec/models/notice_observer_spec.rb
... ... @@ -44,7 +44,7 @@ describe NoticeObserver do
44 44 end
45 45  
46 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 48 let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :notices_count => 100)) }
49 49  
50 50 before do
... ... @@ -56,9 +56,6 @@ describe NoticeObserver do
56 56 end
57 57  
58 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 59 app.notification_service.should_receive(:create_notification)
63 60  
64 61 Notice.create!(:err => err, :message => 'FooError: Too Much Bar', :server_environment => {'environment-name' => 'production'},
... ... @@ -66,4 +63,42 @@ describe NoticeObserver do
66 63 end
67 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 104 end
... ...
spec/models/notification_service/hipchat_service_spec.rb 0 → 100644
... ... @@ -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('&lt;3')
  22 + end
  23 + service.create_notification(problem)
  24 + end
  25 +end
... ...