wackamole 0.0.9 → 0.1.2

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.
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