fluent-rubyprof 0.0.2 → 0.2.0
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 +5 -5
- data/CHANGELOG.md +12 -0
- data/README.md +17 -10
- data/bin/fluent-rubyprof +1 -0
- data/fluent-rubyprof.gemspec +1 -1
- data/lib/fluent/rubyprof.rb +108 -76
- data/spec/fluent-rubyprof/rubyprof_spec.rb +39 -14
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3e9007c7738a7ea50f10d65f25839bcea13a2f1444d2e238d0c0404d40239dd6
|
4
|
+
data.tar.gz: d708dd7e5d27e9938cdbb998e146fa5a8a7a731f06afe998c769e3da43567804
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3261542f9662711b20ce5ddd0744be04295c3167ca6737669cf4cfc87037cb212e3a25e88d8aea72aaf64eb8e73e8690a575cdc7d60ad66f5326e9aa20024025
|
7
|
+
data.tar.gz: 96ecae12b9e548bd4793cd27cf577b5f96fa569aec48a15461bb83d9447aed88603b46a1c213389e8a00e93789420b399d98d685d4987622319be2eb5b598d59
|
data/CHANGELOG.md
CHANGED
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
|
|
data/bin/fluent-rubyprof
CHANGED
data/fluent-rubyprof.gemspec
CHANGED
@@ -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
|
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}
|
data/lib/fluent/rubyprof.rb
CHANGED
@@ -1,89 +1,121 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'drb/drb'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
51
|
-
|
44
|
+
op.on('-p', '--port PORT', "debug_agent tcp port (default: #{opts[:host]})", Integer) {|v|
|
45
|
+
opts[:port] = v
|
46
|
+
}
|
52
47
|
|
53
|
-
|
54
|
-
|
48
|
+
op.on('-u', '--unix PATH', "use unix socket instead of tcp") {|v|
|
49
|
+
opts[:unix] = v
|
50
|
+
}
|
55
51
|
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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
|
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
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
14
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
26
|
-
|
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
|
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:
|
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.
|
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
|