fluent-rubyprof 0.0.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a39b11208c6b56b2e344c89bbf955dfc645c4c94
4
- data.tar.gz: 8ff204c9322cd2bf16d4ce9308e5e2538f7e881b
2
+ SHA256:
3
+ metadata.gz: 3e9007c7738a7ea50f10d65f25839bcea13a2f1444d2e238d0c0404d40239dd6
4
+ data.tar.gz: d708dd7e5d27e9938cdbb998e146fa5a8a7a731f06afe998c769e3da43567804
5
5
  SHA512:
6
- metadata.gz: 81de9e6eb2a8fb23023654c86b4e87b95f9b96595113fc5c556f68f84a7840baf1f97b229b3c447d6e394dd241158036c967865fc4124ff4246e4f9558c39198
7
- data.tar.gz: ecde003870cd35f7fa592c7f2795619538137a298b6c766a79e357cf28d19149b7c5e19214f70a731bf12132a4d2a2bbbc2b75c76b7327bd4aa8146a03cdcb90
6
+ metadata.gz: 3261542f9662711b20ce5ddd0744be04295c3167ca6737669cf4cfc87037cb212e3a25e88d8aea72aaf64eb8e73e8690a575cdc7d60ad66f5326e9aa20024025
7
+ data.tar.gz: 96ecae12b9e548bd4793cd27cf577b5f96fa569aec48a15461bb83d9447aed88603b46a1c213389e8a00e93789420b399d98d685d4987622319be2eb5b598d59
@@ -1,3 +1,15 @@
1
+ # 0.2.0 (2018/11/21)
2
+
3
+ Enhancements:
4
+
5
+ * Add `--printer` option (thanks to Fujimoto Seiji)
6
+
7
+ # 0.1.0 (2014/08/01)
8
+
9
+ Enhancements:
10
+
11
+ * Support ruby-prof measure_mode
12
+
1
13
  # 0.0.2 (2014/08/01)
2
14
 
3
15
  Changes:
data/README.md CHANGED
@@ -1,12 +1,6 @@
1
1
  # Fluent::Rubyprof
2
2
 
3
- Using fluent-rubyprof, you can start and stop ruby-prof dynamically from outside of fluentd without any configuration changes.
4
-
5
- ## Installation
6
-
7
- ```
8
- $ fluent-gem install fluent-rubyprof
9
- ```
3
+ Using fluent-rubyprof, you can start and stop [ruby-prof](https://github.com/ruby-prof/ruby-prof) dynamically from outside of fluentd without any configuration changes.
10
4
 
11
5
  ## Prerequisite
12
6
 
@@ -15,6 +9,7 @@ $ fluent-gem install fluent-rubyprof
15
9
  ```
16
10
  <source>
17
11
  type debug_agent
12
+ port 24230
18
13
  </source>
19
14
  ```
20
15
 
@@ -24,18 +19,24 @@ And, `ruby-prof` gem is required.
24
19
  $ fluent-gem install ruby-prof
25
20
  ```
26
21
 
22
+ ## Installation
23
+
24
+ ```
25
+ $ fluent-gem install fluent-rubyprof
26
+ ```
27
+
27
28
  ## Usage
28
29
 
29
30
  Start
30
31
 
31
32
  ```
32
- $ fluent-rubyprof start
33
+ $ fluent-rubyprof start -h localhost -p 24230
33
34
  ```
34
35
 
35
36
  Stop and write a profiling result.
36
37
 
37
38
  ```
38
- $ fluent-rubyprof stop -o /tmp/fluent-rubyprof.txt
39
+ $ fluent-rubyprof stop -h localhost -p 24230 -o /tmp/fluent-rubyprof.txt
39
40
  ```
40
41
 
41
42
  ## Options
@@ -43,9 +44,15 @@ $ fluent-rubyprof stop -o /tmp/fluent-rubyprof.txt
43
44
  |parameter|description|default|
44
45
  |---|---|---|
45
46
  |-h, --host HOST|fluent host|127.0.0.1|
46
- |-p, --port PORT|debug_agent|24230|
47
+ |-p, --port PORT|debug_agent port|24230|
47
48
  |-u, --unix PATH|use unix socket instead of tcp||
48
49
  |-o, --output PATH|output file|/tmp/fluent-rubyprof.txt|
50
+ |-m, --measure_mode MEASURE_MODE|ruby-prof measure mode. See [ruby-prof#measurements](https://github.com/ruby-prof/ruby-prof#measurements)|PROCESS_TIME|
51
+ |-P, --printer PRINTER|ruby-prof print format. See [ruby-prof#printers](https://github.com/ruby-prof/ruby-prof#printers)|flat|
52
+
53
+ ## Further Reading
54
+
55
+ * [Fluentd の debug_agent 経由で ruby-prof を起動する](http://qiita.com/sonots/items/749280547176d82f3e2c) (Japanese)
49
56
 
50
57
  ## ChangeLog
51
58
 
@@ -4,3 +4,4 @@ require 'rubygems' unless defined?(gem)
4
4
  here = File.dirname(__FILE__)
5
5
  $LOAD_PATH << File.expand_path(File.join(here, '..', 'lib'))
6
6
  require 'fluent/rubyprof'
7
+ Fluent::Rubyprof.new.run
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "fluent-rubyprof"
7
- spec.version = "0.0.2"
7
+ spec.version = "0.2.0"
8
8
  spec.authors = ["Naotoshi Seo"]
9
9
  spec.email = ["sonots@gmail.com"]
10
10
  spec.summary = %q{Tools for start/stop ruby-prof dynamically from outside of fluentd}
@@ -1,89 +1,121 @@
1
1
  require 'optparse'
2
2
  require 'drb/drb'
3
3
 
4
- def parse_options
5
- op = OptionParser.new
6
- op.banner += ' <start/stop> [output_file]'
7
-
8
- (class<<self;self;end).module_eval do
9
- define_method(:usage) do |msg|
10
- puts op.to_s
11
- puts "error: #{msg}" if msg
12
- exit 1
13
- end
14
- end
4
+ module Fluent
5
+ class Rubyprof
6
+
7
+ PRINTERS = {
8
+ 'flat' => 'FlatPrinter',
9
+ 'flat_with_line_numbers' => 'FlatPrinterWithLineNumbers',
10
+ 'graph' => 'GraphPrinter',
11
+ 'graph_html' => 'GraphHtmlPrinter',
12
+ 'call_tree' => 'CallTreePrinter',
13
+ 'call_stack' => 'CallStackPrinter',
14
+ 'dot' => 'DotPrinter',
15
+ 'multi' => 'MultiPrinter',
16
+ }
17
+
18
+ def parse_options(argv = ARGV)
19
+ op = OptionParser.new
20
+ op.banner += ' <start/stop> [output_file]'
21
+
22
+ (class<<self;self;end).module_eval do
23
+ define_method(:usage) do |msg|
24
+ puts op.to_s
25
+ puts "error: #{msg}" if msg
26
+ exit 1
27
+ end
28
+ end
29
+
30
+ opts = {
31
+ host: '127.0.0.1',
32
+ port: 24230,
33
+ unix: nil,
34
+ command: nil, # start or stop
35
+ output: '/tmp/fluent-rubyprof.txt',
36
+ measure_mode: 'PROCESS_TIME',
37
+ printer: 'flat',
38
+ }
15
39
 
16
- opts = {
17
- host: '127.0.0.1',
18
- port: 24230,
19
- unix: nil,
20
- command: nil, # start or stop
21
- output: '/tmp/fluent-rubyprof.txt'
22
- }
23
-
24
- op.on('-h', '--host HOST', "fluent host (default: #{opts[:host]})") {|v|
25
- opts[:host] = v
26
- }
27
-
28
- op.on('-p', '--port PORT', "debug_agent tcp port (default: #{opts[:host]})", Integer) {|v|
29
- opts[:port] = v
30
- }
31
-
32
- op.on('-u', '--unix PATH', "use unix socket instead of tcp") {|v|
33
- opts[:unix] = v
34
- }
35
-
36
- op.on('-o', '--output PATH', "output path (default: #{opts[:output]})") {|v|
37
- opts[:output] = v
38
- }
39
-
40
- begin
41
- op.parse!(ARGV)
42
- opts[:command] = ARGV.shift
43
- unless %w[start stop].include?(opts[:command])
44
- usage "`start` or `stop` must be specified as the 1st argument"
45
- end
46
- rescue
47
- usage $!.to_s
48
- end
40
+ op.on('-h', '--host HOST', "fluent host (default: #{opts[:host]})") {|v|
41
+ opts[:host] = v
42
+ }
49
43
 
50
- opts
51
- end
44
+ op.on('-p', '--port PORT', "debug_agent tcp port (default: #{opts[:host]})", Integer) {|v|
45
+ opts[:port] = v
46
+ }
52
47
 
53
- def main
54
- opts = parse_options
48
+ op.on('-u', '--unix PATH', "use unix socket instead of tcp") {|v|
49
+ opts[:unix] = v
50
+ }
55
51
 
56
- unless opts[:unix].nil?
57
- uri = "drbunix:#{opts[:unix]}"
58
- else
59
- uri = "druby://#{opts[:host]}:#{opts[:port]}"
60
- end
52
+ op.on('-o', '--output PATH', "output path (default: #{opts[:output]})") {|v|
53
+ opts[:output] = v
54
+ }
61
55
 
62
- $remote_engine = DRb::DRbObject.new_with_uri(uri)
63
-
64
- case opts[:command]
65
- when 'start'
66
- remote_code = <<-CODE
67
- require 'ruby-prof'
68
- RubyProf.start
69
- CODE
70
- when 'stop'
71
- remote_code = <<-"CODE"
72
- result = RubyProf.stop
73
- File.open('#{opts[:output]}', 'w') {|f|
74
- RubyProf::FlatPrinter.new(result).print(f)
56
+ op.on('-m', '--measure_mode MEASURE_MODE', "ruby-prof measure mode (default: #{opts[:measure_mode]})") {|v|
57
+ opts[:measure_mode] = v
75
58
  }
76
- CODE
77
- end
78
59
 
79
- $remote_engine.method_missing(:instance_eval, remote_code)
60
+ op.on('-P', '--printer PRINTER', PRINTERS.keys,
61
+ "ruby-prof print format (default: #{opts[:printer]})",
62
+ "currently one of: #{PRINTERS.keys.join(', ')}") {|v|
63
+ opts[:printer] = v
64
+ }
65
+ op.parse!(argv)
66
+
67
+ opts[:command] = argv.shift
68
+ unless %w[start stop].include?(opts[:command])
69
+ raise OptionParser::InvalidOption.new("`start` or `stop` must be specified as the 1st argument")
70
+ end
71
+
72
+ measure_modes = %w[PROCESS_TIME WALL_TIME CPU_TIME ALLOCATIONS MEMORY GC_RUNS GC_TIME]
73
+ unless measure_modes.include?(opts[:measure_mode])
74
+ raise OptionParser::InvalidOption.new("-m allows one of #{measure_modes.join(', ')}")
75
+ end
80
76
 
81
- case opts[:command]
82
- when 'start'
83
- $stdout.puts 'fluent-rubyprof: started'
84
- when 'stop'
85
- $stdout.puts "fluent-rubyprof: outputs to #{opts[:output]}"
77
+ opts
78
+ end
79
+
80
+ def run
81
+ begin
82
+ opts = parse_options
83
+ rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
84
+ usage e.message
85
+ end
86
+
87
+ unless opts[:unix].nil?
88
+ uri = "drbunix:#{opts[:unix]}"
89
+ else
90
+ uri = "druby://#{opts[:host]}:#{opts[:port]}"
91
+ end
92
+
93
+ $remote_engine = DRb::DRbObject.new_with_uri(uri)
94
+
95
+ case opts[:command]
96
+ when 'start'
97
+ remote_code = <<-CODE
98
+ require 'ruby-prof'
99
+ RubyProf.measure_mode = eval("RubyProf::#{opts[:measure_mode]}")
100
+ RubyProf.start
101
+ CODE
102
+ when 'stop'
103
+ remote_code = <<-"CODE"
104
+ result = RubyProf.stop
105
+ File.open('#{opts[:output]}', 'w') {|f|
106
+ RubyProf::#{PRINTERS[opts[:printer]]}.new(result).print(f)
107
+ }
108
+ CODE
109
+ end
110
+
111
+ $remote_engine.method_missing(:instance_eval, remote_code)
112
+
113
+ case opts[:command]
114
+ when 'start'
115
+ $stdout.puts 'fluent-rubyprof: started'
116
+ when 'stop'
117
+ $stdout.puts "fluent-rubyprof: outputs to #{opts[:output]}"
118
+ end
119
+ end
86
120
  end
87
121
  end
88
-
89
- main
@@ -1,28 +1,53 @@
1
1
  require 'json'
2
2
  require 'spec_helper'
3
+ require 'fluent/rubyprof'
3
4
 
4
- describe 'Fluent::Rubyprof' do
5
+ describe Fluent::Rubyprof do
5
6
  CONFIG_PATH = File.join(File.dirname(__FILE__), 'fluent.conf')
6
7
  BIN_DIR = File.join(ROOT, 'bin')
7
8
  OUTPUT_FILE = File.join(File.dirname(__FILE__), 'test.txt')
8
9
 
9
- before :all do
10
- @fluentd_pid = spawn('fluentd', '-c', CONFIG_PATH, out: '/dev/null')
11
- sleep 2
10
+ context '#parse_options' do
11
+ it 'incorrect subcommand' do
12
+ expect { Fluent::Rubyprof.new.parse_options(['foo']) }.to raise_error(OptionParser::InvalidOption)
13
+ end
12
14
 
13
- system("#{File.join(BIN_DIR, 'fluent-rubyprof')} start")
14
- sleep 2
15
+ it 'correct measure_mode' do
16
+ expect { Fluent::Rubyprof.new.parse_options(['start', '-m', 'CPU_TIME']) }.not_to raise_error
17
+ end
15
18
 
16
- system("#{File.join(BIN_DIR, 'fluent-rubyprof')} stop -o #{OUTPUT_FILE}")
17
- sleep 1
18
- end
19
+ it 'incorrect measure_mode' do
20
+ expect { Fluent::Rubyprof.new.parse_options(['start', '-m', 'foo']) }.to raise_error(OptionParser::InvalidOption)
21
+ end
22
+
23
+ it 'correct printer' do
24
+ expect { Fluent::Rubyprof.new.parse_options(['start', '-P', 'graph']) }.not_to raise_error
25
+ end
19
26
 
20
- after :all do
21
- Process.kill(:TERM, @fluentd_pid)
22
- Process.waitall
27
+ it 'incorrect printer' do
28
+ expect { Fluent::Rubyprof.new.parse_options(['start', '-P', 'bar']) }.to raise_error(OptionParser::InvalidArgument)
29
+ end
23
30
  end
24
31
 
25
- it 'outputs profiling result' do
26
- expect(File.size?(OUTPUT_FILE)).to be_truthy
32
+ context 'profiling' do
33
+ before :all do
34
+ @fluentd_pid = spawn('fluentd', '-c', CONFIG_PATH, out: '/dev/null')
35
+ sleep 2
36
+
37
+ system("#{File.join(BIN_DIR, 'fluent-rubyprof')} start")
38
+ sleep 2
39
+
40
+ system("#{File.join(BIN_DIR, 'fluent-rubyprof')} stop -o #{OUTPUT_FILE}")
41
+ sleep 1
42
+ end
43
+
44
+ after :all do
45
+ Process.kill(:TERM, @fluentd_pid)
46
+ Process.waitall
47
+ end
48
+
49
+ it 'should output' do
50
+ expect(File.size?(OUTPUT_FILE)).to be_truthy
51
+ end
27
52
  end
28
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-rubyprof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naotoshi Seo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-01 00:00:00.000000000 Z
11
+ date: 2018-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
94
  version: '0'
95
95
  requirements: []
96
96
  rubyforge_project:
97
- rubygems_version: 2.2.0
97
+ rubygems_version: 2.7.4
98
98
  signing_key:
99
99
  specification_version: 4
100
100
  summary: Tools for start/stop ruby-prof dynamically from outside of fluentd