memory_tracker 1.0.4 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +71 -0
- data/app/controllers/memory_tracker/dashboards_controller.rb +13 -2
- data/app/helpers/memory_tracker/dashboards_helper.rb +9 -0
- data/app/views/memory_tracker/dashboards/index.html.erb +25 -1
- data/lib/memory_tracker/version.rb +1 -1
- data/memory_tracker.gemspec +2 -2
- metadata +3 -3
- data/README.rdoc +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adeca7dfc23c7e1fc6ba5c3411ed54639ca30b87
|
4
|
+
data.tar.gz: b94c7d23aa9f03912cdc4be6c025860428e97aa7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67c83299b9e960365b3a8429402b2b05f63c8b4baeb589ceef5385d2f24c63be1d3d285629b35f718a3c0bac93953e88a65d732c31d73df6cae1498a126a6f22
|
7
|
+
data.tar.gz: d7d17859238f52bfac1cb69a4c00761444f64a08f339bed9c0c7c45f941edc5db05e6b058e1f9c9f2008ccb771b9b547e5f07da9a9ce7dbe68dcb85dda65c0a7
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# MemoryTracker
|
2
|
+
|
3
|
+
MemoryTracker collects, analyzes and reports memory usage data of each controller action of a Rails application. The data will identify the parts of the application that are the most memory hungry, so that they can be fixed and the overall memory usage of the application be reduced.
|
4
|
+
|
5
|
+
# Features
|
6
|
+
* Collect stats on each controller action memory consumption.
|
7
|
+
* Display stats on every controller action of the application in a engine webpage embedded in the gem.
|
8
|
+
|
9
|
+
# Dashboard
|
10
|
+
The dashboard is at /memtracker in the host application (but you need to mount the engine in the app first, see below).
|
11
|
+
![Dashboard snapshot](https://github.com/plerohellec/memory_tracker/tree/master/docs/memory_tracker_dashboard.png?raw=true)
|
12
|
+
|
13
|
+
# How?
|
14
|
+
MemoryTracker uses system memory data and Ruby garbage collector statistics to find the memory currently used by The Rails processes, how many objects were allocated in Ruby heaps, how many heaps were created and how many times the garbage collector ran. The MemoryTracker middleware captures the data before and after each HHTP request and saves the deltas per controller/action in a variety of stores.
|
15
|
+
|
16
|
+
MemoryTracker is implemented as a Rails engine and reports its statistics in a web page served by the application where it's embedded. The report currently includes data from the InMemoryStore.
|
17
|
+
|
18
|
+
# Stores
|
19
|
+
MemoryTracker currently comes with 3 stores.
|
20
|
+
|
21
|
+
* The InMemoryStore keeps counters in memory for the process where it runs. This store in itself uses very little memory as it only keeps a set of counters per controller/action in the application. Since it doesn't do any IO, it is also extremely fast. The data is immediately available without any need for a background aggregation tasks.
|
22
|
+
|
23
|
+
* The GcStatLogfile store simply write memory stats to a log file called '#{Rails.root}/log/memtracker_gcstat.log' after each HTTP request.
|
24
|
+
|
25
|
+
* The UrlLogfileStore also stores data in a log file ('#{Rails.root}/log/memtracker_urls.log') but instead of writing the raw memory data, it records the URL that was requested along with the memory deltas between the current request and the previous one. It also highlights the urls where the deltas were the greatest. It's sometimes interesting to browse through this file URLs that are particularly greedy.
|
26
|
+
|
27
|
+
|
28
|
+
# Enabling MemoryTracker
|
29
|
+
Add it to your Gemfile:
|
30
|
+
```ruby
|
31
|
+
gem 'memory_tracker'
|
32
|
+
```
|
33
|
+
To get access to the MemoryTracker UI and see the stats, the engine must be mounted at config/routes.rb
|
34
|
+
```ruby
|
35
|
+
mount MemoryTracker::Engine => "/memtracker"
|
36
|
+
```
|
37
|
+
Once the app is running, go to /memtracker to review the list of controller actions.
|
38
|
+
|
39
|
+
# Requirements
|
40
|
+
The gem has been tested and is compatible with:
|
41
|
+
* Ruby 2.0
|
42
|
+
* Rails 3.2
|
43
|
+
|
44
|
+
# Tips
|
45
|
+
* Ruby processes rarely leak memory. Instead they allocate memory whenever they need it and never release it. This memory is not lost, it's still available to the process that allocated it but it's unavailable for all other processes in the system.
|
46
|
+
* It doesn't matter if the average controller action in the application only consumes 50MB of memory, the size of the process will still reach 100MB if a single one of the controller actions requires 100MB. Therefore, the biggest bang for the bug is to be found in the action at the top of the list. Fix that one and the whole process memory will go down to the level of the second most expensive controller action.
|
47
|
+
* You want the heap_used to be 0, always. If not 0, it means this controller action asked for an amount of memory that required the allocation of new heaps.
|
48
|
+
* rss and vsize should be very low in a memory conscious application.
|
49
|
+
* total_allocated_heaps should mostly be in the same range for all controller actions. Outliers are the ones causing memory bloat.
|
50
|
+
* The stats are only meaningful in the production environment. Do not believe anything you see in the development environment.
|
51
|
+
|
52
|
+
# Coming soon
|
53
|
+
* Redis store.
|
54
|
+
* Store and report the most expensive URLs.
|
55
|
+
* Support for Ruby 1.9 and Rails 4.
|
56
|
+
|
57
|
+
# Contributing to memory_tracker
|
58
|
+
|
59
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
60
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
61
|
+
* Fork the project.
|
62
|
+
* Start a feature/bugfix branch.
|
63
|
+
* Commit and push until you are happy with your contribution.
|
64
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
65
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
66
|
+
|
67
|
+
# Copyright
|
68
|
+
|
69
|
+
Copyright (c) 2013 Philippe Le Rohellec. See LICENSE.txt for
|
70
|
+
further details.
|
71
|
+
|
@@ -8,11 +8,22 @@ module MemoryTracker
|
|
8
8
|
def index
|
9
9
|
stats = MemoryTracker.instance.stats(:memory)
|
10
10
|
@data = stats.to_a
|
11
|
-
sort_by = params[:sort_by] ? params[:sort_by].to_sym : :count
|
11
|
+
sort_by = params[:sort_by] ? params[:sort_by].downcase.to_sym : :count
|
12
12
|
if @data.any? && @data.first.keys.include?(sort_by)
|
13
|
-
|
13
|
+
if [ :controller, :action ].include?(sort_by)
|
14
|
+
@data = @data.sort { |a,b| a[sort_by] <=> b[sort_by] }
|
15
|
+
elsif sort_by == :num
|
16
|
+
@data = @data.sort { |a,b| b[sort_by] <=> a[sort_by] }
|
17
|
+
else
|
18
|
+
@data = @data.sort{ |a,b| b[sort_by].to_f/b[:num] <=> a[sort_by].to_f/a[:num] }
|
19
|
+
end
|
14
20
|
end
|
15
21
|
|
22
|
+
@pid = Process.pid
|
23
|
+
@rss = Request.rss
|
24
|
+
@vsize = Request.vsize
|
25
|
+
@num_heaps = GC.stat[:heap_used]
|
26
|
+
|
16
27
|
respond_to do |format|
|
17
28
|
format.json do
|
18
29
|
render :json => @data.to_json
|
@@ -3,5 +3,14 @@ module MemoryTracker
|
|
3
3
|
def link_to_dashboards(name)
|
4
4
|
link_to(name, memory_tracker.dashboards_path(:sort_by => name))
|
5
5
|
end
|
6
|
+
|
7
|
+
def display_num(val, num)
|
8
|
+
f = val.to_f / num
|
9
|
+
if f > 1000
|
10
|
+
f.to_i
|
11
|
+
else
|
12
|
+
'%.3f' % (val.to_f/num)
|
13
|
+
end
|
14
|
+
end
|
6
15
|
end
|
7
16
|
end
|
@@ -1,3 +1,14 @@
|
|
1
|
+
<h1>Current State</h1>
|
2
|
+
<table width='300px'>
|
3
|
+
<tr><td>Stats displayed for pid</td><td><%= @pid %></td></tr>
|
4
|
+
<tr><td>Current RSS</td><td><%= '%.1f' % @rss %>MB</td></tr>
|
5
|
+
<tr><td>Current VSIZE</td><td><%= '%.1f' % @vsize %>MB</td></tr>
|
6
|
+
<tr><td>Number of ruby heaps</td><td><%= @num_heaps %></td></tr>
|
7
|
+
</table>
|
8
|
+
<br/>
|
9
|
+
|
10
|
+
<hr>
|
11
|
+
<h1>Average Deltas</h1>
|
1
12
|
<% keys = [ :rss, :vsize, :count, :total_allocated_object, :heap_used ] %>
|
2
13
|
<table width="100%">
|
3
14
|
<tr>
|
@@ -14,8 +25,21 @@
|
|
14
25
|
<td><%= "#{row[:action]}" %></td>
|
15
26
|
<td><%= row[:num] %></td>
|
16
27
|
<% keys.each do |key| %>
|
17
|
-
<td><%=
|
28
|
+
<td><%= display_num(row[key], row[:num]) %></td>
|
18
29
|
<% end %>
|
19
30
|
</tr>
|
20
31
|
<% end %>
|
21
32
|
</table>
|
33
|
+
|
34
|
+
<h2>Legend</h2>
|
35
|
+
<p>All numbers are average per controller action.</p>
|
36
|
+
<i>
|
37
|
+
<ul>
|
38
|
+
<li>num: number of HTTP requests</li>
|
39
|
+
<li>rss: resident memory (MB)</li>
|
40
|
+
<li>vsize: virtual memory (MB)</lib>
|
41
|
+
<li>count: number of times the garbage collector ran</li>
|
42
|
+
<li>total_allocated_object: number of objects allocated on the ruby heaps</li>
|
43
|
+
<li>heap_used: number of allocated ruby heaps</li>
|
44
|
+
</ul>
|
45
|
+
</i>
|
data/memory_tracker.gemspec
CHANGED
@@ -16,13 +16,13 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.email = "philippe@lerohellec.com"
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE.txt",
|
19
|
-
"README.
|
19
|
+
"README.md"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
"Gemfile",
|
23
23
|
"Gemfile.lock",
|
24
24
|
"LICENSE.txt",
|
25
|
-
"README.
|
25
|
+
"README.md",
|
26
26
|
"Rakefile",
|
27
27
|
"app/controllers/memory_tracker/application_controller.rb",
|
28
28
|
"app/controllers/memory_tracker/dashboards_controller.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memory_tracker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Philippe Le Rohellec
|
@@ -87,12 +87,12 @@ executables: []
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files:
|
89
89
|
- LICENSE.txt
|
90
|
-
- README.
|
90
|
+
- README.md
|
91
91
|
files:
|
92
92
|
- Gemfile
|
93
93
|
- Gemfile.lock
|
94
94
|
- LICENSE.txt
|
95
|
-
- README.
|
95
|
+
- README.md
|
96
96
|
- Rakefile
|
97
97
|
- app/controllers/memory_tracker/application_controller.rb
|
98
98
|
- app/controllers/memory_tracker/dashboards_controller.rb
|
data/README.rdoc
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
= MemoryTracker
|
2
|
-
|
3
|
-
MemoryTracker collects and analyzes memory usage data for each controller action of a Rails application. It's implemented as a Rails engine with a middleware that captures stats before and after each query.
|
4
|
-
|
5
|
-
== How?
|
6
|
-
It uses GC.stats (Ruby garbage collector) to find how many objects were allocated, how many heaps were created and how many times the garbage collector ran.
|
7
|
-
|
8
|
-
== Features
|
9
|
-
* Collect stats on each controller action memory consumption.
|
10
|
-
* Write a log file with GC.stat data.
|
11
|
-
* The engine includes a couple of web pages that shows a summary of memory utilization per controller action.
|
12
|
-
|
13
|
-
== Enable MemoryTracker in a Rails application
|
14
|
-
In config/routes.rb
|
15
|
-
mount MemoryTracker::Engine, at: "/memory_tracker"
|
16
|
-
|
17
|
-
== Contributing to memory_tracker
|
18
|
-
|
19
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
20
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
21
|
-
* Fork the project.
|
22
|
-
* Start a feature/bugfix branch.
|
23
|
-
* Commit and push until you are happy with your contribution.
|
24
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
25
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
26
|
-
|
27
|
-
== Copyright
|
28
|
-
|
29
|
-
Copyright (c) 2013 Philippe Le Rohellec. See LICENSE.txt for
|
30
|
-
further details.
|
31
|
-
|