Skip to content
Newer
Older
100644 378 lines (281 sloc) 12.4 KB
d2895d1 @flyerhzm update README
authored Jun 21, 2012
1 h1. Bullet
1ae66a8 @flyerhzm revert to README.textile
authored Aug 29, 2009
2
f67503c @flyerhzm fix travis build result in README
authored Mar 8, 2012
3 !https://secure.travis-ci.org/flyerhzm/bullet.png!:http://travis-ci.org/flyerhzm/bullet
7250d00 @flyerhzm add travis-ci support
authored Dec 13, 2011
4
d2895d1 @flyerhzm update README
authored Jun 21, 2012
5 !http://api.coderwall.com/flyerhzm/endorsecount.png!:http://coderwall.com/flyerhzm
6
d1e0543 @flyerhzm update README to tell that bullet already support mongoid
authored May 9, 2012
7 The Bullet gem is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you're using eager loading that isn't necessary and when you should use counter cache.
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
8
9 Best practice is to use Bullet in development mode or custom mode (staging, profile, etc.). The last thing you want is your clients getting alerts about how lazy you are.
10
d1e0543 @flyerhzm update README to tell that bullet already support mongoid
authored May 9, 2012
11 The Bullet gem now supports **activerecord** 2.1, 2.2, 2.3, 3.0, 3.1, 3.2 and **mongoid** >= 2.4.1.
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
12
13 ****************************************************************************
14
93e8aba @flyerhzm update README
authored Aug 10, 2012
15 h2. External Introduction
16
17 * "http://railscasts.com/episodes/372-bullet":http://railscasts.com/episodes/372-bullet
18 * "http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009":http://ruby5.envylabs.com/episodes/9-episode-8-september-8-2009
19 * "http://railslab.newrelic.com/2009/10/23/episode-19-on-the-edge-part-1":http://railslab.newrelic.com/2009/10/23/episode-19-on-the-edge-part-1
20 * "http://weblog.rubyonrails.org/2009/10/22/community-highlights":http://weblog.rubyonrails.org/2009/10/22/community-highlights
21
22 ****************************************************************************
23
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
24 h2. Install
25
26 You can install it as a gem:
0792670 @flyerhzm change gem source from github to gemcutter in README
authored Oct 8, 2009
27 <pre><code>
8335fac @flyerhzm update documents
authored Nov 19, 2010
28 gem install bullet
0792670 @flyerhzm change gem source from github to gemcutter in README
authored Oct 8, 2009
29 </code></pre>
567b87b @flyerhzm update readme
authored Jun 27, 2010
30
8335fac @flyerhzm update documents
authored Nov 19, 2010
31 or add it into a Gemfile (Bundler):
32 <pre><code>
33 gem "bullet", :group => "development"
7839293 @flyerhzm fix typo in README
authored Mar 1, 2012
34 </code></pre>
8335fac @flyerhzm update documents
authored Nov 19, 2010
35
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
36 ****************************************************************************
37
38 h2. Configuration
39
40 Bullet won't do ANYTHING unless you tell it to explicitly. Append to <code>config/environments/development.rb</code> initializer with the following code:
41 <pre><code>
42 config.after_initialize do
8335fac @flyerhzm update documents
authored Nov 19, 2010
43 Bullet.enable = true
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
44 Bullet.alert = true
8335fac @flyerhzm update documents
authored Nov 19, 2010
45 Bullet.bullet_logger = true
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
46 Bullet.console = true
47 Bullet.growl = true
6fdac4a @sriedel Document XMPP notification presenter setup
sriedel authored Jun 20, 2010
48 Bullet.xmpp = { :account => 'bullets_account@jabber.org',
49 :password => 'bullets_password_for_jabber',
50 :receiver => 'your_account@jabber.org',
51 :show_online_status => true }
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
52 Bullet.rails_logger = true
1874491 @kosmatov update README
kosmatov authored Sep 28, 2012
53 Bullet.airbrake = true
7cd4b24 add disable_browser_cache to README
Richard authored Sep 15, 2009
54 Bullet.disable_browser_cache = true
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
55 end
56 </code></pre>
57
8335fac @flyerhzm update documents
authored Nov 19, 2010
58 The notifier of bullet is a wrap of "uniform_notifier":https://github.com/flyerhzm/uniform_notifier
6fdac4a @sriedel Document XMPP notification presenter setup
sriedel authored Jun 20, 2010
59
befed61 @kosmatov update README
kosmatov authored Sep 28, 2012
60 The code above will enable all seven of the Bullet notification systems:
d1e0543 @flyerhzm update README to tell that bullet already support mongoid
authored May 9, 2012
61 * <code>Bullet.enable</code>: enable Bullet gem, otherwise do nothing
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
62 * <code>Bullet.alert</code>: pop up a JavaScript alert in the browser
6d99e92 @flyerhzm compatible with rails3, it seems working fine, needs more test
authored Mar 7, 2010
63 * <code>Bullet.bullet_logger</code>: log to the Bullet log file (Rails.root/log/bullet.log)
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
64 * <code>Bullet.rails_logger</code>: add warnings directly to the Rails log
1874491 @kosmatov update README
kosmatov authored Sep 28, 2012
65 * <code>Bullet.airbrake</code>: add notifications to airbrake
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
66 * <code>Bullet.console</code>: log warnings to your browser's console.log (Safari/Webkit browsers or Firefox w/Firebug installed)
67 * <code>Bullet.growl</code>: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
6fdac4a @sriedel Document XMPP notification presenter setup
sriedel authored Jun 20, 2010
68 * <code>Bullet.xmpp</code>: send XMPP/Jabber notifications to the receiver indicated. Note that the code will currently not handle the adding of contacts, so you will need to make both accounts indicated know each other manually before you will receive any notifications. If you restart the development server frequently, the 'coming online' sound for the bullet account may start to annoy - in this case set :show_online_status to false; you will still get notifications, but the bullet account won't announce it's online status anymore.
7cd4b24 add disable_browser_cache to README
Richard authored Sep 15, 2009
69 * <code>Bullet.disable_browser_cache</code>: disable browser cache which usually causes unexpected problems
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
70
71 ****************************************************************************
72
73 h2. Log
74
75 The Bullet log <code>log/bullet.log</code> will look something like this:
76
77 * N+1 Query:
78 <pre><code>
79 2009-08-25 20:40:17[INFO] N+1 Query: PATH_INFO: /posts; model: Post => associations: [comments]·
80 Add to your finder: :include => [:comments]
81 2009-08-25 20:40:17[INFO] N+1 Query: method call stack:·
82 /Users/richard/Downloads/test/app/views/posts/index.html.erb:11:in `_run_erb_app47views47posts47index46html46erb'
83 /Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `each'
84 /Users/richard/Downloads/test/app/views/posts/index.html.erb:8:in `_run_erb_app47views47posts47index46html46erb'
85 /Users/richard/Downloads/test/app/controllers/posts_controller.rb:7:in `index'
86 </code></pre>
87
88 The first two lines are notifications that N+1 queries have been encountered. The remaining lines are stack traces so you can find exactly where the queries were invoked in your code, and fix them.
89
d911954 @webmat Fixed 2 typos in the readme
webmat authored Oct 6, 2009
90 * Unused eager loading:
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
91 <pre><code>
92 2009-08-25 20:53:56[INFO] Unused eager loadings: PATH_INFO: /posts; model: Post => associations: [comments]·
93 Remove from your finder: :include => [:comments]
94 </code></pre>
95
96 These two lines are notifications that unused eager loadings have been encountered.
97
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
98 * Need counter cache:
99 <pre><code>
100 2009-09-11 09:46:50[INFO] Need Counter Cache
101 Post => [:comments]
102 </code></pre>
103
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
104 ****************************************************************************
105
1874491 @kosmatov update README
kosmatov authored Sep 28, 2012
106 h2. Growl, XMPP/Jabber and Airbrake Support
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
107
50949e9 @flyerhzm update README for Growl Support
authored Aug 17, 2012
108 see "https://github.com/flyerhzm/uniform_notifier":https://github.com/flyerhzm/uniform_notifier
e24a276 @flyerhzm fix ruby1.9 issue with rack response body
authored Feb 10, 2010
109
110 ****************************************************************************
111
8152357 @flyerhzm add important section in README to tell user disable cache in browser
authored Sep 9, 2009
112 h2. Important
113
1fafe3e @flyerhzm update README
authored Mar 7, 2010
114 If you find bullet does not work for you, *please disable your browser's cache*.
8152357 @flyerhzm add important section in README to tell user disable cache in browser
authored Sep 9, 2009
115
116 ****************************************************************************
117
e3e1084 add advance usage for server other than http server
Richard authored Sep 7, 2009
118 h2. Advance
119
d1e0543 @flyerhzm update README to tell that bullet already support mongoid
authored May 9, 2012
120 The bullet gem use rack middleware for http request. If you want to bullet for without http server, such as job server. You can do like this:
e3e1084 add advance usage for server other than http server
Richard authored Sep 7, 2009
121
122 <pre><code>
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
123 Bullet.start_request if Bullet.enable?
e3e1084 add advance usage for server other than http server
Richard authored Sep 7, 2009
124 # run job
2dd91f3 better README
Richard authored Sep 7, 2009
125 if Bullet.enable?
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
126 Bullet.growl_notification
d911954 @webmat Fixed 2 typos in the readme
webmat authored Oct 6, 2009
127 Bullet.log_notification('JobServer: ')
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
128 Bullet.end_request
2dd91f3 better README
Richard authored Sep 7, 2009
129 end
e3e1084 add advance usage for server other than http server
Richard authored Sep 7, 2009
130 </code></pre>
131
a123bba add bullet for test to README
Richard authored Sep 11, 2009
132 Or you want to use it in test mode
133
134 <pre><code>
135 before(:each)
136 Bullet.start_request if Bullet.enable?
137 end
138
139 after(:each)
140 if Bullet.enable?
7591f67 @flyerhzm update README for using bullet in test environment
authored Nov 1, 2010
141 Bullet.perform_out_of_channel_notifications
a123bba add bullet for test to README
Richard authored Sep 11, 2009
142 Bullet.end_request
143 end
144 end
145 </code></pre>
146
de2f7ee notify users enable bullet in test environment if they want to use it…
Richard authored Nov 20, 2009
147 Don't forget enabling bullet in test environment.
148
e3e1084 add advance usage for server other than http server
Richard authored Sep 7, 2009
149 ****************************************************************************
2d53eae add links section in README
Richard authored Nov 6, 2009
150
f359e9b @flyerhzm README for rails2 and rails3
authored Mar 7, 2010
151 h2. Contributors
152
5e81f1b @flyerhzm update README for contributors
authored Dec 30, 2011
153 "https://github.com/flyerhzm/bullet/contributors":https://github.com/flyerhzm/bullet/contributors
f359e9b @flyerhzm README for rails2 and rails3
authored Mar 7, 2010
154
155 ****************************************************************************
156
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
157 h2. Step by step example
158
159 Bullet is designed to function as you browse through your application in development. It will alert you whenever it encounters N+1 queries or unused eager loading.
160
161 1. setup test environment
162
163 <pre><code>
8ffd4b6 @flyerhzm update README
authored Dec 11, 2011
164 $ rails new test_bullet
165 $ cd test_bullet
166 $ rails g scaffold post name:string
167 $ rails g scaffold comment name:string post_id:integer
168 $ bundle exec rake db:migrate
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
169 </code></pre>
170
171 2. change <code>app/model/post.rb</code> and <code>app/model/comment.rb</code>
172
173 <pre><code>
174 class Post < ActiveRecord::Base
175 has_many :comments
176 end
177
178 class Comment < ActiveRecord::Base
179 belongs_to :post
180 end
181 </code></pre>
182
8ffd4b6 @flyerhzm update README
authored Dec 11, 2011
183 3. go to <code>rails c</code> and execute
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
184
185 <pre><code>
186 post1 = Post.create(:name => 'first')
187 post2 = Post.create(:name => 'second')
188 post1.comments.create(:name => 'first')
189 post1.comments.create(:name => 'second')
190 post2.comments.create(:name => 'third')
191 post2.comments.create(:name => 'fourth')
192 </code></pre>
193
194 4. change the <code>app/views/posts/index.html.erb</code> to produce a N+1 query
195
196 <pre><code>
197 <% @posts.each do |post| %>
198 <tr>
d961a89 @flyerhzm update README
authored Mar 7, 2010
199 <td><%= post.name %></td>
8ffd4b6 @flyerhzm update README
authored Dec 11, 2011
200 <td><%= post.comments.map(&:name) %></td>
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
201 <td><%= link_to 'Show', post %></td>
202 <td><%= link_to 'Edit', edit_post_path(post) %></td>
203 <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
204 </tr>
205 <% end %>
206 </code></pre>
207
1fafe3e @flyerhzm update README
authored Mar 7, 2010
208 5. add bullet gem to <code>Gemfile</code>
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
209
210 <pre><code>
8ffd4b6 @flyerhzm update README
authored Dec 11, 2011
211 gem "bullet"
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
212 </code></pre>
213
1fafe3e @flyerhzm update README
authored Mar 7, 2010
214 And run
215
216 <pre><code>bundle install</code></pre>
217
d1e0543 @flyerhzm update README to tell that bullet already support mongoid
authored May 9, 2012
218 6. enable the bullet gem in development, add a line to <code>config/environments/development.rb</code>
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
219
220 <pre><code>
75c1793 @flyerhzm better README
authored Aug 29, 2009
221 config.after_initialize do
6848666 @flyerhzm add config to step by step example
authored Sep 15, 2009
222 Bullet.enable = true
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
223 Bullet.alert = true
6848666 @flyerhzm add config to step by step example
authored Sep 15, 2009
224 Bullet.bullet_logger = true
225 Bullet.console = true
226 # Bullet.growl = true
227 Bullet.rails_logger = true
228 Bullet.disable_browser_cache = true
75c1793 @flyerhzm better README
authored Aug 29, 2009
229 end
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
230 </code></pre>
231
232 7. start server
233
234 <pre><code>
8ffd4b6 @flyerhzm update README
authored Dec 11, 2011
235 $ rails s
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
236 </code></pre>
237
238 8. input http://localhost:3000/posts in browser, then you will see a popup alert box says
239
240 <pre><code>
241 The request has unused preload associations as follows:
242 None
243 The request has N+1 queries as follows:
244 model: Post => associations: [comment]
245 </code></pre>
246
247 which means there is a N+1 query from post object to comments associations.
248
249 In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
250
251 <pre><code>
1fafe3e @flyerhzm update README
authored Mar 7, 2010
252 2010-03-07 14:12:18[INFO] N+1 Query in /posts
253 Post => [:comments]
254 Add to your finder: :include => [:comments]
255 2010-03-07 14:12:18[INFO] N+1 Query method call stack
8ffd4b6 @flyerhzm update README
authored Dec 11, 2011
256 /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:14:in `_render_template__600522146_80203160_0'
257 /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `each'
258 /home/flyerhzm/Downloads/test_bullet/app/views/posts/index.html.erb:11:in `_render_template__600522146_80203160_0'
259 /home/flyerhzm/Downloads/test_bullet/app/controllers/posts_controller.rb:7:in `index'
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
260 </code></pre>
261
262 The generated SQLs are
263
264 <pre><code>
8335fac @flyerhzm update documents
authored Nov 19, 2010
265 Post Load (1.0ms) SELECT * FROM "posts"
266 Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments".post_id = 1)
267 Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments".post_id = 2)
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
268 </code></pre>
269
270
271 9. fix the N+1 query, change <code>app/controllers/posts_controller.rb</code> file
272
273 <pre><code>
274 def index
f359e9b @flyerhzm README for rails2 and rails3
authored Mar 7, 2010
275 @posts = Post.includes(:comments)
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
276
277 respond_to do |format|
278 format.html # index.html.erb
279 format.xml { render :xml => @posts }
8335fac @flyerhzm update documents
authored Nov 19, 2010
280 end
281 end
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
282 </code></pre>
283
284 10. refresh http://localhost:3000/posts page, no alert box and no log appended.
285
286 The generated SQLs are
287
288 <pre><code>
8335fac @flyerhzm update documents
authored Nov 19, 2010
289 Post Load (0.5ms) SELECT * FROM "posts"
290 Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id IN (1,2))
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
291 </code></pre>
292
293 a N+1 query fixed. Cool!
294
295 11. now simulate unused eager loading. Change <code>app/controllers/posts_controller.rb</code> and <code>app/views/posts/index.html.erb</code>
296
297 <pre><code>
298 def index
f359e9b @flyerhzm README for rails2 and rails3
authored Mar 7, 2010
299 @posts = Post.includes(:comments)
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
300
301 respond_to do |format|
302 format.html # index.html.erb
303 format.xml { render :xml => @posts }
8335fac @flyerhzm update documents
authored Nov 19, 2010
304 end
305 end
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
306 </code></pre>
307
308 <pre><code>
309 <% @posts.each do |post| %>
310 <tr>
d961a89 @flyerhzm update README
authored Mar 7, 2010
311 <td><%= post.name %></td>
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
312 <td><%= link_to 'Show', post %></td>
313 <td><%= link_to 'Edit', edit_post_path(post) %></td>
314 <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
315 </tr>
316 <% end %>
317 </code></pre>
318
319 12. refresh http://localhost:3000/posts page, then you will see a popup alert box says
320
321 <pre><code>
322 The request has unused preload associations as follows:
323 model: Post => associations: [comment]
324 The request has N+1 queries as follows:
325 None
326 </code></pre>
327
328 In the meanwhile, there's a log appended into <code>log/bullet.log</code> file
329
330 <pre><code>
331 2009-08-25 21:13:22[INFO] Unused preload associations: PATH_INFO: /posts; model: Post => associations: [comments]·
332 Remove from your finder: :include => [:comments]
333 </code></pre>
334
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
335 13. simulate counter_cache. Change <code>app/controllers/posts_controller.rb</code> and <code>app/views/posts/index.html.erb</code>
336
337 <pre><code>
338 def index
1fafe3e @flyerhzm update README
authored Mar 7, 2010
339 @posts = Post.all
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
340
341 respond_to do |format|
342 format.html # index.html.erb
343 format.xml { render :xml => @posts }
8335fac @flyerhzm update documents
authored Nov 19, 2010
344 end
345 end
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
346 </code></pre>
347
348 <pre><code>
349 <% @posts.each do |post| %>
350 <tr>
d961a89 @flyerhzm update README
authored Mar 7, 2010
351 <td><%= post.name %></td>
352 <td><%= post.comments.size %></td>
5182aa3 @flyerhzm upgrade README to support new configuration and counter_cache
authored Sep 11, 2009
353 <td><%= link_to 'Show', post %></td>
354 <td><%= link_to 'Edit', edit_post_path(post) %></td>
355 <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
356 </tr>
357 <% end %>
358 </code></pre>
359
360 14. refresh http://localhost:3000/posts page, then you will see a popup alert box says
361
362 <pre><code>
363 Need counter cache
364 Post => [:comments]
365 </code></pre>
366
367 In the meanwhile, there's a log appended into <code>log/bullet.log</code> file.
368
369 <pre><code>
370 2009-09-11 10:07:10[INFO] Need Counter Cache
371 Post => [:comments]
372 </code></pre>
373
25e1ad0 @flyerhzm better README
authored Oct 22, 2009
374 ****************************************************************************
375
1ae66a8 @flyerhzm revert to README.textile
authored Aug 28, 2009
376
c66c114 @flyerhzm update README
authored Mar 4, 2012
377 Copyright (c) 2009 - 2012 Richard Huang (flyerhzm@gmail.com), released under the MIT license
Something went wrong with that request. Please try again.