howler 1.0.0 → 1.1.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.
@@ -6,6 +6,7 @@ PATH
6
6
  connection_pool
7
7
  multi_json
8
8
  redis
9
+ sinatra
9
10
 
10
11
  GEM
11
12
  remote: http://rubygems.org/
@@ -64,5 +65,4 @@ DEPENDENCIES
64
65
  howler!
65
66
  rake
66
67
  rspec
67
- sinatra
68
68
  timecop
@@ -16,8 +16,8 @@ Gem::Specification.new do |gem|
16
16
  gem.add_dependency 'celluloid'
17
17
  gem.add_dependency 'connection_pool'
18
18
  gem.add_dependency 'multi_json'
19
+ gem.add_dependency 'sinatra'
19
20
  gem.add_development_dependency 'rake'
20
- gem.add_development_dependency 'sinatra'
21
21
  gem.add_development_dependency 'rspec'
22
22
  gem.add_development_dependency 'capybara'
23
23
  gem.add_development_dependency 'timecop'
@@ -1,4 +1,6 @@
1
1
  require File.expand_path('../web', __FILE__)
2
2
  require 'multi_json'
3
3
 
4
+ Howler::Config[:path_prefix] = '/'
5
+
4
6
  run Howler::Web
@@ -11,5 +11,9 @@ module Howler
11
11
  'ruby_version' => `ruby -v`.chomp
12
12
  }
13
13
  end
14
+
15
+ def to_s(*)
16
+ "Exception from #{@env['hostname']}\n\n#{backtrace.join("\n")}"
17
+ end
14
18
  end
15
19
  end
@@ -116,7 +116,7 @@ module Howler
116
116
 
117
117
  def notify(message, e)
118
118
  message[:status] = 'notified'
119
- message[:exception] = e
119
+ message[:cause] = e
120
120
  Howler.redis.with {|redis| redis.lpush("notifications", MultiJson.encode(message)) }
121
121
  end
122
122
 
@@ -1,6 +1,6 @@
1
1
  module Howler
2
2
  class Config
3
- WHITELIST = %w(concurrency shutdown_timeout)
3
+ WHITELIST = %w(concurrency shutdown_timeout path_prefix).freeze
4
4
 
5
5
  def self.[](key)
6
6
  Howler.redis.with {|redis| redis.hget("howler:config", key.to_s) }
@@ -1,3 +1,3 @@
1
1
  module Howler
2
- VERSION = %W(1 0 0) .join(".")
2
+ VERSION = %W(1 1 0) .join(".")
3
3
  end
@@ -3,6 +3,8 @@ require_relative ''
3
3
  require 'sinatra/base'
4
4
  require 'erb'
5
5
 
6
+ Howler::Config[:path_prefix] = '/howler/'
7
+
6
8
  module Howler
7
9
  class Web < Sinatra::Base
8
10
  dir = File.dirname(File.expand_path(__FILE__))
@@ -39,6 +41,14 @@ module Howler
39
41
  end
40
42
 
41
43
  helpers do
44
+ def path(item)
45
+ Howler::Config[:path_prefix] + item
46
+ end
47
+
48
+ def h(thing)
49
+ escape_html(thing).gsub("\n", "<br>")
50
+ end
51
+
42
52
  def process_args(args)
43
53
  args.to_s.gsub(/^\[|\]$/, '')
44
54
  end
@@ -2,9 +2,9 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <title>Howler</title>
5
+ <title>Howler Dashboard</title>
6
6
  <meta name="description" content="Monitoring Panel for Howler.">
7
- <link href="/application.css" rel="stylesheet">
8
- <link href="/queues.css" rel="stylesheet">
9
- <link href="/bootstrap.min.css" rel="stylesheet">
7
+ <link href="<%= path 'application.css' %>" rel="stylesheet">
8
+ <link href="<%= path 'queues.css' %>" rel="stylesheet">
9
+ <link href="<%= path 'bootstrap.min.css' %>" rel="stylesheet">
10
10
  </head>
@@ -5,7 +5,7 @@
5
5
  <%= erb(:navigation) %>
6
6
 
7
7
  <footer>
8
- <p>&copy; <%= Time.now.year %></p>
8
+ <p></p>
9
9
  </footer>
10
10
  </body>
11
11
  </html>
@@ -8,15 +8,15 @@
8
8
  </a>
9
9
  <div class="nav-collapse">
10
10
  <ul class="nav">
11
- <li class="item"><a href="/">Howler</a></li>
11
+ <li class="item"><a href="<%= path '' %>/howler">Howler</a></li>
12
12
  <li class="divider-vertical"></li>
13
- <li class="item"><a href="/queues">Queues</a></li>
13
+ <li class="item"><a href="<%= path 'queues' %>">Queues</a></li>
14
14
  <li class="divider-vertical"></li>
15
- <li class="item"><a href="/notifications">Notifications</a></li>
15
+ <li class="item"><a href="<%= path 'notifications' %>">Notifications</a></li>
16
16
  <li class="divider-vertical"></li>
17
- <li class="item"><a href="/statistics">Statistics</a></li>
17
+ <li class="item"><a href="<%= path 'statistics' %>">Statistics</a></li>
18
18
  <li class="divider-vertical"></li>
19
- <li class="item"><a href="/settings">Settings</a></li>
19
+ <li class="item"><a href="<%= path 'settings' %>">Settings</a></li>
20
20
  <li class="divider-vertical"></li>
21
21
  </ul>
22
22
  </div>
@@ -5,7 +5,7 @@
5
5
  <thead>
6
6
  <tr>
7
7
  <th>Message</th>
8
- <th>Notification</th>
8
+ <th>Notification (Cause)</th>
9
9
  <th>Occurred</th>
10
10
  </tr>
11
11
  </thead>
@@ -14,8 +14,8 @@
14
14
  <% @notifications.each do |notification| %>
15
15
  <tr>
16
16
  <td><%= notification['class'] %>.<%= notification['method'] %>(<%= process_args(notification['args']) %>)</td>
17
+ <td class="cause"><%= h notification['cause'] %></td>
17
18
  <td><%= Howler::Util.at(notification['created_at']) %></td>
18
- <td><%= notification['status'] %></td>
19
19
  </tr>
20
20
  <% end %>
21
21
  </tbody>
@@ -9,7 +9,7 @@
9
9
  </div>
10
10
 
11
11
  <footer>
12
- <p>&copy; <%= Time.now.year %></p>
12
+ <p></p>
13
13
  </footer>
14
14
  </body>
15
15
  </html>
@@ -30,7 +30,7 @@
30
30
  </div>
31
31
 
32
32
  <footer>
33
- <p>&copy; <%= Time.now.year %></p>
33
+ <p></p>
34
34
  </footer>
35
35
  </body>
36
36
  </html>
@@ -18,7 +18,7 @@
18
18
  <td><%= queue.created_at %></td>
19
19
  <td><%= queue.success %></td>
20
20
  <td class="error"><%= queue.error %></td>
21
- <td><a href="/queues/<%= queue.id %>">More...</a></td>
21
+ <td><a href="<%= path "queues/#{queue.id}" %>">More...</a></td>
22
22
  </tr>
23
23
  <% end %>
24
24
  </tbody>
@@ -9,7 +9,7 @@
9
9
  </div>
10
10
 
11
11
  <footer>
12
- <p>&copy; <%= Time.now.year %></p>
12
+ <p></p>
13
13
  </footer>
14
14
  </body>
15
15
  </html>
@@ -23,4 +23,12 @@ describe Howler::Message::Notify do
23
23
  subject.env['ruby_version'].should == `ruby -v`.chomp
24
24
  end
25
25
  end
26
+
27
+ describe "#to_s" do
28
+ let!(:subj) { begin; raise subject; rescue Exception => e; e; end}
29
+
30
+ it "should have the allowed attributes" do
31
+ subject.to_s.should == "Exception from #{subject.env['hostname']}\n\n#{subject.backtrace.join("\n")}"
32
+ end
33
+ end
26
34
  end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe Howler::Config do
4
4
  it "should have an attribute white-list" do
5
- Howler::Config::WHITELIST.should == %w(concurrency shutdown_timeout)
5
+ Howler::Config::WHITELIST.should == %w(concurrency shutdown_timeout path_prefix)
6
6
  end
7
7
 
8
8
  describe ".[]" do
@@ -191,8 +191,9 @@ describe "web" do
191
191
  describe "Notifications#index" do
192
192
  describe "when there are notifications" do
193
193
  before do
194
+ @ex = generate_exception
194
195
  [:length, :collect, :max].each_with_index do |method, i|
195
- queue.statistics(Array, method, [i*10]) { raise Howler::Message::Notify.new(generate_exception, :type => method)}
196
+ queue.statistics(Array, method, [i*10]) { raise Howler::Message::Notify.new(@ex, :type => method)}
196
197
  end
197
198
 
198
199
  visit "/notifications"
@@ -208,8 +209,9 @@ describe "web" do
208
209
 
209
210
  within ".table tbody" do
210
211
  page.should have_content(Howler::Util.at(@time))
212
+ page.should have_content(@ex.to_s)
211
213
 
212
- %w(Array.length(0) Array.collect(10) Array.max(20) notified).each do |value|
214
+ %w(Array.length(0) Array.collect(10) Array.max(20)).each do |value|
213
215
  page.should have_content(value)
214
216
  end
215
217
  end
@@ -26,7 +26,6 @@ require 'howler/async'
26
26
  require 'howler/web'
27
27
 
28
28
  Capybara.default_driver = :selenium
29
-
30
29
  Capybara.app = Howler::Web
31
30
 
32
31
  RSpec.configure do |config|
@@ -34,8 +33,9 @@ RSpec.configure do |config|
34
33
 
35
34
  config.before(:each) do
36
35
  Howler.send(:_redis).flushall
37
- Howler::Config.class_eval("@@options={:concurrency => 1}")
38
36
  Howler.stub(:next).with(:id).and_return(123)
37
+ Howler::Config[:concurrency] = 1
38
+ Howler::Config[:path_prefix] = '/'
39
39
  end
40
40
 
41
41
  config.after(:suite) do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: howler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-09 00:00:00.000000000 Z
12
+ date: 2012-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -76,14 +76,14 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: rake
79
+ name: sinatra
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
83
  - - ! '>='
84
84
  - !ruby/object:Gem::Version
85
85
  version: '0'
86
- type: :development
86
+ type: :runtime
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
89
89
  none: false
@@ -92,7 +92,7 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: sinatra
95
+ name: rake
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements: