stackprof 0.2.21 → 0.2.22

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33a342cae97be870781375a647e95936c6a6016ae711f27d60e41a891cb809f4
4
- data.tar.gz: 867d55b7c7cdfc928ae35b3c36474bdda41ed4c4dc8e8b661b0c6580890b0b28
3
+ metadata.gz: 8e473c6b4408f04dc69f4abd425ab68896b4f705adadd467ded771003eb84da1
4
+ data.tar.gz: 5bfaa3c22d7e59271f65136b0237cddc4d1a97edf9650db4caf53c9b36fda55e
5
5
  SHA512:
6
- metadata.gz: 255835983ab93b52f7d1118a076f1881511c27b82a6db9e3f5db909f888bb563b26b855fc49dacbd0ef0b41f77af6c7638bf15721ff5085d012e916d4871592f
7
- data.tar.gz: 7520e06a5bdf8fb240538b9a333f265675cc4056bc24b88c06d0d8c2e7cd5185346be6268707fe00f7f41bf6f8c8d70abc3925e53ac6684889ef4dc9e3ef6afd
6
+ metadata.gz: eb0ffc8bac6c1c66b13ce67d89bac3fbd1c601754024c3e8455e194a35e58f3c515586aa0ffeee4e30985a6e140ce64724c0960dce8de67d8a3e0f0e912d3898
7
+ data.tar.gz: 4cfc9aa211ab10a7b0a0c222e94538311bd91950fa32fc0602e2535468df4c48158219cad2f2f6fee015f94a9b415c3a285406fcc66ab27676a6572492b2d7f9
data/bin/stackprof CHANGED
@@ -2,94 +2,129 @@
2
2
  require 'optparse'
3
3
  require 'stackprof'
4
4
 
5
- options = {}
5
+ if ARGV.first == "run"
6
+ ARGV.shift
7
+ env = {}
8
+ parser = OptionParser.new(ARGV) do |o|
9
+ o.banner = "Usage: stackprof run [--mode|--out|--interval] -- COMMAND"
10
+ o.banner = "Usage: stackprof [file.dump]+ [--text|--method=NAME|--callgrind|--graphviz]"
6
11
 
7
- parser = OptionParser.new(ARGV) do |o|
8
- o.banner = "Usage: stackprof [file.dump]+ [--text|--method=NAME|--callgrind|--graphviz]"
12
+ o.on('--mode', 'Mode of sampling: cpu, wall, object, default to wall') do |mode|
13
+ env["STACKPROF_MODE"] = mode
14
+ end
9
15
 
10
- o.on('--text', 'Text summary per method (default)'){ options[:format] = :text }
11
- o.on('--json', 'JSON output (use with web viewers)'){ options[:format] = :json }
12
- o.on('--files', 'List of files'){ |f| options[:format] = :files }
13
- o.on('--limit [num]', Integer, 'Limit --text, --files, or --graphviz output to N entries'){ |n| options[:limit] = n }
14
- o.on('--sort-total', "Sort --text or --files output on total samples\n\n"){ options[:sort] = true }
15
- o.on('--method [grep]', 'Zoom into specified method'){ |f| options[:format] = :method; options[:filter] = f }
16
- o.on('--file [grep]', "Show annotated code for specified file"){ |f| options[:format] = :file; options[:filter] = f }
17
- o.on('--walk', "Walk the stacktrace interactively\n\n"){ |f| options[:walk] = true }
18
- o.on('--callgrind', 'Callgrind output (use with kcachegrind, stackprof-gprof2dot.py)'){ options[:format] = :callgrind }
19
- o.on('--graphviz', "Graphviz output (use with dot)"){ options[:format] = :graphviz }
20
- o.on('--node-fraction [frac]', OptionParser::DecimalNumeric, 'Drop nodes representing less than [frac] fraction of samples'){ |n| options[:node_fraction] = n }
21
- o.on('--stackcollapse', 'stackcollapse.pl compatible output (use with stackprof-flamegraph.pl)'){ options[:format] = :stackcollapse }
22
- o.on('--timeline-flamegraph', "timeline-flamegraph output (js)"){ options[:format] = :timeline_flamegraph }
23
- o.on('--alphabetical-flamegraph', "alphabetical-flamegraph output (js)"){ options[:format] = :alphabetical_flamegraph }
24
- o.on('--flamegraph', "alias to --timeline-flamegraph"){ options[:format] = :timeline_flamegraph }
25
- o.on('--flamegraph-viewer [f.js]', String, "open html viewer for flamegraph output"){ |file|
26
- puts("open file://#{File.expand_path('../../lib/stackprof/flamegraph/viewer.html', __FILE__)}?data=#{File.expand_path(file)}")
27
- exit
28
- }
29
- o.on('--d3-flamegraph', "flamegraph output (html using d3-flame-graph)\n\n"){ options[:format] = :d3_flamegraph }
30
- o.on('--select-files []', String, 'Show results of matching files'){ |path| (options[:select_files] ||= []) << File.expand_path(path) }
31
- o.on('--reject-files []', String, 'Exclude results of matching files'){ |path| (options[:reject_files] ||= []) << File.expand_path(path) }
32
- o.on('--select-names []', Regexp, 'Show results of matching method names'){ |regexp| (options[:select_names] ||= []) << regexp }
33
- o.on('--reject-names []', Regexp, 'Exclude results of matching method names'){ |regexp| (options[:reject_names] ||= []) << regexp }
34
- o.on('--dump', 'Print marshaled profile dump (combine multiple profiles)'){ options[:format] = :dump }
35
- o.on('--debug', 'Pretty print raw profile data'){ options[:format] = :debug }
36
- end
16
+ o.on('--out', 'The target file, which will be overwritten. Defaults to a random temporary file') do |out|
17
+ env['STACKPROF_OUT'] = out
18
+ end
37
19
 
38
- parser.parse!
39
- parser.abort(parser.help) if ARGV.empty?
20
+ o.on('--interval', 'Mode-relative sample rate') do |interval|
21
+ env['STACKPROF_INTERVAL'] = Integer(interval).to_s
22
+ end
40
23
 
41
- reports = []
42
- while ARGV.size > 0
43
- begin
44
- file = ARGV.pop
45
- reports << StackProf::Report.from_file(file)
46
- rescue TypeError => e
47
- STDERR.puts "** error parsing #{file}: #{e.inspect}"
24
+ o.on('--raw', 'collects the extra data required by the --flamegraph and --stackcollapse report types') do
25
+ env['STACKPROF_RAW'] = '1'
26
+ end
27
+
28
+ o.on('--ignore-gc', 'Ignore garbage collection frames') do
29
+ env['STACKPROF_IGNORE_GC'] = '1'
30
+ end
48
31
  end
49
- end
50
- report = reports.inject(:+)
32
+ parser.parse!
33
+ parser.abort(parser.help) if ARGV.empty?
34
+ stackprof_path = File.expand_path('../lib', __dir__)
35
+ env['RUBYOPT'] = "-I #{stackprof_path} -r stackprof/autorun #{ENV['RUBYOPT']}"
36
+ Kernel.exec(env, *ARGV)
37
+ else
38
+ options = {}
51
39
 
52
- default_options = {
53
- :format => :text,
54
- :sort => false,
55
- :limit => 30
56
- }
40
+ parser = OptionParser.new(ARGV) do |o|
41
+ o.banner = "Usage: stackprof run [--mode|--out|--interval] -- COMMAND"
42
+ o.banner = "Usage: stackprof [file.dump]+ [--text|--method=NAME|--callgrind|--graphviz]"
57
43
 
58
- if options[:format] == :graphviz
59
- default_options[:limit] = 120
60
- default_options[:node_fraction] = 0.005
61
- end
44
+ o.on('--text', 'Text summary per method (default)'){ options[:format] = :text }
45
+ o.on('--json', 'JSON output (use with web viewers)'){ options[:format] = :json }
46
+ o.on('--files', 'List of files'){ |f| options[:format] = :files }
47
+ o.on('--limit [num]', Integer, 'Limit --text, --files, or --graphviz output to N entries'){ |n| options[:limit] = n }
48
+ o.on('--sort-total', "Sort --text or --files output on total samples\n\n"){ options[:sort] = true }
49
+ o.on('--method [grep]', 'Zoom into specified method'){ |f| options[:format] = :method; options[:filter] = f }
50
+ o.on('--file [grep]', "Show annotated code for specified file"){ |f| options[:format] = :file; options[:filter] = f }
51
+ o.on('--walk', "Walk the stacktrace interactively\n\n"){ |f| options[:walk] = true }
52
+ o.on('--callgrind', 'Callgrind output (use with kcachegrind, stackprof-gprof2dot.py)'){ options[:format] = :callgrind }
53
+ o.on('--graphviz', "Graphviz output (use with dot)"){ options[:format] = :graphviz }
54
+ o.on('--node-fraction [frac]', OptionParser::DecimalNumeric, 'Drop nodes representing less than [frac] fraction of samples'){ |n| options[:node_fraction] = n }
55
+ o.on('--stackcollapse', 'stackcollapse.pl compatible output (use with stackprof-flamegraph.pl)'){ options[:format] = :stackcollapse }
56
+ o.on('--timeline-flamegraph', "timeline-flamegraph output (js)"){ options[:format] = :timeline_flamegraph }
57
+ o.on('--alphabetical-flamegraph', "alphabetical-flamegraph output (js)"){ options[:format] = :alphabetical_flamegraph }
58
+ o.on('--flamegraph', "alias to --timeline-flamegraph"){ options[:format] = :timeline_flamegraph }
59
+ o.on('--flamegraph-viewer [f.js]', String, "open html viewer for flamegraph output"){ |file|
60
+ puts("open file://#{File.expand_path('../../lib/stackprof/flamegraph/viewer.html', __FILE__)}?data=#{File.expand_path(file)}")
61
+ exit
62
+ }
63
+ o.on('--d3-flamegraph', "flamegraph output (html using d3-flame-graph)\n\n"){ options[:format] = :d3_flamegraph }
64
+ o.on('--select-files []', String, 'Show results of matching files'){ |path| (options[:select_files] ||= []) << File.expand_path(path) }
65
+ o.on('--reject-files []', String, 'Exclude results of matching files'){ |path| (options[:reject_files] ||= []) << File.expand_path(path) }
66
+ o.on('--select-names []', Regexp, 'Show results of matching method names'){ |regexp| (options[:select_names] ||= []) << regexp }
67
+ o.on('--reject-names []', Regexp, 'Exclude results of matching method names'){ |regexp| (options[:reject_names] ||= []) << regexp }
68
+ o.on('--dump', 'Print marshaled profile dump (combine multiple profiles)'){ options[:format] = :dump }
69
+ o.on('--debug', 'Pretty print raw profile data'){ options[:format] = :debug }
70
+ end
62
71
 
63
- options = default_options.merge(options)
64
- options.delete(:limit) if options[:limit] == 0
72
+ parser.parse!
73
+ parser.abort(parser.help) if ARGV.empty?
65
74
 
66
- case options[:format]
67
- when :text
68
- report.print_text(options[:sort], options[:limit], options[:select_files], options[:reject_files], options[:select_names], options[:reject_names])
69
- when :json
70
- report.print_json
71
- when :debug
72
- report.print_debug
73
- when :dump
74
- report.print_dump
75
- when :callgrind
76
- report.print_callgrind
77
- when :graphviz
78
- report.print_graphviz(options)
79
- when :stackcollapse
80
- report.print_stackcollapse
81
- when :timeline_flamegraph
82
- report.print_timeline_flamegraph
83
- when :alphabetical_flamegraph
84
- report.print_alphabetical_flamegraph
85
- when :d3_flamegraph
86
- report.print_d3_flamegraph
87
- when :method
88
- options[:walk] ? report.walk_method(options[:filter]) : report.print_method(options[:filter])
89
- when :file
90
- report.print_file(options[:filter])
91
- when :files
92
- report.print_files(options[:sort], options[:limit])
93
- else
94
- raise ArgumentError, "unknown format: #{options[:format]}"
75
+ reports = []
76
+ while ARGV.size > 0
77
+ begin
78
+ file = ARGV.pop
79
+ reports << StackProf::Report.from_file(file)
80
+ rescue TypeError => e
81
+ STDERR.puts "** error parsing #{file}: #{e.inspect}"
82
+ end
83
+ end
84
+ report = reports.inject(:+)
85
+
86
+ default_options = {
87
+ :format => :text,
88
+ :sort => false,
89
+ :limit => 30
90
+ }
91
+
92
+ if options[:format] == :graphviz
93
+ default_options[:limit] = 120
94
+ default_options[:node_fraction] = 0.005
95
+ end
96
+
97
+ options = default_options.merge(options)
98
+ options.delete(:limit) if options[:limit] == 0
99
+
100
+ case options[:format]
101
+ when :text
102
+ report.print_text(options[:sort], options[:limit], options[:select_files], options[:reject_files], options[:select_names], options[:reject_names])
103
+ when :json
104
+ report.print_json
105
+ when :debug
106
+ report.print_debug
107
+ when :dump
108
+ report.print_dump
109
+ when :callgrind
110
+ report.print_callgrind
111
+ when :graphviz
112
+ report.print_graphviz(options)
113
+ when :stackcollapse
114
+ report.print_stackcollapse
115
+ when :timeline_flamegraph
116
+ report.print_timeline_flamegraph
117
+ when :alphabetical_flamegraph
118
+ report.print_alphabetical_flamegraph
119
+ when :d3_flamegraph
120
+ report.print_d3_flamegraph
121
+ when :method
122
+ options[:walk] ? report.walk_method(options[:filter]) : report.print_method(options[:filter])
123
+ when :file
124
+ report.print_file(options[:filter])
125
+ when :files
126
+ report.print_files(options[:sort], options[:limit])
127
+ else
128
+ raise ArgumentError, "unknown format: #{options[:format]}"
129
+ end
95
130
  end
@@ -0,0 +1,19 @@
1
+ require "stackprof"
2
+
3
+ options = {}
4
+ options[:mode] = ENV["STACKPROF_MODE"].to_sym if ENV.key?("STACKPROF_MODE")
5
+ options[:interval] = Integer(ENV["STACKPROF_INTERVAL"]) if ENV.key?("STACKPROF_INTERVAL")
6
+ options[:raw] = true if ENV["STACKPROF_RAW"]
7
+ options[:ignore_gc] = true if ENV["STACKPROF_IGNORE_GC"]
8
+
9
+ at_exit do
10
+ StackProf.stop
11
+ output_path = ENV.fetch("STACKPROF_OUT") do
12
+ require "tempfile"
13
+ Tempfile.create(["stackprof", ".dump"]).path
14
+ end
15
+ StackProf.results(output_path)
16
+ $stderr.puts("StackProf results dumped at: #{output_path}")
17
+ end
18
+
19
+ StackProf.start(**options)
data/lib/stackprof.rb CHANGED
@@ -9,7 +9,7 @@ if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
9
9
  end
10
10
 
11
11
  module StackProf
12
- VERSION = '0.2.21'
12
+ VERSION = '0.2.22'
13
13
  end
14
14
 
15
15
  StackProf.autoload :Report, "stackprof/report.rb"
data/stackprof.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'stackprof'
3
- s.version = '0.2.21'
3
+ s.version = '0.2.22'
4
4
  s.homepage = 'http://github.com/tmm1/stackprof'
5
5
 
6
6
  s.authors = 'Aman Gupta'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackprof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.21
4
+ version: 0.2.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aman Gupta
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-22 00:00:00.000000000 Z
11
+ date: 2022-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -76,6 +76,7 @@ files:
76
76
  - ext/stackprof/extconf.rb
77
77
  - ext/stackprof/stackprof.c
78
78
  - lib/stackprof.rb
79
+ - lib/stackprof/autorun.rb
79
80
  - lib/stackprof/flamegraph/flamegraph.js
80
81
  - lib/stackprof/flamegraph/viewer.html
81
82
  - lib/stackprof/middleware.rb
@@ -98,10 +99,10 @@ licenses:
98
99
  - MIT
99
100
  metadata:
100
101
  bug_tracker_uri: https://github.com/tmm1/stackprof/issues
101
- changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.21/CHANGELOG.md
102
- documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.21
103
- source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.21
104
- post_install_message:
102
+ changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.22/CHANGELOG.md
103
+ documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.22
104
+ source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.22
105
+ post_install_message:
105
106
  rdoc_options: []
106
107
  require_paths:
107
108
  - lib
@@ -116,8 +117,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
117
  - !ruby/object:Gem::Version
117
118
  version: '0'
118
119
  requirements: []
119
- rubygems_version: 3.4.0.dev
120
- signing_key:
120
+ rubygems_version: 3.0.3.1
121
+ signing_key:
121
122
  specification_version: 4
122
123
  summary: sampling callstack-profiler for ruby 2.2+
123
124
  test_files: []