wackamole 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/bin/setup_indexes +44 -0
- data/bin/wackamole +8 -6
- data/config.ru +18 -0
- data/lib/app.rb +8 -5
- data/lib/controllers/dashboard.rb +13 -1
- data/lib/controllers/features.rb +4 -0
- data/lib/controllers/logs.rb +14 -5
- data/lib/controllers/mission.rb +19 -12
- data/lib/controllers/users.rb +7 -0
- data/lib/helpers/dashboard_helper.rb +7 -7
- data/lib/helpers/logs_helper.rb +29 -12
- data/lib/helpers/mission_helper.rb +21 -7
- data/lib/wackamole.rb +1 -1
- data/lib/wackamole/models/control.rb +45 -22
- data/lib/wackamole/models/log.rb +6 -4
- data/lib/wackamole/models/mission.rb +44 -132
- data/lib/wackamole/models/mole_info.rb +21 -15
- data/lib/wackamole/models/search_filter.rb +25 -11
- data/public/images/browsers_sprite.png +0 -0
- data/public/images/fault_small.png +0 -0
- data/public/images/perf_small.png +0 -0
- data/public/stylesheets/wackamole.css +135 -111
- data/spec/models/log_spec.rb +4 -4
- data/spec/models/mission_spec.rb +13 -192
- data/spec/models/search_filter_spec.rb +37 -9
- data/views/dashboard/_report.erb +2 -2
- data/views/dashboard/index.erb +2 -0
- data/views/features/index.erb +3 -1
- data/views/layout.erb +7 -7
- data/views/logs/_rows.erb +4 -3
- data/views/logs/index.erb +3 -1
- data/views/logs/show.erb +4 -8
- data/views/mission/_report.erb +66 -40
- data/views/mission/index.erb +1 -3
- data/views/mission/refresh_js.erb +5 -2
- data/views/mission/trash.txt +50 -0
- data/views/shared/_filter.erb +8 -9
- data/views/shared/_search.erb +2 -2
- data/views/users/index.erb +3 -1
- metadata +18 -2
data/Rakefile
CHANGED
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
|
-
|
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['
|
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}
|
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 => '
|
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
|
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,
|
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 =
|
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
|
data/lib/controllers/features.rb
CHANGED
@@ -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
|
data/lib/controllers/logs.rb
CHANGED
@@ -2,12 +2,11 @@ module Logs
|
|
2
2
|
|
3
3
|
# ---------------------------------------------------------------------------
|
4
4
|
get "/logs/:page" do
|
5
|
-
page
|
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
|
-
|
47
|
-
|
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
|
data/lib/controllers/mission.rb
CHANGED
@@ -1,27 +1,34 @@
|
|
1
1
|
require 'chronic'
|
2
2
|
|
3
|
-
module Mission
|
4
|
-
|
3
|
+
module Mission
|
5
4
|
# ---------------------------------------------------------------------------
|
6
|
-
get '/
|
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
|
-
|
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
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
data/lib/controllers/users.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
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...
|
data/lib/helpers/logs_helper.rb
CHANGED
@@ -2,18 +2,30 @@ module LogsHelper
|
|
2
2
|
|
3
3
|
helpers do
|
4
4
|
# ---------------------------------------------------------------------------
|
5
|
-
def user_name_for( user_id )
|
6
|
-
|
7
|
-
user[
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
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
|
32
|
+
def assign_class( type, count )
|
23
33
|
clazz = case type
|
24
|
-
when
|
25
|
-
|
26
|
-
when
|
27
|
-
|
28
|
-
|
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
|
|