wackamole 0.0.9 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/History.txt +4 -1
  2. data/README.rdoc +17 -17
  3. data/Rakefile +1 -1
  4. data/bin/wackamole +5 -3
  5. data/lib/app.rb +13 -13
  6. data/lib/controllers/dashboard.rb +7 -2
  7. data/lib/controllers/features.rb +1 -1
  8. data/lib/controllers/logs.rb +20 -1
  9. data/lib/controllers/mission.rb +7 -8
  10. data/lib/controllers/session.rb +0 -1
  11. data/lib/controllers/users.rb +5 -1
  12. data/lib/helpers/dashboard_helper.rb +7 -2
  13. data/lib/helpers/flash_helper.rb +0 -1
  14. data/lib/helpers/main_helper.rb +6 -0
  15. data/lib/helpers/session_helper.rb +9 -6
  16. data/lib/wackamole.rb +1 -1
  17. data/lib/wackamole/models/control.rb +58 -31
  18. data/lib/wackamole/models/feature.rb +1 -1
  19. data/lib/wackamole/models/log.rb +1 -2
  20. data/lib/wackamole/models/mission.rb +49 -46
  21. data/lib/wackamole/models/mole_info.rb +4 -5
  22. data/lib/wackamole/models/search_filter.rb +2 -2
  23. data/lib/wackamole/models/user.rb +1 -1
  24. data/public/stylesheets/wackamole.css +41 -14
  25. data/spec/config/test.yml +4 -3
  26. data/spec/data/fixtures.rb +92 -92
  27. data/spec/spec_helper.rb +2 -1
  28. data/spec/wackamole/models/control_spec.rb +27 -33
  29. data/spec/wackamole/models/feature_spec.rb +19 -20
  30. data/spec/wackamole/models/log_spec.rb +2 -3
  31. data/spec/wackamole/models/mission_spec.rb +16 -18
  32. data/spec/wackamole/models/moled_info_spec.rb +9 -10
  33. data/spec/wackamole/models/search_filter_spec.rb +4 -5
  34. data/spec/wackamole/models/user_spec.rb +2 -3
  35. data/views/features/_rows.erb +1 -1
  36. data/views/layout.erb +18 -26
  37. data/views/logs/show.erb +6 -4
  38. data/views/mission/_report.erb +39 -39
  39. data/views/users/_rows.erb +2 -2
  40. metadata +11 -11
@@ -19,7 +19,7 @@ module Wackamole
19
19
  # ---------------------------------------------------------------------------
20
20
  # Paginate top features
21
21
  def self.paginate_tops( conds, page=1, page_size=default_page_size )
22
- tops = logs_cltn.group( [:fid], conds, { :count => 0 }, 'function(obj,prev) { prev.count += 1}', true )
22
+ tops = logs_cltn.group( [:fid], conds, { :count => 0 }, 'function(obj,prev) { prev.count += 1}' )
23
23
 
24
24
  all_features = features_cltn.find( {}, :fields => [:_id] )
25
25
  feature_ids = all_features.map{ |f| f['_id'] }
@@ -13,8 +13,7 @@ module Wackamole
13
13
 
14
14
  # ---------------------------------------------------------------------------
15
15
  # Fetch all logs matching the given condition
16
- def self.paginate( conds, page=1, page_size=default_page_size )
17
- puts conds.inspect
16
+ def self.paginate( conds, page=1, page_size=default_page_size )
18
17
  matching = logs_cltn.find( conds )
19
18
  WillPaginate::Collection.create( page, page_size, matching.count ) do |pager|
20
19
  pager.replace( logs_cltn.find( conds,
@@ -7,60 +7,63 @@ module Wackamole
7
7
  # -----------------------------------------------------------------------
8
8
  # Pick up moled application pulse
9
9
  def self.pulse( last_tick )
10
- count_to_date = count_logs
11
- count_today = count_logs( last_tick, true )
12
- count_last_tick = count_logs( last_tick )
13
- { :to_date => count_to_date, :today => count_today, :last_tick => count_last_tick }
14
- end
15
-
16
- # -----------------------------------------------------------------------
17
- # generates mole logs conditons
18
- def self.gen_conds( now, single_day )
19
- conds = {}
20
- if now
21
- if single_day
22
- conds = SearchFilter.time_conds( now, 1 )
23
- else
24
- now = now.clone.utc
25
- date_id = now.to_date_id.to_s
26
- time_id = now.to_time_id
27
- conds[:did] = { '$gte' => date_id }
28
- conds[:tid] = { '$gte' => time_id }
10
+ zones = {}
11
+ Wackamole::Control.zones.each do |zone|
12
+ zones[zone] = {}
13
+ Wackamole::Control.mole_databases( zone ).each do |db_name|
14
+ db = Wackamole::Control.db( zone, db_name )
15
+ app_name, env = Wackamole::Control.extract_app_info( db_name )
16
+ logs_cltn = db['logs']
17
+
18
+ zones[zone][app_name] = {} unless zones[zone][app_name]
19
+ zones[zone][app_name][env] = {} unless zones[zone][app_name][env]
20
+
21
+ zones[zone][app_name][env][:to_date] = count_logs( logs_cltn )
22
+ zones[zone][app_name][env][:today] = count_logs( logs_cltn, last_tick, true )
23
+ zones[zone][app_name][env][:last_tick] = count_logs( logs_cltn, last_tick )
29
24
  end
30
25
  end
31
- conds
26
+ zones
32
27
  end
33
-
34
- # -----------------------------------------------------------------------
35
- # Compute mole counts for each moled apps
36
- def self.count_logs( now=nil, single_day=false )
37
- counts = {}
38
- conds = gen_conds( now, single_day )
28
+
29
+ # =========================================================================
30
+ private
39
31
 
40
- Wackamole::Control.mole_databases.each do |db_name|
41
- db = Wackamole::Control.db( db_name )
42
- app_name, env = Wackamole::Control.extract_app_info( db_name )
43
- logs_cltn = db['logs']
44
-
45
- totals = { Rackamole.feature => 0, Rackamole.perf => 0, Rackamole.fault => 0 }
46
- if counts[app_name]
47
- counts[app_name][env] = totals
48
- else
49
- counts[app_name] = { env => totals }
50
- end
51
- row = counts[app_name][env]
32
+ # -----------------------------------------------------------------------
33
+ # Compute mole counts for each moled apps
34
+ def self.count_logs( logs_cltn, now=nil, single_day=false )
35
+ conds = gen_conds( now, single_day )
36
+ # puts conds.inspect
37
+ totals = {
38
+ Rackamole.feature => 0,
39
+ Rackamole.perf => 0,
40
+ Rackamole.fault => 0
41
+ }
52
42
  [Rackamole.feature, Rackamole.perf, Rackamole.fault].each do |t|
53
43
  conds[:typ] = t
54
- logs = logs_cltn.find( conds, :fields => [:_id] )
55
- row[t] = logs.count
44
+ totals[t] = logs_cltn.find( conds, :fields => [:_id] ).count
56
45
  end
46
+ totals
57
47
  end
58
- counts
59
- end
60
-
61
- # =========================================================================
62
- private
63
-
48
+
49
+ # -----------------------------------------------------------------------
50
+ # generates mole logs conditons
51
+ def self.gen_conds( now, single_day )
52
+ conds = {}
53
+ if now
54
+ if single_day
55
+ conds = SearchFilter.time_conds( now, 0 )
56
+ else
57
+ now = now.clone.utc
58
+ date_id = now.to_date_id.to_s
59
+ time_id = now.to_time_id
60
+ conds[:did] = { '$gte' => date_id }
61
+ conds[:tid] = { '$gte' => time_id }
62
+ end
63
+ end
64
+ conds
65
+ end
66
+
64
67
  # -----------------------------------------------------------------------
65
68
  # Map rackamole types to report types
66
69
  def self.to_type_name( type )
@@ -9,7 +9,6 @@ module Wackamole
9
9
 
10
10
  # ---------------------------------------------------------------------------
11
11
  # Collect various data points to power up dashboard
12
- # TODO - PERF - try just using cursor vs to_a
13
12
  def self.collect_dashboard_info( now )
14
13
  info = {}
15
14
 
@@ -20,13 +19,12 @@ module Wackamole
20
19
 
21
20
  # Fetch day logs
22
21
  utc_time = now.clone.utc
23
- puts utc_time
24
22
  conds = SearchFilter.time_conds( now, 0 )
23
+ # puts conds.inspect
25
24
  day_logs = logs_cltn.find( conds,
26
25
  :fields => [:typ, :fid, :tid, :did, :uid],
27
26
  :sort => [ [:tid => Mongo::ASCENDING] ] )
28
- puts conds.inspect
29
- puts day_logs.count
27
+ # puts "Found logs #{day_logs.count}"
30
28
  # Count all logs per hourly time period
31
29
  users = Set.new
32
30
  features = Set.new
@@ -36,7 +34,8 @@ puts day_logs.count
36
34
  user_per_hour = {}
37
35
  day_logs.each do |log|
38
36
  date_tokens = log['did'].match( /(\d{4})(\d{2})(\d{2})/ ).captures
39
- time_tokens = log['tid'].match( /(\d{2})(\d{2})(\d{2})/ ).captures
37
+ time_tokens = log['tid'].match( /(\d{2})(\d{2})(\d{2})/ ).captures
38
+ # puts "#{log['did']} - #{log['tid']} - #{log['uid']}"
40
39
  log_utc = Time.utc( date_tokens[0], date_tokens[1], date_tokens[2], time_tokens[0], time_tokens[1], time_tokens[2] )
41
40
  local = log_utc.clone.localtime
42
41
  hour = local.hour
@@ -141,7 +141,7 @@ module Wackamole
141
141
  to_utc = Time.local( local_now.year, local_now.month, local_now.day, 23, 59, 59 ).utc
142
142
 
143
143
  from_date_id = from_utc.to_date_id.to_s
144
- to_date_id = to_utc.to_date_id.to_s
144
+ to_date_id = to_utc.to_date_id.to_s
145
145
 
146
146
  if from_date_id != to_date_id
147
147
  from_time_id = from_utc.to_time_id.to_s
@@ -151,7 +151,7 @@ module Wackamole
151
151
  conds[:did] = to_date_id
152
152
  end
153
153
  else
154
- date = Chronic.parse( "#{days == 1 ? "now" : "#{days} days ago"}" )
154
+ date = Chronic.parse( "#{days == 0 ? "now" : "#{days} days ago"}" )
155
155
  current = "%4d/%02d/%02d %02d:%02d:%02d" % [date.year, date.month, date.day, current_hour, 0, 1]
156
156
  time = Chronic.parse( current ).utc
157
157
  conds[:did] = { '$gte' => time.to_date_id.to_s }
@@ -12,7 +12,7 @@ module Wackamole
12
12
  # ---------------------------------------------------------------------------
13
13
  # Find all users matching criteria and returns pagination collection
14
14
  def self.paginate_tops( conds, page=1, page_size=default_page_size )
15
- tops = logs_cltn.group( [:uid], conds, { :count => 0 }, 'function(obj,prev) { prev.count += 1}', true )
15
+ tops = logs_cltn.group( [:uid], conds, { :count => 0 }, 'function(obj,prev) { prev.count += 1}' )
16
16
  users = []
17
17
  tops.sort{ |a,b| b['count'] <=> a['count'] }.each do |row|
18
18
  users << { :uid => row['uid'], :total => row['count'].to_i, :details => [] }
@@ -32,6 +32,17 @@ div#logo {
32
32
  margin-bottom: 5px;
33
33
  }
34
34
 
35
+ span#version {
36
+ position: relative;
37
+ top: -12px;
38
+ left: 32px;
39
+ font-weight: bold;
40
+ color: #316071;
41
+ }
42
+ a.logout {
43
+ font-size: 0.8em;
44
+ }
45
+
35
46
  div#main {
36
47
  clear: both;
37
48
  margin: 40px 10px 10px 20px;
@@ -63,6 +74,17 @@ div#navigation {
63
74
  background: #c1c1c1 url(../images/fade.png) repeat-x;
64
75
  }
65
76
 
77
+ a.nav_link {
78
+ color: #646464;
79
+ font-weight: bold;
80
+ text-decoration: none;
81
+ }
82
+ a.nav_link:hover {
83
+ color : #1779ff;
84
+ border-bottom: 1px #1779ff solid;
85
+ text-decoration: none;
86
+ }
87
+
66
88
  a.site_link {
67
89
  color: #646464;
68
90
  font-weight: bold;
@@ -80,26 +102,31 @@ a.current {
80
102
  border-bottom: 5px #646464 solid;
81
103
  }
82
104
 
83
- div#app_info {
105
+ div#links {
84
106
  text-align: right;
85
- font-size: 2em;
86
107
  }
87
- div#app_info li {
88
- color:#3968ff;
108
+ div#links p {
109
+ text-align: right;
110
+ margin-top: 5px;
89
111
  }
90
- div#app_info li span {
91
- color:#666;
112
+ span#timestamp {
92
113
  }
93
- div#app_info li#env {
94
- color: #c1c1c1;
95
- font-size: 0.5em;
96
- font-style: italic;
114
+
115
+ ul#app_info {
116
+ font-size: 1.5em;
117
+ margin-top: 10px;
97
118
  }
98
- div#app_info p {
99
- text-align: right;
100
- font-size: 1.0em;
119
+ ul#app_info li {
101
120
  }
102
- span#timestamp {
121
+ ul#app_info span.zone {
122
+ color: #fe9500;
123
+ }
124
+ ul#app_info span.app {
125
+ color: #666;
126
+ }
127
+ ul#app_info span.stage {
128
+ color: #a1bf6d;
129
+ font-style: italic;
103
130
  }
104
131
 
105
132
  #header {
@@ -1,3 +1,4 @@
1
- test:
2
- host: localhost
3
- port: 27099
1
+ zones:
2
+ test:
3
+ host: localhost
4
+ port: 27099
@@ -1,92 +1,92 @@
1
- require 'rackamole'
2
-
3
- class Fixtures
4
-
5
- def self.test_time_id() @test_time ||= 20100101; end
6
-
7
- def self.load_data
8
- puts "Loading fixture data..."
9
- Wackamole::Control.init_config( File.join(File.dirname(__FILE__), %w[.. config test.yml]), 'test' )
10
- load_test_dbs
11
- load_bogus_dbs
12
- end
13
-
14
- def self.load_test_dbs
15
- con = Wackamole::Control.connection
16
- %w[development test production].each{ |env| create_valid_mole_db( con, "fred", env) }
17
- end
18
-
19
- def self.load_bogus_dbs
20
- con = Wackamole::Control.connection
21
- %w[mole_blee_mdb zorg_blee_dev_mdb].each do |db_name|
22
- create_db( con, db_name )
23
- end
24
- # create mole db with wrong cltns
25
- # BOZO !! An empty db does not show up?
26
- db = create_db( con, "mole_zorg_wrong_mdb" )
27
- %w[features1 logs1 users1].each { |cltn| db.drop_collection( cltn );db.create_collection( cltn ) }
28
- # missing cltn
29
- db = create_db( con, "mole_zorg_missing_mdb" )
30
- %w[features logs].each { |cltn| db.drop_collection( cltn );db.create_collection( cltn ) }
31
- end
32
-
33
- def self.create_db( con, db_name )
34
- # if con.database_names.include?( db_name )
35
- # con.drop_database( db_name )
36
- # end
37
- con.db( db_name, :strict => true )
38
- end
39
-
40
- def self.create_valid_mole_db( con, app_name, env )
41
- db_name = "mole_#{app_name}_#{env}_mdb"
42
- db = create_db( con, db_name )
43
- %w[users features logs].each do |cltn_name|
44
- db.drop_collection( cltn_name )
45
- cltn = db.create_collection( cltn_name ) # :capped => false, :size => 1_000_000, :limit => 100 )
46
- case cltn_name
47
- when 'users' : populate_users( cltn, app_name, env )
48
- when 'features' : populate_features( cltn, app_name, env )
49
- when 'logs' : populate_logs( cltn, app_name, env )
50
- end
51
- end
52
- end
53
-
54
- def self.populate_users( cltn, app_name, env )
55
- 10.times do |i|
56
- cltn.insert( { :una => "blee_#{i}@#{app_name}.#{env}", :did => test_time_id.to_s } )
57
- end
58
- end
59
-
60
- def self.populate_features( cltn, app_name, env )
61
- 10.times do |i|
62
- cltn.insert( { :env => env, :app => app_name, :did => test_time_id.to_s, :ctx => "feature_#{i}" } )
63
- end
64
- end
65
-
66
- def self.populate_logs( cltn, app_name, env )
67
- features = cltn.db['features'].find( {} ).to_a
68
- users = cltn.db['users'].find( {} ).to_a
69
- [Rackamole.feature, Rackamole.perf, Rackamole.fault].each do |type|
70
- 5.times do |i|
71
- cltn.insert({
72
- :typ => type,
73
- :fid => features[i]['_id'],
74
- :uid => users[i]['_id'],
75
- :did => test_time_id.to_s,
76
- :tid => "070000",
77
- :ip => "127.0.0.#{i}"
78
- })
79
- end
80
- 2.times do |i|
81
- cltn.insert({
82
- :typ => type,
83
- :fid => features[5+i]['_id'],
84
- :uid => users[5+i]['_id'],
85
- :did => test_time_id.to_s,
86
- :tid => "080000",
87
- :ip => "127.0.0.#{i}"
88
- })
89
- end
90
- end
91
- end
92
- end
1
+ # require 'rackamole'
2
+ #
3
+ # class Fixtures
4
+ #
5
+ # def self.test_time_id() @test_time ||= 20100101; end
6
+ #
7
+ # def self.load_data
8
+ # puts "Loading fixture data..."
9
+ # Wackamole::Control.init_config( File.join(File.dirname(__FILE__), %w[.. config test.yml]), 'test' )
10
+ # load_test_dbs
11
+ # load_bogus_dbs
12
+ # end
13
+ #
14
+ # def self.load_test_dbs
15
+ # con = Wackamole::Control.connection( 'test' )
16
+ # %w[development test production].each{ |env| create_valid_mole_db( con, "fred", env) }
17
+ # end
18
+ #
19
+ # def self.load_bogus_dbs
20
+ # con = Wackamole::Control.connection( 'test' )
21
+ # %w[mole_blee_mdb zorg_blee_dev_mdb].each do |db_name|
22
+ # create_db( con, db_name )
23
+ # end
24
+ # # create mole db with wrong cltns
25
+ # # BOZO !! An empty db does not show up?
26
+ # db = create_db( con, "mole_zorg_wrong_mdb" )
27
+ # %w[features1 logs1 users1].each { |cltn| db.drop_collection( cltn );db.create_collection( cltn ) }
28
+ # # missing cltn
29
+ # db = create_db( con, "mole_zorg_missing_mdb" )
30
+ # %w[features logs].each { |cltn| db.drop_collection( cltn );db.create_collection( cltn ) }
31
+ # end
32
+ #
33
+ # def self.create_db( con, db_name )
34
+ # # if con.database_names.include?( db_name )
35
+ # # con.drop_database( db_name )
36
+ # # end
37
+ # con.db( db_name, :strict => true )
38
+ # end
39
+ #
40
+ # def self.create_valid_mole_db( con, app_name, env )
41
+ # db_name = "mole_#{app_name}_#{env}_mdb"
42
+ # db = create_db( con, db_name )
43
+ # %w[users features logs].each do |cltn_name|
44
+ # db.drop_collection( cltn_name )
45
+ # cltn = db.create_collection( cltn_name ) # :capped => false, :size => 1_000_000, :limit => 100 )
46
+ # case cltn_name
47
+ # when 'users' : populate_users( cltn, app_name, env )
48
+ # when 'features' : populate_features( cltn, app_name, env )
49
+ # when 'logs' : populate_logs( cltn, app_name, env )
50
+ # end
51
+ # end
52
+ # end
53
+ #
54
+ # def self.populate_users( cltn, app_name, env )
55
+ # 10.times do |i|
56
+ # cltn.insert( { :una => "blee_#{i}@#{app_name}.#{env}", :did => test_time_id.to_s } )
57
+ # end
58
+ # end
59
+ #
60
+ # def self.populate_features( cltn, app_name, env )
61
+ # 10.times do |i|
62
+ # cltn.insert( { :env => env, :app => app_name, :did => test_time_id.to_s, :ctx => "feature_#{i}" } )
63
+ # end
64
+ # end
65
+ #
66
+ # def self.populate_logs( cltn, app_name, env )
67
+ # features = cltn.db['features'].find( {} ).to_a
68
+ # users = cltn.db['users'].find( {} ).to_a
69
+ # [Rackamole.feature, Rackamole.perf, Rackamole.fault].each do |type|
70
+ # 5.times do |i|
71
+ # cltn.insert({
72
+ # :typ => type,
73
+ # :fid => features[i]['_id'],
74
+ # :uid => users[i]['_id'],
75
+ # :did => test_time_id.to_s,
76
+ # :tid => "070000",
77
+ # :ip => "127.0.0.#{i}"
78
+ # })
79
+ # end
80
+ # 2.times do |i|
81
+ # cltn.insert({
82
+ # :typ => type,
83
+ # :fid => features[5+i]['_id'],
84
+ # :uid => users[5+i]['_id'],
85
+ # :did => test_time_id.to_s,
86
+ # :tid => "080000",
87
+ # :ip => "127.0.0.#{i}"
88
+ # })
89
+ # end
90
+ # end
91
+ # end
92
+ # end