Permalink
Browse files

Merge branch 'master' of https://github.com/boblail/errbit into bobla…

…il_master

Conflicts:
	Gemfile
	Gemfile.lock
	app/models/notice.rb
	app/views/notices/_environment.html.haml
	app/views/notices/_summary.html.haml
	spec/models/notice_spec.rb
  • Loading branch information...
oruen committed May 3, 2011
2 parents 217069e + 567d7e9 commit 005eaf224602e154cd1d233c084597802d100d3c
View
@@ -9,6 +9,7 @@ gem 'devise', '~> 1.1.8'
gem 'lighthouse-api'
gem 'redmine_client', :git => "git://github.com/oruen/redmine_client.git"
gem 'mongoid_rails_migrations'
+gem 'useragent', '~> 0.3.1'
platform :ruby do
gem 'bson_ext', '~> 1.2'
View
@@ -114,6 +114,7 @@ GEM
treetop (1.4.9)
polyglot (>= 0.3.1)
tzinfo (0.3.26)
+ useragent (0.3.1)
warden (1.0.3)
rack (>= 1.0.0)
webmock (1.6.2)
@@ -138,5 +139,6 @@ DEPENDENCIES
redmine_client!
rspec (~> 2.5)
rspec-rails (~> 2.5)
+ useragent (~> 0.3.1)
webmock
will_paginate
@@ -4,7 +4,8 @@ class NoticesController < ApplicationController
skip_before_filter :authenticate_user!, :only => :create
def create
- @notice = Notice.from_xml(request.raw_post)
+ # params[:data] if the notice came from a GET request, raw_post if it came via POST
+ @notice = Notice.from_xml(params[:data] || request.raw_post)
respond_with @notice
end
@@ -1,5 +1,45 @@
module ApplicationHelper
+
+
def lighthouse_tracker? object
object.issue_tracker_type == "lighthouseapp"
end
+
+
+ def user_agent_graph(error)
+ tallies = tally(error.notices) {|notice| pretty_user_agent(notice.user_agent)}
+ create_percentage_table(tallies, :total => error.notices.count)
+ end
+
+ def pretty_user_agent(user_agent)
+ (user_agent.nil? || user_agent.none?) ? "N/A" : "#{user_agent.browser} #{user_agent.version}"
+ end
+
+
+ def tally(collection, &block)
+ collection.inject({}) do |tallies, item|
+ value = yield item
+ tallies[value] = (tallies[value] || 0) + 1
+ tallies
+ end
+ end
+
+
+ def create_percentage_table(tallies, options={})
+ total = (options[:total] || total_from_tallies(tallies))
+ percent = 100.0 / total.to_f
+ rows = tallies.map {|value, count| [(count.to_f * percent), value]} \
+ .sort {|a, b| a[0] <=> b[0]}
+ render :partial => "errs/tally_table", :locals => {:rows => rows}
+ end
+
+
+private
+
+
+ def total_from_tallies(tallies)
+ tallies.values.inject(0) {|sum, n| sum + n}
+ end
+
+
end
View
@@ -51,6 +51,11 @@ def self.from_xml(hoptoad_xml)
})
end
+ def user_agent
+ agent_string = env_vars['HTTP_USER_AGENT']
+ agent_string.blank? ? nil : UserAgent.parse(agent_string)
+ end
+
def request
read_attribute(:request) || {}
end
@@ -11,7 +11,7 @@
- errs.each do |err|
%tr{:class => err.resolved? ? 'resolved' : 'unresolved'}
%td.app
- = err.app.name
+ = link_to err.app.name, app_path(err.app)
%span.environment= err.environment
%td.message
= link_to err.message, app_err_path(err.app, err)
@@ -0,0 +1,5 @@
+%table.tally
+ - rows.each do |row|
+ %tr
+ %td.percent= number_to_percentage(row[0], :precision => 1)
+ %th.value= row[1]
@@ -1,6 +1,6 @@
.window
%table.environment
- - notice.env_vars.each do |key,val|
+ - notice.env_vars.sort_by {|pair| pair[0]}.each do |pair|
%tr
- %th= raw key
- %td.main= val
+ %th= pair[0]
+ %td.main= pair[1]
@@ -15,4 +15,7 @@
%td= notice.created_at.to_s(:micro)
%tr
%th Similar
- %td= notice.err.notices_count - 1
+ %td= notice.err.notices.count - 1
+ %tr
+ %th Browser
+ %td= user_agent_graph(notice.err)
@@ -562,7 +562,7 @@ table.errs td.app .environment {
table.errs td.message a {
width: 420px;
display: block;
- word-wrap: break-word;
+ word-wrap: break-word;
}
table.errs td.message em {
color: #727272;
@@ -574,6 +574,27 @@ table.errs tr.resolved td > * {
-webkit-opacity: 0.5;
}
+/* Tally tables */
+table.tally {
+ border:none;
+}
+table.tally td,
+table.tally th {
+ border:none !important;
+ background:none !important;
+ padding:8px 0 0;
+}
+table.tally tbody tr:first-child td,
+table.tally tbody tr:first-child th {
+ padding-top:0;
+}
+table.tally td.percent {
+ width:4.5em;
+}
+table.tally th.value {
+ text-transform:none;
+}
+
/* Resolve Errs */
#action-bar a.resolve {
background: transparent url(images/icons/thumbs-up.png) 6px 5px no-repeat;
@@ -2,7 +2,7 @@
describe NoticesController do
- context 'POST[XML] notices#create' do
+ context 'notices API' do
before do
@xml = Rails.root.join('spec','fixtures','hoptoad_test_notice.xml').read
@app = Factory(:app_with_watcher)
@@ -11,15 +11,21 @@
request.env['Content-type'] = 'text/xml'
request.env['Accept'] = 'text/xml, application/xml'
- request.should_receive(:raw_post).and_return(@xml)
end
- it "generates a notice from the xml" do
+ it "generates a notice from xml [POST]" do
Notice.should_receive(:from_xml).with(@xml).and_return(@notice)
+ request.should_receive(:raw_post).and_return(@xml)
post :create
end
+ it "generates a notice from xml [GET]" do
+ Notice.should_receive(:from_xml).with(@xml).and_return(@notice)
+ get :create, {:data => @xml}
+ end
+
it "sends a notification email" do
+ request.should_receive(:raw_post).and_return(@xml)
post :create
email = ActionMailer::Base.deliveries.last
email.to.should include(@app.watchers.first.email)
View
@@ -119,6 +119,19 @@
end
end
+ describe "user agent" do
+ it "should be parsed and human-readable" do
+ notice = Factory.build(:notice, :request => {'cgi-data' => {'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16'}})
+ notice.user_agent.browser.should == 'Chrome'
+ notice.user_agent.version.to_s.should =~ /^10\.0/
+ end
+
+ it "should be nil if HTTP_USER_AGENT is blank" do
+ notice = Factory.build(:notice)
+ notice.user_agent.should == nil
+ end
+ end
+
describe "email notifications" do
before do
@app = Factory(:app_with_watcher)

0 comments on commit 005eaf2

Please sign in to comment.