stackprof 0.2.9 → 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.travis.yml +8 -0
- data/Gemfile.lock +1 -1
- data/README.md +39 -2
- data/Rakefile +1 -1
- data/bin/stackprof +5 -1
- data/ext/{extconf.rb → stackprof/extconf.rb} +1 -1
- data/ext/{stackprof.c → stackprof/stackprof.c} +1 -4
- data/lib/stackprof.rb +4 -0
- data/lib/stackprof/report.rb +7 -2
- data/stackprof.gemspec +2 -2
- metadata +17 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afa4ecbd5eba7e06625bb12c770da033682539f4
|
4
|
+
data.tar.gz: fc0f0ad1bcc0e1d726c82437a57aa6c0beb8b3e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddb8ed15ef2275231790a475a770a72753fe87aee98fc77d2c7a19d9405228f72832b76f941c84db94bf62fd5a445fb9d3b8e3521f2bc016f6dc170229d56a0e
|
7
|
+
data.tar.gz: b911543ceb1e019086adda7780aa72b48dc6bede83ee99cf746b5cac557f5f9a395c5f88ac3a5f34414e1c1dc8f56c5559e770e8eb355cc9a0c9f7071bb144fe
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -24,7 +24,7 @@ in ruby:
|
|
24
24
|
|
25
25
|
``` ruby
|
26
26
|
StackProf.run(mode: :cpu, out: 'tmp/stackprof-cpu-myapp.dump') do
|
27
|
-
|
27
|
+
#...
|
28
28
|
end
|
29
29
|
```
|
30
30
|
|
@@ -77,6 +77,22 @@ $ stackprof tmp/stackprof-cpu-*.dump --method 'Object#present?'
|
|
77
77
|
|
78
78
|
For an experimental version of WebUI reporting of stackprof, see [stackprof-webnav](https://github.com/alisnic/stackprof-webnav)
|
79
79
|
|
80
|
+
You can generate a flamegraph however additional data must be collected using the `raw: true` flag. Once you've collected results with this flag enabled you can generate a flamegraph:
|
81
|
+
|
82
|
+
```
|
83
|
+
$ stackprof --flamegraph tmp/stackprof-cpu-myapp.dump > tmp/flamegraph
|
84
|
+
```
|
85
|
+
|
86
|
+
Once the flamegraph has been generated you can generate a viewer command with:
|
87
|
+
|
88
|
+
```
|
89
|
+
$ stackprof --flamegraph-viewer=tmp/flamegraph
|
90
|
+
```
|
91
|
+
|
92
|
+
The `--flamegraph-viewer` command will output the exact shell command you need to run to open the `tmp/flamegraph` you generated with the built in stackprof flamegraph viewer:
|
93
|
+
|
94
|
+
![](http://i.imgur.com/EwndrgD.png)
|
95
|
+
|
80
96
|
### sampling
|
81
97
|
|
82
98
|
four sampling modes are supported:
|
@@ -89,9 +105,30 @@ four sampling modes are supported:
|
|
89
105
|
samplers have a tuneable interval which can be used to reduce overhead or increase granularity:
|
90
106
|
|
91
107
|
- wall time: sample every _interval_ microseconds of wallclock time (default: 1000)
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
StackProf.run(mode: :wall, out: 'tmp/stackprof.dump', interval: 1000) do
|
111
|
+
#...
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
92
115
|
- cpu time: sample every _interval_ microseconds of cpu activity (default: 1000 = 1 millisecond)
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
StackProf.run(mode: :cpu, out: 'tmp/stackprof.dump', interval: 1000) do
|
119
|
+
#...
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
93
123
|
- object allocation: sample every _interval_ allocations (default: 1)
|
94
124
|
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
StackProf.run(mode: :object, out: 'tmp/stackprof.dump', interval: 1) do
|
128
|
+
#...
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
95
132
|
samples are taken using a combination of three new C-APIs in ruby 2.1:
|
96
133
|
|
97
134
|
- signal handlers enqueue a sampling job using `rb_postponed_job_register_one`.
|
@@ -105,7 +142,7 @@ samples are taken using a combination of three new C-APIs in ruby 2.1:
|
|
105
142
|
- in allocation mode, samples are taken via `rb_tracepoint_new(RUBY_INTERNAL_EVENT_NEWOBJ)`,
|
106
143
|
which provides a notification every time the VM allocates a new object.
|
107
144
|
|
108
|
-
###
|
145
|
+
### Aggregation
|
109
146
|
|
110
147
|
each sample consists of N stack frames, where a frame looks something like `MyClass#method` or `block in MySingleton.method`.
|
111
148
|
for each of these frames in the sample, the profiler collects a few pieces of metadata:
|
data/Rakefile
CHANGED
data/bin/stackprof
CHANGED
@@ -22,6 +22,10 @@ parser = OptionParser.new(ARGV) do |o|
|
|
22
22
|
puts("open file://#{File.expand_path('../../lib/stackprof/flamegraph/viewer.html', __FILE__)}?data=#{File.expand_path(file)}")
|
23
23
|
exit
|
24
24
|
}
|
25
|
+
o.on('--select-files []', String, 'Show results of matching files'){ |path| (options[:select_files] ||= []) << File.expand_path(path) }
|
26
|
+
o.on('--reject-files []', String, 'Exclude results of matching files'){ |path| (options[:reject_files] ||= []) << File.expand_path(path) }
|
27
|
+
o.on('--select-names []', Regexp, 'Show results of matching method names'){ |regexp| (options[:select_names] ||= []) << regexp }
|
28
|
+
o.on('--reject-names []', Regexp, 'Exclude results of matching method names'){ |regexp| (options[:reject_names] ||= []) << regexp }
|
25
29
|
o.on('--dump', 'Print marshaled profile dump (combine multiple profiles)'){ options[:format] = :dump }
|
26
30
|
o.on('--debug', 'Pretty print raw profile data'){ options[:format] = :debug }
|
27
31
|
end
|
@@ -56,7 +60,7 @@ options.delete(:limit) if options[:limit] == 0
|
|
56
60
|
|
57
61
|
case options[:format]
|
58
62
|
when :text
|
59
|
-
report.print_text(options[:sort], options[:limit])
|
63
|
+
report.print_text(options[:sort], options[:limit], options[:select_files], options[:reject_files], options[:select_names], options[:reject_names])
|
60
64
|
when :debug
|
61
65
|
report.print_debug
|
62
66
|
when :dump
|
@@ -3,7 +3,7 @@ if have_func('rb_postponed_job_register_one') &&
|
|
3
3
|
have_func('rb_profile_frames') &&
|
4
4
|
have_func('rb_tracepoint_new') &&
|
5
5
|
have_const('RUBY_INTERNAL_EVENT_NEWOBJ')
|
6
|
-
create_makefile('stackprof')
|
6
|
+
create_makefile('stackprof/stackprof')
|
7
7
|
else
|
8
8
|
fail 'missing API: are you using ruby 2.1+?'
|
9
9
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
stackprof.c - Sampling call-stack frame profiler for MRI.
|
4
4
|
|
5
|
-
vim:
|
5
|
+
vim: noexpandtab shiftwidth=4 tabstop=8 softtabstop=4
|
6
6
|
|
7
7
|
**********************************************************************/
|
8
8
|
|
@@ -540,8 +540,5 @@ Init_stackprof(void)
|
|
540
540
|
rb_define_singleton_method(rb_mStackProf, "results", stackprof_results, -1);
|
541
541
|
rb_define_singleton_method(rb_mStackProf, "sample", stackprof_sample, 0);
|
542
542
|
|
543
|
-
rb_autoload(rb_mStackProf, rb_intern_const("Report"), "stackprof/report.rb");
|
544
|
-
rb_autoload(rb_mStackProf, rb_intern_const("Middleware"), "stackprof/middleware.rb");
|
545
|
-
|
546
543
|
pthread_atfork(stackprof_atfork_prepare, stackprof_atfork_parent, stackprof_atfork_child);
|
547
544
|
}
|
data/lib/stackprof.rb
ADDED
data/lib/stackprof/report.rb
CHANGED
@@ -9,7 +9,8 @@ module StackProf
|
|
9
9
|
attr_reader :data
|
10
10
|
|
11
11
|
def frames(sort_by_total=false)
|
12
|
-
@data[:
|
12
|
+
@data[:"sorted_frames_#{sort_by_total}"] ||=
|
13
|
+
@data[:frames].sort_by{ |iseq, stats| -stats[sort_by_total ? :total_samples : :samples] }.inject({}){|h, (k, v)| h[k] = v; h}
|
13
14
|
end
|
14
15
|
|
15
16
|
def normalized_frames
|
@@ -209,7 +210,7 @@ module StackProf
|
|
209
210
|
f.puts "}"
|
210
211
|
end
|
211
212
|
|
212
|
-
def print_text(sort_by_total=false, limit=nil, f = STDOUT)
|
213
|
+
def print_text(sort_by_total=false, limit=nil, select_files= nil, reject_files=nil, select_names=nil, reject_names=nil, f = STDOUT)
|
213
214
|
f.puts "=================================="
|
214
215
|
f.printf " Mode: #{modeline}\n"
|
215
216
|
f.printf " Samples: #{@data[:samples]} (%.2f%% miss rate)\n", 100.0*@data[:missed_samples]/(@data[:missed_samples]+@data[:samples])
|
@@ -217,6 +218,10 @@ module StackProf
|
|
217
218
|
f.puts "=================================="
|
218
219
|
f.printf "% 10s (pct) % 10s (pct) FRAME\n" % ["TOTAL", "SAMPLES"]
|
219
220
|
list = frames(sort_by_total)
|
221
|
+
list.select!{|_, info| select_files.any?{|path| info[:file].start_with?(path)}} if select_files
|
222
|
+
list.select!{|_, info| select_names.any?{|reg| info[:name] =~ reg}} if select_names
|
223
|
+
list.reject!{|_, info| reject_files.any?{|path| info[:file].start_with?(path)}} if reject_files
|
224
|
+
list.reject!{|_, info| reject_names.any?{|reg| info[:name] =~ reg}} if reject_names
|
220
225
|
list = list.first(limit) if limit
|
221
226
|
list.each do |frame, info|
|
222
227
|
call, total = info.values_at(:samples, :total_samples)
|
data/stackprof.gemspec
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'stackprof'
|
3
|
-
s.version = '0.2.
|
3
|
+
s.version = '0.2.10'
|
4
4
|
s.homepage = 'http://github.com/tmm1/stackprof'
|
5
5
|
|
6
6
|
s.authors = 'Aman Gupta'
|
7
7
|
s.email = 'aman@tmm1.net'
|
8
8
|
|
9
9
|
s.files = `git ls-files`.split("\n")
|
10
|
-
s.extensions = 'ext/extconf.rb'
|
10
|
+
s.extensions = 'ext/stackprof/extconf.rb'
|
11
11
|
|
12
12
|
s.bindir = 'bin'
|
13
13
|
s.executables << 'stackprof'
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aman Gupta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.9'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: mocha
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0.14'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.14'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '5.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '5.0'
|
55
55
|
description: stackprof is a fast sampling profiler for ruby code, with cpu, wallclock
|
@@ -60,10 +60,11 @@ executables:
|
|
60
60
|
- stackprof-flamegraph.pl
|
61
61
|
- stackprof-gprof2dot.py
|
62
62
|
extensions:
|
63
|
-
- ext/extconf.rb
|
63
|
+
- ext/stackprof/extconf.rb
|
64
64
|
extra_rdoc_files: []
|
65
65
|
files:
|
66
|
-
- .gitignore
|
66
|
+
- ".gitignore"
|
67
|
+
- ".travis.yml"
|
67
68
|
- Gemfile
|
68
69
|
- Gemfile.lock
|
69
70
|
- LICENSE
|
@@ -72,8 +73,9 @@ files:
|
|
72
73
|
- bin/stackprof
|
73
74
|
- bin/stackprof-flamegraph.pl
|
74
75
|
- bin/stackprof-gprof2dot.py
|
75
|
-
- ext/extconf.rb
|
76
|
-
- ext/stackprof.c
|
76
|
+
- ext/stackprof/extconf.rb
|
77
|
+
- ext/stackprof/stackprof.c
|
78
|
+
- lib/stackprof.rb
|
77
79
|
- lib/stackprof/flamegraph/flamegraph.js
|
78
80
|
- lib/stackprof/flamegraph/viewer.html
|
79
81
|
- lib/stackprof/middleware.rb
|
@@ -97,17 +99,17 @@ require_paths:
|
|
97
99
|
- lib
|
98
100
|
required_ruby_version: !ruby/object:Gem::Requirement
|
99
101
|
requirements:
|
100
|
-
- -
|
102
|
+
- - ">="
|
101
103
|
- !ruby/object:Gem::Version
|
102
104
|
version: '0'
|
103
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
106
|
requirements:
|
105
|
-
- -
|
107
|
+
- - ">="
|
106
108
|
- !ruby/object:Gem::Version
|
107
109
|
version: '0'
|
108
110
|
requirements: []
|
109
111
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.4.5.1
|
111
113
|
signing_key:
|
112
114
|
specification_version: 4
|
113
115
|
summary: sampling callstack-profiler for ruby 2.1+
|