stackprof 0.2.9 → 0.2.10
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/.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
|
+

|
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+
|