wackamole 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Rakefile +1 -0
  2. data/bin/setup_indexes +44 -0
  3. data/bin/wackamole +8 -6
  4. data/config.ru +18 -0
  5. data/lib/app.rb +8 -5
  6. data/lib/controllers/dashboard.rb +13 -1
  7. data/lib/controllers/features.rb +4 -0
  8. data/lib/controllers/logs.rb +14 -5
  9. data/lib/controllers/mission.rb +19 -12
  10. data/lib/controllers/users.rb +7 -0
  11. data/lib/helpers/dashboard_helper.rb +7 -7
  12. data/lib/helpers/logs_helper.rb +29 -12
  13. data/lib/helpers/mission_helper.rb +21 -7
  14. data/lib/wackamole.rb +1 -1
  15. data/lib/wackamole/models/control.rb +45 -22
  16. data/lib/wackamole/models/log.rb +6 -4
  17. data/lib/wackamole/models/mission.rb +44 -132
  18. data/lib/wackamole/models/mole_info.rb +21 -15
  19. data/lib/wackamole/models/search_filter.rb +25 -11
  20. data/public/images/browsers_sprite.png +0 -0
  21. data/public/images/fault_small.png +0 -0
  22. data/public/images/perf_small.png +0 -0
  23. data/public/stylesheets/wackamole.css +135 -111
  24. data/spec/models/log_spec.rb +4 -4
  25. data/spec/models/mission_spec.rb +13 -192
  26. data/spec/models/search_filter_spec.rb +37 -9
  27. data/views/dashboard/_report.erb +2 -2
  28. data/views/dashboard/index.erb +2 -0
  29. data/views/features/index.erb +3 -1
  30. data/views/layout.erb +7 -7
  31. data/views/logs/_rows.erb +4 -3
  32. data/views/logs/index.erb +3 -1
  33. data/views/logs/show.erb +4 -8
  34. data/views/mission/_report.erb +66 -40
  35. data/views/mission/index.erb +1 -3
  36. data/views/mission/refresh_js.erb +5 -2
  37. data/views/mission/trash.txt +50 -0
  38. data/views/shared/_filter.erb +8 -9
  39. data/views/shared/_search.erb +2 -2
  40. data/views/users/index.erb +3 -1
  41. metadata +18 -2
data/Rakefile CHANGED
@@ -37,6 +37,7 @@ depend_on "mongo_rack" , ">= 0.0.1"
37
37
  depend_on "main" , ">= 4.2.0"
38
38
  depend_on "sinatra" , ">= 0.9.4"
39
39
  depend_on "mongo_rack" , ">= 0.0.3"
40
+ depend_on "rackamole" , ">= 0.0.3"
40
41
 
41
42
  # Rake
42
43
  task :default => ['fixtures:load','spec:run']
data/bin/setup_indexes ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'main'
4
+ require 'mongo'
5
+ require File.expand_path( File.join(File.dirname(__FILE__), %w[.. lib wackamole]))
6
+
7
+ Main {
8
+ option('reset', 'r') {
9
+ default false
10
+ description "Reset all indexes"
11
+ }
12
+
13
+ option('set', 's') {
14
+ default false
15
+ description "Set all indexes"
16
+ }
17
+
18
+ option('clear', 'c') {
19
+ default false
20
+ description "Clear all indexes"
21
+ }
22
+
23
+ option( 'verbose', 'v') {
24
+ default false
25
+ description "Show verbose information"
26
+ }
27
+
28
+ environment( 'WACKAMOLE_ENV' ) {
29
+ default 'production'
30
+ description 'Wackamole env to choose from in landscape yml'
31
+ }
32
+
33
+ # Enter main loop
34
+ def run
35
+ config_file = File.join( ENV['HOME'], %w[.wackamole wackamole.yml] )
36
+ Wackamole::Control.init_config( config_file, params['WACKAMOLE_ENV'].value )
37
+ Wackamole::Control.ensure_indexes!(
38
+ params[:set].value,
39
+ params[:reset].value,
40
+ params[:verbose].value,
41
+ params[:clear].value
42
+ )
43
+ end
44
+ }
data/bin/wackamole CHANGED
@@ -9,8 +9,10 @@ Main {
9
9
  validate { |pool| pool =~ URI_MATCH }
10
10
  description "specify session server uri. Must be of the form {[mongo|memcache]}://{host}:{port}/{[database_name|namespace]}[/{collection_name}]"
11
11
  }
12
- environment( 'RACK_ENV' ) {
12
+ option( 'environment', 'e' ) {
13
+ argument :required
13
14
  default 'production'
15
+ description 'Specifies the env to run wackamole in'
14
16
  }
15
17
 
16
18
  @@options = {}
@@ -18,9 +20,9 @@ Main {
18
20
  # Enter main loop
19
21
  def run
20
22
  require File.expand_path( File.join(File.dirname(__FILE__), %w[.. lib wackamole]))
21
-
23
+
22
24
  @@options = parse_args( params[:pool].value )
23
- ENV['RACK_ENV'] = params['RACK_ENV'].value
25
+ ENV['RACK_ENV'] = params['environment'].value
24
26
 
25
27
  Thread.new do
26
28
  puts "-"*100
@@ -33,19 +35,19 @@ Main {
33
35
  puts "\n"*2
34
36
  puts ">>> Opening console..."
35
37
  puts "\n"*2
36
- open( "http://localhost:#{default_port}/mission" )
38
+ open( "http://localhost:#{default_port}" )
37
39
  end
38
40
 
39
41
  # Clearing args for franky!
40
42
  ARGV.clear
41
43
  require 'sinatra'
42
44
  require File.join(File.dirname(__FILE__), %w[.. lib app.rb])
43
- Sinatra::Application.run! :port => default_port, :environment => 'production'
45
+ Sinatra::Application.run! :port => default_port, :environment => params['environment'].value
44
46
  end
45
47
 
46
48
  # default wackamole port
47
49
  def default_port() 7777; end
48
-
50
+
49
51
  # sleepy time...
50
52
  def sleep_time() 3; end
51
53
 
data/config.ru ADDED
@@ -0,0 +1,18 @@
1
+ #------------
2
+ # Wackamole Sessions Options
3
+ #
4
+ # @@options defines where Wackamole puts its sessions, which can be either mongo or memcache
5
+ # if @@options is not defined mongo at localhost:27017 is used
6
+ #
7
+ # For customized sessions with Mongo uncomment and modify this line:
8
+ # @@options={:protocol=>"mongo", :host=>"localhost", :port=>"11211", :db_name=>"wackamole_session", :cltn_name=>"sessions"}
9
+ #
10
+ # For Memcache session uncomment and modify this line:
11
+ # @@options={:protocol=>"memcached", :host=>"localhost", :port=>"11211", :namespace=>"wackamole_session"}
12
+ #
13
+ #------------
14
+
15
+ require 'rubygems'
16
+ require 'sinatra'
17
+ require File.join(File.dirname(__FILE__), %w[lib app.rb])
18
+ run Sinatra::Application
data/lib/app.rb CHANGED
@@ -24,6 +24,7 @@ end
24
24
 
25
25
  configure do
26
26
  set :sessions, false
27
+ set :logging, true
27
28
 
28
29
  Wackamole.load_all_libs_relative_to(__FILE__, 'helpers' )
29
30
  Wackamole.load_all_libs_relative_to(__FILE__, 'controllers' )
@@ -32,7 +33,8 @@ configure do
32
33
  if defined? @@options and @@options
33
34
  if @@options[:protocol] == 'mongo'
34
35
  use Rack::Session::Mongo,
35
- :server => "%s:%d/%s/%s" % [@@options[:host], @@options[:port], @@options[:db_name], @@options[:cltn_name]]
36
+ :server => "%s:%d/%s/%s" % [@@options[:host], @@options[:port], @@options[:db_name], @@options[:cltn_name]],
37
+ :log_level => :debug
36
38
  else
37
39
  use Rack::Session::Memcache,
38
40
  :memcache_server => "%s:%d" % [@@options[:host], @@options[:port]],
@@ -40,7 +42,9 @@ configure do
40
42
  end
41
43
  else
42
44
  # Default is a mongo session store
43
- use Rack::Session::Mongo, :server => "%s:%d/%s/%s" % ['localhost', '27017', 'wackamole_ses', 'sessions']
45
+ use Rack::Session::Mongo,
46
+ :server => "%s:%d/%s/%s" % ['localhost', '27017', 'wackamole_ses', 'sessions'],
47
+ :log_level => :error
44
48
  end
45
49
  set :con, Wackamole::Control.init_config( default_config, Sinatra::Application.environment.to_s )
46
50
  end
@@ -55,13 +59,12 @@ before do
55
59
  session[:filter] = @filter
56
60
  end
57
61
  @updated_on = Time.now
58
- @refresh_rate = 60
59
-
62
+ @refresh_rate = 30
60
63
  @app_info = session[:app_info]
61
64
  begin
62
65
  Wackamole::Control.switch_mole_db!( @app_info[:app_name].downcase, @app_info[:stage] ) if @app_info
63
66
  rescue => boom
64
- puts boom
67
+ $stderr.puts boom
65
68
  @app_info = nil
66
69
  session[:app_info] = nil
67
70
  end
@@ -8,7 +8,6 @@ module Dashboard
8
8
  get '/dashboard/:app_name/:stage' do
9
9
  Wackamole::Control.switch_mole_db!( params[:app_name].downcase, params[:stage] )
10
10
 
11
- ensure_indexes!
12
11
  load_app_details
13
12
 
14
13
  # Reset app info
@@ -27,4 +26,17 @@ module Dashboard
27
26
  erb :'dashboard/refresh_js', :layout => false
28
27
  end
29
28
 
29
+ # ---------------------------------------------------------------------------
30
+ get '/dashboard/logs/:app_name/:stage/:type' do
31
+ Wackamole::Control.switch_mole_db!( params[:app_name].downcase, params[:stage] )
32
+ load_app_details
33
+ load_app_info
34
+
35
+ filter = Wackamole::SearchFilter.new
36
+ filter.mole_type( params[:type].to_i )
37
+ puts "SETTING FILTER", filter.inspect
38
+ session[:filter] = filter
39
+ redirect '/logs/1'
40
+ end
41
+
30
42
  end
@@ -5,6 +5,8 @@ module Features
5
5
  get "/features/:page" do
6
6
  page = params[:page] ? params[:page].to_i : 1
7
7
 
8
+ puts @filter.inspect
9
+
8
10
  @features = Wackamole::Feature.paginate_tops( @filter.to_conds, page )
9
11
  @search_path = "/features/search"
10
12
  @filter_path = "/features/filter"
@@ -35,6 +37,8 @@ module Features
35
37
  # Filter
36
38
  post "/features/filter" do
37
39
  @filter.from_options( params[:filter] )
40
+ session[:filter] = @filter
41
+ puts "Setting #{session[:filter].inspect}"
38
42
  @features = Wackamole::Feature.paginate_tops( @filter.to_conds )
39
43
  erb :"features/filter.js", :layout => false
40
44
  end
@@ -2,12 +2,11 @@ module Logs
2
2
 
3
3
  # ---------------------------------------------------------------------------
4
4
  get "/logs/:page" do
5
- page = params[:page] ? params[:page].to_i : 1
6
-
5
+ page = params[:page] ? params[:page].to_i : 1
7
6
  @logs = Wackamole::Log.paginate( @filter.to_conds, page)
8
7
  @search_path = "/logs/search"
9
8
  @filter_path = "/logs/filter"
10
-
9
+
11
10
  if request.xhr?
12
11
  erb :'logs/index.js', :layout => false
13
12
  else
@@ -43,7 +42,17 @@ module Logs
43
42
  @filter = Wackamole::SearchFilter.new
44
43
  @filter.from_options( params[:filter] )
45
44
  session[:filter] = @filter
46
- @logs = Wackamole::Log.paginate( @filter.to_conds )
47
- erb :"logs/filter.js", :layout => false
45
+
46
+ # elapsed = Benchmark.realtime do
47
+ @logs = Wackamole::Log.paginate( @filter.to_conds )
48
+ # end
49
+ # puts "Filter logs %5.4f" % elapsed
50
+
51
+ out = nil
52
+ # elapsed = Benchmark.realtime do
53
+ out = erb :"logs/filter.js", :layout => false
54
+ # end
55
+ # puts "Render logs %5.4f" % elapsed
56
+ out
48
57
  end
49
58
  end
@@ -1,27 +1,34 @@
1
1
  require 'chronic'
2
2
 
3
- module Mission
4
-
3
+ module Mission
5
4
  # ---------------------------------------------------------------------------
6
- get '/mission' do
5
+ get '/' do
7
6
  # reset app info
8
7
  session[:app_info] = @app_info = nil
8
+
9
+ last_tick = session[:last_tick]
10
+ last_tick ||= Chronic.parse( "#{@refresh_rate} seconds ago" )
11
+ session[:last_tick] = Time.now
9
12
 
10
- load_report
13
+ @pulse = Wackamole::Mission.pulse( last_tick.utc )
14
+
11
15
  erb :'mission/index'
12
16
  end
13
17
 
14
18
  # ---------------------------------------------------------------------------
15
19
  get '/mission/refresh' do
16
- load_report
20
+ last_tick = session[:last_tick]
21
+ last_tick ||= Chronic.parse( "#{@refresh_rate} seconds ago" )
22
+ session[:last_tick] = Time.now
23
+
24
+ @pulse = Wackamole::Mission.pulse( last_tick.utc )
25
+
17
26
  erb :'/mission/refresh_js', :layout => false
18
27
  end
19
28
 
20
- # ---------------------------------------------------------------------------
21
- get '/mission/fixed/:app/:env/:type' do
22
- Wackamole::Mission.reset!( params[:app], params[:env], params[:type] )
23
- load_report
24
- erb :'/mission/refresh_js', :layout => false
25
- end
26
-
29
+ # # ---------------------------------------------------------------------------
30
+ # get '/mission/fixed/:app/:env/:type' do
31
+ # Wackamole::Mission.reset!( params[:app], params[:env], params[:type] )
32
+ # erb :'/mission/refresh_js', :layout => false
33
+ # end
27
34
  end
@@ -5,7 +5,12 @@ module Users
5
5
  get "/users/:page" do
6
6
  page = params[:page] ? params[:page].to_i : 1
7
7
 
8
+ puts "User filter", @filter.inspect
9
+ elapsed = Benchmark.realtime do
8
10
  @users = Wackamole::User.paginate_tops( @filter.to_conds, page )
11
+ end
12
+ puts "Find users %5.4f" % elapsed
13
+
9
14
  @search_path = "/users/search"
10
15
  @filter_path = "/users/filter"
11
16
 
@@ -35,6 +40,8 @@ module Users
35
40
  # Filter
36
41
  post "/users/filter" do
37
42
  @filter.from_options( params[:filter] )
43
+ session[:filter] = @filter
44
+ puts "Setting user filter #{session[:filter].inspect}"
38
45
  @users = Wackamole::User.paginate_tops( @filter.to_conds )
39
46
  erb :"users/filter.js", :layout => false
40
47
  end
@@ -2,13 +2,13 @@ module DashboardHelper
2
2
 
3
3
  helpers do
4
4
 
5
- # -------------------------------------------------------------------------
6
- # Make sure all indexes are set
7
- def ensure_indexes!
8
- Wackamole::Log.ensure_indexes!
9
- Wackamole::User.ensure_indexes!
10
- Wackamole::Feature.ensure_indexes!
11
- end
5
+ # # -------------------------------------------------------------------------
6
+ # # Make sure all indexes are set
7
+ # def ensure_indexes!
8
+ # Wackamole::Log.ensure_indexes!
9
+ # Wackamole::User.ensure_indexes!
10
+ # Wackamole::Feature.ensure_indexes!
11
+ # end
12
12
 
13
13
  # -------------------------------------------------------------------------
14
14
  # Retrieve moled app info...
@@ -2,18 +2,30 @@ module LogsHelper
2
2
 
3
3
  helpers do
4
4
  # ---------------------------------------------------------------------------
5
- def user_name_for( user_id )
6
- user = Wackamole::User.users_cltn.find_one( user_id )
7
- user['una']
5
+ def user_name_for( ctx, user_id )
6
+ return ctx[user_id] if ctx[user_id]
7
+ user = Wackamole::User.users_cltn.find_one( user_id, :fields => [:una] )
8
+ value = user['una']
9
+ ctx[user_id] = value
10
+ value
8
11
  end
9
12
 
10
13
  # ---------------------------------------------------------------------------
11
14
  # Find feature context for log entry
12
- def context_for( feature_id )
13
- feature = Wackamole::Feature.features_cltn.find_one( feature_id )
14
- return "Unknown" unless feature
15
- return "#{feature['ctl']}##{feature['act']}" if feature['ctl']
16
- feature['ctx']
15
+ def context_for( ctx, feature_id )
16
+ return ctx[feature_id] if ctx[feature_id]
17
+ feature = Wackamole::Feature.features_cltn.find_one( feature_id, :fields => [:ctl, :act, :ctx] )
18
+ if feature
19
+ if feature['ctl']
20
+ value = "#{feature['ctl']}##{feature['act']}"
21
+ else
22
+ value = feature['ctx']
23
+ end
24
+ else
25
+ value = "Unknown"
26
+ end
27
+ ctx[feature_id] = value
28
+ value
17
29
  end
18
30
 
19
31
  # ---------------------------------------------------------------------------
@@ -97,10 +109,15 @@ module LogsHelper
97
109
 
98
110
  # ---------------------------------------------------------------------------
99
111
  # Setup browser icon indicator
100
- def browser_icon( browser )
101
- img_name = browser
102
- img_name = "unknown_browser" if img_name.nil? or img_name == "N/A"
103
- image_tag "browsers/#{img_name.to_s.downcase.gsub( /\\/, '')}.png", :size => "20x20"
112
+ def browser_class( browser )
113
+ class_name = browser['name'].downcase
114
+ if class_name == 'msie'
115
+ version = browser['version'].match( /(\d)\.\d/ ).captures.first
116
+ class_name = "ie_#{version.to_s}"
117
+ elsif class_name == "n/a"
118
+ class_name = 'unknown'
119
+ end
120
+ class_name
104
121
  end
105
122
  end
106
123
  end
@@ -1,6 +1,12 @@
1
1
  module MissionHelper
2
2
  helpers do
3
3
 
4
+ def extract_applications( pulse )
5
+ apps = OrderedHash.new
6
+ pulse[:to_date].keys.sort.each { |app_name| apps[app_name] = pulse[:to_date][app_name].keys.sort }
7
+ apps
8
+ end
9
+
4
10
  # -------------------------------------------------------------------------
5
11
  def load_report
6
12
  @old_reports = Wackamole::Mission.find( {}, :sort => [ [:app, Mongo::ASCENDING], [:env, Mongo::ASCENDING] ] ).to_a
@@ -8,7 +14,11 @@ module MissionHelper
8
14
  reset = last_tick.nil?
9
15
  last_tick = last_tick || Chronic.parse( '1 minute ago' )
10
16
  session[:last_tick] = Time.now
11
- @reports = Wackamole::Mission.rollups( last_tick.utc, reset )
17
+
18
+ elapsed = Benchmark.realtime do
19
+ @reports = Wackamole::Mission.rollups( last_tick.utc, reset )
20
+ end
21
+ puts "Rollups %5.4f" % elapsed
12
22
  end
13
23
 
14
24
  # -------------------------------------------------------------------------
@@ -19,13 +29,17 @@ module MissionHelper
19
29
 
20
30
  # -------------------------------------------------------------------------
21
31
  # Assign status fg for application
22
- def assign_class( type, count, diff )
32
+ def assign_class( type, count )
23
33
  clazz = case type
24
- when "faults" : (diff > 0 ? "fault" : "")
25
- when "perfs" : (diff > 0 ? "perf" : "")
26
- when "features" : (diff > 0 ? "active" : "inactive")
27
- else ""
28
- end
34
+ when Rackamole.fault
35
+ (count > 0 ? "fault" : "")
36
+ when Rackamole.perf
37
+ (count > 0 ? "perf" : "")
38
+ when Rackamole.feature
39
+ (count > 0 ? "feature" : "" )
40
+ else
41
+ ""
42
+ end
29
43
  clazz
30
44
  end
31
45