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
@@ -20,6 +20,22 @@ describe Wackamole::SearchFilter do
20
20
  @filter.reset!
21
21
  check_filter( @filter, "today", "All", "", -1)
22
22
  end
23
+
24
+ it "should retrieve the correct feature context" do
25
+ @filter.context_for( {'ctx' => "/blee/fred" } ).should == "/blee/fred"
26
+ @filter.context_for( {'ctl' => "blee", 'act' => "fred" } ).should == "blee#fred"
27
+ end
28
+
29
+ it "should retrieve the correct start date" do
30
+ @filter.from_date_id.should_not be_nil
31
+ end
32
+
33
+ it "should map id to type correctly" do
34
+ types = %w( Feature Perf Fault )
35
+ [0,1,2].each do |t|
36
+ @filter.send( :to_filter_type, t ).should == types[t]
37
+ end
38
+ end
23
39
 
24
40
  describe "series" do
25
41
  it "should generate the correct time_ids" do
@@ -59,7 +75,7 @@ describe Wackamole::SearchFilter do
59
75
  conds.should have(2).items
60
76
  conds.key?( :did ).should == true
61
77
  conds[:did].should == { "$gte" => @now.to_date_id.to_s }
62
- conds[:bro].should == "Safari"
78
+ conds['bro.name'].should == "Safari"
63
79
  end
64
80
 
65
81
  it "should include mole type is specfied" do
@@ -70,7 +86,7 @@ describe Wackamole::SearchFilter do
70
86
  conds.should have(3).items
71
87
  conds.key?( :did ).should == true
72
88
  conds[:did].should == { "$gte" => @now.to_date_id.to_s }
73
- conds[:bro].should == "Safari"
89
+ conds['bro.name'].should == "Safari"
74
90
  conds[:typ].should == Rackamole.feature
75
91
  end
76
92
 
@@ -91,6 +107,18 @@ describe Wackamole::SearchFilter do
91
107
  Wackamole::Control.db( "mole_fred_test_mdb" )
92
108
  end
93
109
 
110
+ it "should retrieve features correctly" do
111
+ features = @filter.features
112
+ features.should have(11).items
113
+ count = 0
114
+ features.each do |f|
115
+ f.should have(2).items
116
+ f.first.should == "All" if count == 0
117
+ f.first.should == "feature_#{count-1}" if count > 0
118
+ count += 1
119
+ end
120
+ end
121
+
94
122
  it "should include user if specified" do
95
123
  @filter.search_terms = "user:blee_0@fred.test"
96
124
  conds = @filter.to_conds
@@ -102,19 +130,19 @@ describe Wackamole::SearchFilter do
102
130
  end
103
131
 
104
132
  it "should include an adoc regexp if specified" do
105
- @filter.search_terms = "key:blee"
106
- conds = @filter.to_conds
133
+ @filter.search_terms = "host:blee"
134
+ conds = @filter.to_conds
107
135
  conds.should have(2).items
108
- conds['key'].should_not be_nil
109
- conds['key'].should == /blee/
136
+ conds[:hos].should_not be_nil
137
+ conds[:hos].should == /blee/
110
138
  end
111
139
 
112
140
  it "should include an adoc regexp if specified" do
113
- @filter.search_terms = "key:blee:duh"
141
+ @filter.search_terms = "browser:name:duh"
114
142
  conds = @filter.to_conds
115
143
  conds.should have(2).items
116
- conds['key.blee'].should_not be_nil
117
- conds['key.blee'].should == /duh/
144
+ conds['bro.name'].should_not be_nil
145
+ conds['bro.name'].should == /duh/
118
146
  end
119
147
 
120
148
  it "should raise an exception is search exp cannot be parsed" do
@@ -1,5 +1,5 @@
1
1
  <div class="section" id="summary">
2
- <p class="title">Current status</p>
2
+ <p class="title">this hour</p>
3
3
  <ul id="summary">
4
4
  <li>
5
5
  <p class="status">Users</p>
@@ -20,7 +20,7 @@
20
20
  </div>
21
21
 
22
22
  <div class="section" id="activity">
23
- <p class="title">Today's activities</p>
23
+ <p class="title">day summary</p>
24
24
  <ul class="section">
25
25
  <li>
26
26
  <p id="faults">Faults</p>
@@ -1,3 +1,5 @@
1
+ <%= javascripts %w[raphael.min g.raphael.min g.dot.min] %>
2
+
1
3
  <div id="dash">
2
4
  <%= partial :'dashboard/report' %>
3
5
  </div>
@@ -1,6 +1,8 @@
1
+ <%= javascripts %w[jquery.example] %>
2
+
1
3
  <%= partial :'shared/filter' %>
2
4
 
3
- <div id="features">
5
+ <div id="features" class="spe_corners">
4
6
  <%= partial :'features/rows' %>
5
7
  </div>
6
8
 
data/views/layout.erb CHANGED
@@ -6,28 +6,28 @@
6
6
  <link rel="icon" href="/images/small_logo.png" type="image/x-icon"/>
7
7
  <link rel="shortcut icon" href="/images/small_logo.png" type="image/x-icon"/>
8
8
  <%= stylesheets %w[wackamole] %>
9
- <%= javascripts %w[jquery_min jquery_ui_min jquery.tools.min jquery.example application raphael.min g.raphael.min g.dot.min] %>
9
+ <%= javascripts %w[jquery_min jquery_ui_min] %>
10
10
  </head>
11
11
 
12
12
  <body id="body">
13
13
  <div id="overall">
14
- <div id="logo" style="margin-bottom:50px">
15
- <%= link_to image_tag( 'wackamole_logo.png', :border => 0 ), '/mission' %>
14
+ <div id="logo" style="margin-bottom:5px">
15
+ <%= link_to image_tag( 'wackamole_logo.png', :border => 0 ), '/' %>
16
16
  </div>
17
17
  <div id="app_info">
18
18
  <% if @app_info %>
19
19
  <ul>
20
- <li>&lt;<%=@app_info[:app_name]%>&gt;</li>
20
+ <li>&laquo;<span><%=@app_info[:app_name]%></span>&raquo;</li>
21
21
  <li id="env"><%=@app_info[:stage]%></li>
22
22
  <ul>
23
23
  <% end %>
24
- <p id="timestamp"><%=partial :'shared/timestamp'%></p>
24
+ <p><span id="timestamp"><%=partial :'shared/timestamp'%></span></p>
25
25
  </div>
26
26
  <div id="main">
27
27
  <div class="flash"></div>
28
28
  <% if @app_info %>
29
- <div id='navigation'>
30
- <%=link_to "mission control", "/mission" , :class => "site_link land" %>&nbsp;&bull;&nbsp;
29
+ <div id='navigation' class='corners'>
30
+ <%=link_to "mission control", "/" , :class => "site_link land" %>&nbsp;&bull;&nbsp;
31
31
  <%=link_to "dashboard" , "/dashboard/#{@app_info[:app_name]}/#{@app_info[:stage]}", :class => "site_link dash" %>&nbsp;&bull;&nbsp;
32
32
  <%=link_to "logs" , "/logs/1" , :class => "site_link logs" %>&nbsp;&bull;&nbsp;
33
33
  <%=link_to "features" , "/features/1" , :class => "site_link features" %>&nbsp;&bull;&nbsp;
data/views/logs/_rows.erb CHANGED
@@ -2,6 +2,7 @@
2
2
  <%= page_entries_info @logs, :entry_name => 'log' %>
3
3
  </div>
4
4
 
5
+ <% users={}; contexts={} %>
5
6
  <div id="content">
6
7
  <table class="logs">
7
8
  <thead>
@@ -17,14 +18,14 @@
17
18
  <tbody>
18
19
  <% count=0;@logs.each do |log| %>
19
20
  <tr class="<%=row_class_for log['typ'] %>" href="<%="/logs/#{log['_id']}/show"%>" rel='#details'>
20
- <td><%=context_for log['fid'] %></td>
21
+ <td><%=context_for( contexts, log['fid']) %></td>
21
22
  <td><%=log['met']%></td>
22
- <td><%=truncate( user_name_for( log['uid'] ), 30 )%></td>
23
+ <td><%=truncate( user_name_for( users, log['uid'] ), 30 )%></td>
23
24
  <td><%=log['ip']%></td>
24
25
  <td><%=format_host( log['hos'] )%></td>
25
26
  <td><%=timestamp_for log %></td>
26
27
  <td align="right"><%=request_time( log['rti'] )%></td>
27
- <td align="right"><%=browser_icon( log['bro']['name'] )%></td>
28
+ <td align="right"><div class="browser <%=browser_class( log['bro'])%>"></div></td>
28
29
  </tr>
29
30
  <% count+=1;end %>
30
31
  </body>
data/views/logs/index.erb CHANGED
@@ -1,8 +1,10 @@
1
+ <%= javascripts %w[jquery.example jquery.tools.min] %>
2
+
1
3
  <div id="filter">
2
4
  <%= partial :'shared/filter' %>
3
5
  </div>
4
6
 
5
- <div id="logs">
7
+ <div id="logs" class="spe_corners">
6
8
  <%= partial :'logs/rows' %>
7
9
  </div>
8
10
 
data/views/logs/show.erb CHANGED
@@ -1,11 +1,7 @@
1
1
  <p id="info">
2
- <%=image_tag mole_type_icon( @log['typ'] ), :border => 0 %>
3
- <p class="title" id="type">
4
- <%=human_type @log['typ'] %>
5
- </p>
6
- <p class="title" id="feature">
7
- <%=context_for @log['fid'] %>
8
- </p>
2
+ <%=image_tag mole_type_icon( @log['typ'] ), :border => 0, :class => "info", :size => "35x35" %>
3
+ <span id="type"><%=human_type @log['typ'] %></span>
4
+ <span id="feature"><%=context_for( {}, @log['fid'] ) %></span>
9
5
  </p>
10
6
 
11
7
  <div id="info">
@@ -19,7 +15,7 @@
19
15
  <% end %>
20
16
  <tr>
21
17
  <td class="label">User</td>
22
- <td><%=user_name_for @log['uid'] %></td>
18
+ <td><%=user_name_for( {}, @log['uid'] ) %></td>
23
19
  </tr>
24
20
  <tr>
25
21
  <td class="label">Method</td>
@@ -1,49 +1,75 @@
1
- <% if @reports.count == 0 %>
1
+ <style>
2
+ table#mission {
3
+ width: 100%;
4
+ border: 1;
5
+ text-align: left;
6
+ min-height: 500px;
7
+ }
8
+ table#mission thead tr {
9
+ font-size: 1.2em;
10
+ color: #808080;
11
+ }
12
+ table#mission tr.div {
13
+ border-bottom: 1px #c1c1c1 solid;
14
+ }
15
+ </style>
16
+
17
+ <% applications = extract_applications( @pulse ) %>
18
+ <% if applications.count == 0 %>
2
19
  <div class="doh">
3
20
  <p>Unable to find a Rackamole MongoDb database on this connection <%=Wackamole::Control.connection.host%>:<%=Wackamole::Control.connection.port%>.</p>
4
21
  <p>Make sure you moled database follows this naming convention</p>
5
22
  <p>mole_{<i>application name in lower case</i>}_{<i>environment</i>}_mdb</p>
6
23
  </div>
7
24
  <% else %>
8
- <% @reports.each do |report| %>
9
- <div class="mission">
10
- <p class="app_name"><%= report['app'] %></p>
11
- <% report['envs'].keys.sort.each do |env| %>
12
- <div class="environment">
13
- <div class="env">
14
- <%= link_to env, "/dashboard/#{report['app']}/#{env}", :class => 'site_link app_link' %>
15
- </div>
16
- <div class="details">
17
- <table border='0' width="100%">
18
- <% report['envs'][env].each do |type, count| %>
19
- <% diff = compute_diff( report['app'], env, type, count )%>
20
- <tr>
21
- <td class="<%=assign_class( type, count, diff )%>" align="left">
22
- <%=type.capitalize %>
23
- </td>
24
- <td>
25
- <%=count%>
26
- </td>
27
- <td>
28
- &lsaquo;<%= delta?( diff ) %>&rsaquo;
29
- </td>
30
- <% if type != 'features' and count > 0%>
31
- <td align='right'>
32
- <%= link_to_remote 'fixed',
33
- "/mission/fixed/#{report['app']}/#{env}/#{type}",
34
- :class => "fixed" %>
35
- </td>
36
- <% else %>
37
- <td>
38
- <p style="width:30px"></p>
39
- </td>
40
- <% end %>
41
- </tr>
25
+ <table class="logs" id="mission">
26
+ <thead>
27
+ <tr>
28
+ <th width="25%">application</th>
29
+ <th width="10%">environment</th>
30
+ <th width="20%">to date</th>
31
+ <th width="20%">today</th>
32
+ <th width="20%">last tick</th>
33
+ </tr>
34
+ </thead>
35
+ <tbody>
36
+ <% applications.each_pair do |app_name, envs| %>
37
+ <% envs.each do |env| %>
38
+ <tr class="div">
39
+ <td valign="top"><%= link_to app_name, "/dashboard/#{app_name}/#{env}", :class => 'site_link' %></td>
40
+ <td valign="top"><%= env %></td>
41
+ <% %w(to_date today last_tick).each do |period| %>
42
+ <% info = @pulse[period.to_sym][app_name][env] %>
43
+ <td>
44
+ <table border="0" width="100%">
45
+ <tbody>
46
+ <% info.each_pair do |type, count| %>
47
+ <tr>
48
+ <% clazz = ( (count > 0 and %w(last_tick today).include?(period)) ? assign_class( type, count ) : nil) %>
49
+ <td width="25px">
50
+ <% if( %w(last_tick today).include?( period ) and count > 0 ) %>
51
+ <%= link_to Wackamole::Mission.to_type_name(type), "/dashboard/logs/#{app_name}/#{env}/#{type}", :class => "site_link" %>:
52
+ <% else %>
53
+ <%=Wackamole::Mission.to_type_name(type)%>:
54
+ <% end %>
55
+ </td>
56
+ <td align='right'>
57
+ <span class="<%= (clazz and count > 0 ? "#{period}_#{clazz}" : '') %>">
58
+ &nbsp;<%= format_number(count) %>&nbsp;
59
+ </span>
60
+ </td>
61
+ <!-- < if period == 'last_tick' %>
62
+ <td width="5px" class="<=clazz%>">&nbsp;&nbsp;</td>
63
+ < end %> -->
64
+ </tr>
65
+ <% end %>
66
+ </tbody>
67
+ </table>
68
+ </td>
42
69
  <% end %>
43
- </table>
44
- </div>
45
- </div>
70
+ </tr>
71
+ <% end %>
46
72
  <% end %>
47
- </div>
48
- <% end %>
73
+ </tbody>
74
+ </table>
49
75
  <% end %>
@@ -1,6 +1,4 @@
1
- <p class="title">Mission Control</p>
2
-
3
- <div id="dash">
1
+ <div id="mission">
4
2
  <%= partial :'mission/report' %>
5
3
  </div>
6
4
 
@@ -1,3 +1,6 @@
1
- $('p#timestamp').html( "<%=escape_javascript(partial(:'shared/timestamp'))%>" );
1
+ $('span#timestamp').html( "<%=escape_javascript(partial(:'shared/timestamp'))%>" );
2
+ $("span#timestamp").effect( 'pulsate', { times:1 }, 500 );
2
3
 
3
- $('div#dash').html( "<%=escape_javascript(partial(:'mission/report'))%>" );
4
+ $('div#mission').html( "<%=escape_javascript(partial(:'mission/report'))%>" );
5
+
6
+ $("span.last_tick_fault" ).effect( 'shake', { times: 3, distance: 5, direction: 'left' }, 300 );
@@ -0,0 +1,50 @@
1
+ <% applications = extract_applications( @pulse ) %>
2
+ <% if applications.count == 0 %>
3
+ <div class="doh">
4
+ <p>Unable to find a Rackamole MongoDb database on this connection <%=Wackamole::Control.connection.host%>:<%=Wackamole::Control.connection.port%>.</p>
5
+ <p>Make sure you moled database follows this naming convention</p>
6
+ <p>mole_{<i>application name in lower case</i>}_{<i>environment</i>}_mdb</p>
7
+ </div>
8
+ <% else %>
9
+ <% @.each do |report| %>
10
+ <div class="mission">
11
+ <p class="app_name"><%= report['app'] %></p>
12
+ <% report['envs'].keys.sort.each do |env| %>
13
+ <div class="environment">
14
+ <div class="env">
15
+ <%= link_to env, "/dashboard/#{report['app']}/#{env}", :class => 'site_link app_link' %>
16
+ </div>
17
+ <div class="details">
18
+ <table border='0' width="100%">
19
+ <% report['envs'][env].each do |type, count| %>
20
+ <% diff = compute_diff( report['app'], env, type, count )%>
21
+ <tr>
22
+ <td class="<%=assign_class( type, count, diff )%>" align="left">
23
+ <%=type.capitalize %>
24
+ </td>
25
+ <td>
26
+ <%=count%>
27
+ </td>
28
+ <td>
29
+ &lsaquo;<%= delta?( diff ) %>&rsaquo;
30
+ </td>
31
+ <% if type != 'features' and count > 0%>
32
+ <td align='right'>
33
+ <%= link_to_remote 'fixed',
34
+ "/mission/fixed/#{report['app']}/#{env}/#{type}",
35
+ :class => "fixed" %>
36
+ </td>
37
+ <% else %>
38
+ <td>
39
+ <p style="width:30px"></p>
40
+ </td>
41
+ <% end %>
42
+ </tr>
43
+ <% end %>
44
+ </table>
45
+ </div>
46
+ </div>
47
+ <% end %>
48
+ </div>
49
+ <% end %>
50
+ <% end %>
@@ -1,13 +1,5 @@
1
- <div id="filters">
1
+ <div id="filters" class="corners">
2
2
  <form id="filter_form">
3
- <fieldset id="submit">
4
- <label>
5
- &nbsp;
6
- <input type="submit" name="commit" value="Filter"/>
7
- <%= image_tag 'loading.gif', :border => '0', :size => '24x24', :id => 'loading' %>
8
- </label>
9
- </fieldset>
10
-
11
3
  <fieldset class="inline">
12
4
  <label for="time_frame">
13
5
  Time range:
@@ -43,6 +35,13 @@
43
35
  </select>
44
36
  </label>
45
37
  </fieldset>
38
+ <fieldset id="submit">
39
+ <label>
40
+ &nbsp;
41
+ <input type="submit" name="commit" value="Filter"/>
42
+ <%= image_tag 'loading.gif', :border => '0', :size => '24x24', :id => 'loading' %>
43
+ </label>
44
+ </fieldset>
46
45
  </form>
47
46
  </div>
48
47
 
@@ -1,7 +1,7 @@
1
1
  <div id="search">
2
2
  <form id="search_form">
3
- <input id="search_term" class="search" type="text" size="30" name="search_filter[search_terms]"/>
4
- <%= image_tag 'loading.gif', :border => 0, :size => "22x22", :id => "search_loader" %>
3
+ <input id="search_term" class="search" type="text" size="50" name="search_filter[search_terms]"/>
4
+ <%= image_tag 'loading.gif', :border => 0, :size => "20x20", :id => "search_loader" %>
5
5
  <input type="submit" value="Search" style="display: none;" name="commit"/>
6
6
  </form>
7
7
  </div>