wackamole 0.0.3 → 0.0.4
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.
- 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
@@ -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[
|
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[
|
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 = "
|
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[
|
109
|
-
conds[
|
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 = "
|
141
|
+
@filter.search_terms = "browser:name:duh"
|
114
142
|
conds = @filter.to_conds
|
115
143
|
conds.should have(2).items
|
116
|
-
conds['
|
117
|
-
conds['
|
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
|
data/views/dashboard/_report.erb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="section" id="summary">
|
2
|
-
<p class="title">
|
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">
|
23
|
+
<p class="title">day summary</p>
|
24
24
|
<ul class="section">
|
25
25
|
<li>
|
26
26
|
<p id="faults">Faults</p>
|
data/views/dashboard/index.erb
CHANGED
data/views/features/index.erb
CHANGED
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
|
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:
|
15
|
-
<%= link_to image_tag( 'wackamole_logo.png', :border => 0 ), '/
|
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>&
|
20
|
+
<li>«<span><%=@app_info[:app_name]%></span>»</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", "/
|
29
|
+
<div id='navigation' class='corners'>
|
30
|
+
<%=link_to "mission control", "/" , :class => "site_link land" %> •
|
31
31
|
<%=link_to "dashboard" , "/dashboard/#{@app_info[:app_name]}/#{@app_info[:stage]}", :class => "site_link dash" %> •
|
32
32
|
<%=link_to "logs" , "/logs/1" , :class => "site_link logs" %> •
|
33
33
|
<%=link_to "features" , "/features/1" , :class => "site_link features" %> •
|
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"
|
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
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
|
-
<
|
4
|
-
|
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>
|
data/views/mission/_report.erb
CHANGED
@@ -1,49 +1,75 @@
|
|
1
|
-
|
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
|
-
|
9
|
-
<
|
10
|
-
<
|
11
|
-
|
12
|
-
<
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
<
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
+
<%= format_number(count) %>
|
59
|
+
</span>
|
60
|
+
</td>
|
61
|
+
<!-- < if period == 'last_tick' %>
|
62
|
+
<td width="5px" class="<=clazz%>"> </td>
|
63
|
+
< end %> -->
|
64
|
+
</tr>
|
65
|
+
<% end %>
|
66
|
+
</tbody>
|
67
|
+
</table>
|
68
|
+
</td>
|
42
69
|
<% end %>
|
43
|
-
|
44
|
-
|
45
|
-
</div>
|
70
|
+
</tr>
|
71
|
+
<% end %>
|
46
72
|
<% end %>
|
47
|
-
</
|
48
|
-
|
73
|
+
</tbody>
|
74
|
+
</table>
|
49
75
|
<% end %>
|
data/views/mission/index.erb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
-
$('
|
1
|
+
$('span#timestamp').html( "<%=escape_javascript(partial(:'shared/timestamp'))%>" );
|
2
|
+
$("span#timestamp").effect( 'pulsate', { times:1 }, 500 );
|
2
3
|
|
3
|
-
$('div#
|
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
|
+
‹<%= delta?( diff ) %>›
|
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 %>
|
data/views/shared/_filter.erb
CHANGED
@@ -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
|
-
|
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
|
+
|
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
|
|
data/views/shared/_search.erb
CHANGED
@@ -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="
|
4
|
-
<%= image_tag 'loading.gif', :border => 0, :size => "
|
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>
|