railsprof 0.0.1 → 0.0.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.
- checksums.yaml +4 -4
- data/lib/railsprof/lineprof_parser.rb +19 -6
- data/lib/railsprof/profiler.rb +18 -7
- data/lib/railsprof/version.rb +1 -1
- data/lib/railsprof/views/railsprof-tmpl.html.erb +53 -34
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69f4db46ad80ecccc6865b388d9b0635e4fbfa1b
|
4
|
+
data.tar.gz: f9b8821aaf2a7d25283628678af859981ec0ad13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05aadce244d50592ab86757ba849be1c442236c87abeda0e2aefc188de573989edba4862eb1e9520a190e5e92db61a38a2f7fa8ac472b40e64fbda784d743539
|
7
|
+
data.tar.gz: a2f0fd21ec88b697fad8182d9f4ee558f2514c3499643e8a30791c86b41a3dd000bfaf8b998b52a72c856f6ca9566f595ee6a575b96b8322c5cccc8662c43e69
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'erb'
|
2
|
+
require 'pp'
|
2
3
|
|
3
4
|
class Railsprof::LineprofParser
|
4
5
|
# rblineprof formatting
|
@@ -13,20 +14,28 @@ class Railsprof::LineprofParser
|
|
13
14
|
# ...
|
14
15
|
# ]
|
15
16
|
# }
|
17
|
+
attr_reader :logger, :options
|
16
18
|
|
17
|
-
def initialize(profile, paths, threshold_ms: 0.5)
|
19
|
+
def initialize(profile, paths, threshold_ms: 0.5, **options)
|
18
20
|
@threshold = threshold_ms * 1000
|
19
21
|
@paths = paths
|
20
22
|
@profile = profile
|
21
23
|
@friendly_paths = {}
|
22
24
|
@profiled_source = {}
|
25
|
+
@logger = options[:logger]
|
26
|
+
@total_ms = options[:total_ms]
|
27
|
+
@options = options
|
23
28
|
|
24
29
|
@profiled_files = profile
|
25
30
|
.reduce([]) do |files, (file, lines)|
|
26
31
|
total = lines[0][0]
|
27
32
|
if total > @threshold # && !file[/benchmark|\.rake$/] # time in micros
|
28
33
|
@friendly_paths[file] = @paths.relative_path_for(file)
|
29
|
-
|
34
|
+
# [total_time, child_time, excl_time, total_cpu, child_cpu, excl_cpu],
|
35
|
+
tt, _ct, _et, tc, _cc, _ec = lines[0]
|
36
|
+
# total, cpu, idle, exclusive %
|
37
|
+
file_timings = [tt, tc, tt - tc].map { |n| n / 1000.0 }
|
38
|
+
files << [file, *file_timings]
|
30
39
|
end
|
31
40
|
files
|
32
41
|
end
|
@@ -34,11 +43,13 @@ class Railsprof::LineprofParser
|
|
34
43
|
end
|
35
44
|
|
36
45
|
def cli_report
|
37
|
-
|
46
|
+
spacing = 12
|
47
|
+
logger.info ''
|
48
|
+
logger.info(%W(total cpu idle).map { |s| s.ljust(spacing) }.join << " file")
|
38
49
|
|
39
|
-
@profiled_files.each do |file,
|
40
|
-
|
41
|
-
|
50
|
+
@profiled_files.each do |file, *timings|
|
51
|
+
str = timings.map { |t| ('%.1fms' % t).ljust(spacing) }.join
|
52
|
+
logger.info "#{str} #{@friendly_paths[file]}"
|
42
53
|
end
|
43
54
|
end
|
44
55
|
|
@@ -57,6 +68,7 @@ class Railsprof::LineprofParser
|
|
57
68
|
ERB.new(template, 0, "", "@html_output").result(b)
|
58
69
|
File.open(filename, 'w') { |f| f.write(@html_output) }
|
59
70
|
|
71
|
+
logger.info "Results in #{filename}"
|
60
72
|
`open #{filename}`
|
61
73
|
end
|
62
74
|
|
@@ -66,6 +78,7 @@ class Railsprof::LineprofParser
|
|
66
78
|
@profiled_source[file] = "\n % 8s + % 8s (called)\n" % %w(cpu idle)
|
67
79
|
File.readlines(file).each_with_index do |line, num|
|
68
80
|
wall, cpu, calls, _allocations = @profile[file][num + 1]
|
81
|
+
# excl cpu, excl idle, total cpu, total idle
|
69
82
|
@profiled_source[file] <<
|
70
83
|
if calls && calls > 0
|
71
84
|
'% 8.1fms + % 8.1fms % 8s | %s' %
|
data/lib/railsprof/profiler.rb
CHANGED
@@ -12,6 +12,7 @@ class Railsprof::Profiler
|
|
12
12
|
|
13
13
|
def initialize(args, opts = {})
|
14
14
|
@options = Railsprof::DEFAULT_OPTIONS.merge(opts)
|
15
|
+
@history = []
|
15
16
|
|
16
17
|
@logger = options[:logger] || Railsprof::Logger.new(STDOUT)
|
17
18
|
@logger.level = options[:log_level] || Logger::INFO
|
@@ -24,7 +25,7 @@ class Railsprof::Profiler
|
|
24
25
|
args.first.upcase!
|
25
26
|
@method, @path = args
|
26
27
|
else
|
27
|
-
fail ArgumentError "excepted METHOD PATH, received: #{args.join(' ')}"
|
28
|
+
fail ArgumentError, "excepted METHOD PATH, received: #{args.join(' ')}"
|
28
29
|
end
|
29
30
|
|
30
31
|
logger.debug "Request: #@method #@path"
|
@@ -39,7 +40,7 @@ class Railsprof::Profiler
|
|
39
40
|
if options[:runs] > 0
|
40
41
|
logger.info 'Profiling....'
|
41
42
|
|
42
|
-
say_with_time('All profiles') do
|
43
|
+
total = say_with_time('All profiles') do
|
43
44
|
@profile = lineprof(@paths.regexp) do
|
44
45
|
options[:runs].times do |i|
|
45
46
|
say_with_time("Profile ##{i + 1}") { run }
|
@@ -50,7 +51,15 @@ class Railsprof::Profiler
|
|
50
51
|
|
51
52
|
parser = Railsprof::LineprofParser.new(
|
52
53
|
@profile, @paths,
|
53
|
-
threshold_ms: options[:threshold]
|
54
|
+
threshold_ms: options[:threshold],
|
55
|
+
logger: logger,
|
56
|
+
profiler_options: @options.slice(*%i[
|
57
|
+
gems app_paths threshold cookies params session
|
58
|
+
]),
|
59
|
+
history: @history,
|
60
|
+
method: @method,
|
61
|
+
path: @path,
|
62
|
+
total_ms: total
|
54
63
|
)
|
55
64
|
|
56
65
|
parser.cli_report
|
@@ -99,9 +108,9 @@ class Railsprof::Profiler
|
|
99
108
|
env_file = Dir.pwd + '/config/environment.rb'
|
100
109
|
if File.exists?(env_file)
|
101
110
|
ms = Benchmark.ms { load env_file }
|
102
|
-
logger.info '
|
111
|
+
logger.info 'Loaded in %.2f secs (%s mode)' % [ms / 1000.0, Rails.env]
|
103
112
|
else
|
104
|
-
|
113
|
+
logger.error 'Exiting... an application with config/environment.rb was expected'
|
105
114
|
exit 1
|
106
115
|
end
|
107
116
|
@loaded = true
|
@@ -110,8 +119,10 @@ class Railsprof::Profiler
|
|
110
119
|
def say_with_time(msg, level: 'info', &block)
|
111
120
|
ret = nil
|
112
121
|
ms = Benchmark.ms { ret = block.call }
|
113
|
-
|
114
|
-
|
122
|
+
str = '%s completed in %.2fms' % [msg, ms]
|
123
|
+
logger.send(level, str)
|
124
|
+
@history << str
|
125
|
+
ms
|
115
126
|
end
|
116
127
|
end
|
117
128
|
|
data/lib/railsprof/version.rb
CHANGED
@@ -5,6 +5,17 @@
|
|
5
5
|
<link href="http://clifton.is/css/normalize.css" rel="stylesheet" type="text/css">
|
6
6
|
<link href="http://clifton.is/css/highlight.github.css" rel="stylesheet" type="text/css">
|
7
7
|
<style>
|
8
|
+
* { box-sizing: border-box; }
|
9
|
+
.main { margin: 0 20px 50px; }
|
10
|
+
[double] {
|
11
|
+
margin: 0 0;
|
12
|
+
padding: 0 0;
|
13
|
+
font-size: 200%;
|
14
|
+
}
|
15
|
+
pre:first {
|
16
|
+
padding-top: 0;
|
17
|
+
margin 0 0;
|
18
|
+
}
|
8
19
|
pre {
|
9
20
|
overflow: auto;
|
10
21
|
word-wrap: normal;
|
@@ -13,45 +24,53 @@
|
|
13
24
|
</style>
|
14
25
|
</head>
|
15
26
|
<body>
|
16
|
-
<
|
17
|
-
<
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
</tr>
|
27
|
-
</thead>
|
28
|
-
<tbody>
|
29
|
-
<% @profiled_files.each do |file, *times| %>
|
27
|
+
<div class='main'>
|
28
|
+
<pre>
|
29
|
+
<code double><%= @options.values_at(:method, :path).join(' ') %></code>
|
30
|
+
<code class='ruby'>
|
31
|
+
<%= @options[:profiler_options].map { |k, v| ":#{k.to_s.ljust(12)} #{v.inspect}" }.join("\n") %></code>
|
32
|
+
<code>
|
33
|
+
<%= @options[:history].join("\n") %></code>
|
34
|
+
</pre>
|
35
|
+
<table>
|
36
|
+
<thead>
|
30
37
|
<tr>
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
<td>
|
35
|
-
<a href='#' class='js-toggle-code' data-file='<%= file %>'>
|
36
|
-
<%= @friendly_paths[file] %>
|
37
|
-
</a>
|
38
|
-
</td>
|
38
|
+
<td width='90px'>Total</td>
|
39
|
+
<td width='90px'>CPU</td>
|
40
|
+
<td width='90px'>Idle</td>
|
41
|
+
<td>File</td>
|
39
42
|
</tr>
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
43
|
+
</thead>
|
44
|
+
<tbody>
|
45
|
+
<% @profiled_files.each do |file, *timings| %>
|
46
|
+
<tr>
|
47
|
+
<% timings.each do |t| %>
|
48
|
+
<td><%= '%.1fms' % t %></td>
|
49
|
+
<% end %>
|
50
|
+
<td>
|
51
|
+
<a href='#' class='js-toggle-code' data-file='<%= file %>'>
|
52
|
+
<%= @friendly_paths[file] %>
|
53
|
+
</a>
|
54
|
+
</td>
|
55
|
+
</tr>
|
56
|
+
<tr style='display:none'>
|
57
|
+
<td colspan='7' style='overflow: auto'>
|
58
|
+
<br style='clear:both'>
|
59
|
+
<pre>
|
60
|
+
<code class="ruby"><%= @profiled_source[file] %></code>
|
61
|
+
</pre>
|
62
|
+
</td>
|
63
|
+
</tr>
|
64
|
+
<% end %>
|
65
|
+
</tbody>
|
66
|
+
</table>
|
67
|
+
</div>
|
51
68
|
<script src='http://code.jquery.com/jquery-1.11.0.min.js'></script>
|
52
69
|
<script src='http://clifton.is/js/highlight.js'></script>
|
53
70
|
<script>
|
54
|
-
|
71
|
+
$(function () {
|
72
|
+
$('.ruby').each(function(i, e) { hljs.highlightBlock(e, 'ruby') });
|
73
|
+
});
|
55
74
|
$('.js-toggle-code').on('click', function () {
|
56
75
|
$(this).parents('tr').next().toggle();
|
57
76
|
return false;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: railsprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Clifton King
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|