perfmonger 0.11.2 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -5
- data/NEWS +38 -1
- data/Rakefile +18 -7
- data/core/Makefile +20 -21
- data/core/build.sh +4 -6
- data/core/{perfmonger-player.go → cmd/perfmonger-player/perfmonger-player.go} +53 -10
- data/core/cmd/perfmonger-plot-formatter/README.md +24 -0
- data/core/{perfmonger-plot-formatter.go → cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go} +116 -3
- data/core/{perfmonger-recorder.go → cmd/perfmonger-recorder/perfmonger-recorder.go} +6 -0
- data/core/{perfmonger-summarizer.go → cmd/perfmonger-summarizer/perfmonger-summarizer.go} +4 -2
- data/core/{perfmonger-viewer.go → cmd/perfmonger-viewer/perfmonger-viewer.go} +0 -0
- data/core/go.mod +10 -0
- data/core/go.sum +17 -0
- data/core/subsystem/Makefile +4 -0
- data/core/subsystem/perfmonger_linux.go +97 -0
- data/core/subsystem/perfmonger_linux_test.go +40 -0
- data/core/subsystem/stat.go +72 -0
- data/core/subsystem/stat_test.go +9 -0
- data/core/subsystem/usage.go +80 -0
- data/core/utils.go +2 -2
- data/lib/exec/perfmonger-player_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-player_linux_amd64 +0 -0
- data/lib/exec/perfmonger-plot-formatter_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-plot-formatter_linux_amd64 +0 -0
- data/lib/exec/perfmonger-recorder_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-recorder_linux_amd64 +0 -0
- data/lib/exec/perfmonger-summarizer_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-summarizer_linux_amd64 +0 -0
- data/lib/exec/perfmonger-viewer_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-viewer_linux_amd64 +0 -0
- data/lib/perfmonger/command/play.rb +10 -0
- data/lib/perfmonger/command/plot.rb +146 -3
- data/lib/perfmonger/command/record.rb +23 -2
- data/lib/perfmonger/command/record_option.rb +16 -0
- data/lib/perfmonger/version.rb +1 -1
- data/misc/werker-box/Dockerfile +10 -9
- data/misc/werker-box/build-push.sh +2 -2
- data/wercker.yml +10 -10
- metadata +12 -27
data/core/utils.go
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
package
|
1
|
+
package core
|
2
2
|
|
3
3
|
import (
|
4
4
|
"bufio"
|
@@ -6,7 +6,7 @@ import (
|
|
6
6
|
"io"
|
7
7
|
)
|
8
8
|
|
9
|
-
func
|
9
|
+
func NewPerfmongerLogReader(source io.Reader) io.Reader {
|
10
10
|
var ret io.Reader
|
11
11
|
reader := bufio.NewReader(source)
|
12
12
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -26,6 +26,10 @@ EOS
|
|
26
26
|
@pretty = true
|
27
27
|
end
|
28
28
|
|
29
|
+
@disk_only_regex = nil
|
30
|
+
@parser.on('--disk-only REGEX', "Select disk devices that matches REGEX (Ex. 'sd[b-d]')") do |regex|
|
31
|
+
@disk_only_regex = regex
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
def parse_args(argv)
|
@@ -62,6 +66,12 @@ EOS
|
|
62
66
|
if @pretty
|
63
67
|
cmd << "-pretty"
|
64
68
|
end
|
69
|
+
|
70
|
+
if @disk_only_regex
|
71
|
+
cmd << "-disk-only"
|
72
|
+
cmd << @disk_only_regex
|
73
|
+
end
|
74
|
+
|
65
75
|
cmd << @logfile
|
66
76
|
|
67
77
|
Process.exec(*cmd)
|
@@ -30,6 +30,7 @@ EOS
|
|
30
30
|
@disk_plot_write = true
|
31
31
|
@disk_numkey_threshold = 10
|
32
32
|
@plot_iops_max = nil
|
33
|
+
@gnuplot_bin = `which gnuplot`
|
33
34
|
end
|
34
35
|
|
35
36
|
def parse_args(argv)
|
@@ -47,6 +48,10 @@ EOS
|
|
47
48
|
@output_dir = dir
|
48
49
|
end
|
49
50
|
|
51
|
+
@parser.on('--with-gnuplot GNUPLOT_BIN') do |gnuplot_bin|
|
52
|
+
@gnuplot_bin = gnuplot_bin
|
53
|
+
end
|
54
|
+
|
50
55
|
@parser.on('-T', '--output-type TYPE', 'Available: pdf, png') do |typ|
|
51
56
|
unless ['pdf', 'png'].include?(typ)
|
52
57
|
puts("ERROR: non supported image type: #{typ}")
|
@@ -119,13 +124,14 @@ EOS
|
|
119
124
|
end
|
120
125
|
|
121
126
|
def run(argv)
|
122
|
-
parse_args(argv)
|
123
127
|
unless system('which gnuplot >/dev/null 2>&1')
|
124
128
|
puts("ERROR: gnuplot not found")
|
125
129
|
puts(@parser.help)
|
126
130
|
exit(false)
|
127
131
|
end
|
128
132
|
|
133
|
+
parse_args(argv)
|
134
|
+
|
129
135
|
unless system('gnuplot -e "set terminal" < /dev/null 2>&1 | grep pdfcairo >/dev/null 2>&1')
|
130
136
|
puts("ERROR: pdfcairo is not supported by installed gnuplot")
|
131
137
|
puts("ERROR: PerfMonger requires pdfcairo-supported gnuplot")
|
@@ -139,10 +145,13 @@ EOS
|
|
139
145
|
|
140
146
|
@disk_dat = File.expand_path("disk.dat", @tmpdir)
|
141
147
|
@cpu_dat = File.expand_path("cpu.dat", @tmpdir)
|
148
|
+
@mem_dat = File.expand_path("mem.dat", @tmpdir)
|
142
149
|
|
143
150
|
meta_json = nil
|
144
|
-
cmd = [formatter_bin, "-perfmonger", @data_file,
|
145
|
-
|
151
|
+
cmd = [formatter_bin, "-perfmonger", @data_file,
|
152
|
+
"-cpufile", @cpu_dat,
|
153
|
+
"-diskfile", @disk_dat,
|
154
|
+
"-memfile", @mem_dat]
|
146
155
|
if @disk_only_regex
|
147
156
|
cmd << "-disk-only"
|
148
157
|
cmd << @disk_only
|
@@ -158,6 +167,7 @@ EOS
|
|
158
167
|
|
159
168
|
plot_disk(meta)
|
160
169
|
plot_cpu(meta)
|
170
|
+
plot_mem(meta)
|
161
171
|
|
162
172
|
FileUtils.rm_rf(@tmpdir)
|
163
173
|
|
@@ -502,6 +512,139 @@ EOS
|
|
502
512
|
end
|
503
513
|
end # def
|
504
514
|
|
515
|
+
def plot_mem(meta)
|
516
|
+
pdf_filename = @output_prefix + 'mem.pdf'
|
517
|
+
gp_filename = @output_prefix + 'mem.gp'
|
518
|
+
dat_filename = @output_prefix + 'mem.dat'
|
519
|
+
|
520
|
+
if @output_type != 'pdf'
|
521
|
+
img_filename = @output_prefix + 'cpu.' + @output_type
|
522
|
+
else
|
523
|
+
img_filename = nil
|
524
|
+
end
|
525
|
+
|
526
|
+
start_time = meta["start_time"]
|
527
|
+
end_time = meta["end_time"]
|
528
|
+
|
529
|
+
mem_scaling = 2.0**20 # KB -> GB
|
530
|
+
|
531
|
+
# "elapsed_time", // 1
|
532
|
+
# "mem_total", // 2
|
533
|
+
# "mem_used", // 3
|
534
|
+
# "mem_free", // 4
|
535
|
+
# "buffers", // 5
|
536
|
+
# "cached", // 6
|
537
|
+
# "swap_cached", // 7
|
538
|
+
# "active", // 8
|
539
|
+
# "inactive", // 9
|
540
|
+
# "swap_total", // 10
|
541
|
+
# "swap_free", // 11
|
542
|
+
# "dirty", // 12
|
543
|
+
# "writeback", // 13
|
544
|
+
# "anon_pages", // 14
|
545
|
+
# "mapped", // 15
|
546
|
+
# "shmem", // 16
|
547
|
+
# "slab", // 17
|
548
|
+
# "s_reclaimable", // 18
|
549
|
+
# "s_unreclaim", // 19
|
550
|
+
# "kernel_stack", // 20
|
551
|
+
# "page_tables", // 21
|
552
|
+
# "nfs_unstable", // 22
|
553
|
+
# "bounce", // 23
|
554
|
+
# "commit_limit", // 24
|
555
|
+
# "committed_as", // 25
|
556
|
+
# "anon_huge_pages", // 26
|
557
|
+
# "huge_pages_total", // 27
|
558
|
+
# "huge_pages_free", // 28
|
559
|
+
# "huge_pages_rsvd", // 29
|
560
|
+
# "huge_pages_surp"}, // 30
|
561
|
+
# "hugepagesize"}, // 31
|
562
|
+
|
563
|
+
Dir.chdir(@tmpdir) do
|
564
|
+
total = `tail -n+2 #{dat_filename}|head -n1`.split[1].to_f
|
565
|
+
if total == 0.0
|
566
|
+
raise RuntimeError.new("Failed to get MemTotal value from mem.dat file: #{dat_filename}")
|
567
|
+
end
|
568
|
+
|
569
|
+
gpfile = File.open(gp_filename, 'w')
|
570
|
+
|
571
|
+
pdf_file = File.join(@output_dir, "mem.pdf")
|
572
|
+
gpfile.puts <<EOS
|
573
|
+
set term pdfcairo enhanced color size 6in,2.5in
|
574
|
+
set title "Memory usage"
|
575
|
+
set output "#{pdf_filename}"
|
576
|
+
set key outside center bottom horizontal
|
577
|
+
set size 1.0, 1.0
|
578
|
+
|
579
|
+
set xlabel "elapsed time [sec]"
|
580
|
+
set ylabel "memory usage [GB]"
|
581
|
+
|
582
|
+
# scaling
|
583
|
+
s = #{mem_scaling}
|
584
|
+
|
585
|
+
set grid
|
586
|
+
set xrange [#{@offset_time}:#{end_time - start_time}]
|
587
|
+
set yrange [0:#{total * 1.2}/s]
|
588
|
+
|
589
|
+
# line styles
|
590
|
+
set style line 1 lt 1 lc rgb '#66C2A5' # teal
|
591
|
+
set style line 2 lt 1 lc rgb '#FC8D62' # orange
|
592
|
+
set style line 3 lt 1 lc rgb '#8DA0CB' # lilac
|
593
|
+
set style line 4 lt 1 lc rgb '#E78AC3' # magentat
|
594
|
+
set style line 5 lt 1 lc rgb '#A6D854' # lime green
|
595
|
+
set style line 6 lt 1 lc rgb '#FFD92F' # banana
|
596
|
+
set style line 7 lt 1 lc rgb '#E5C494' # tan
|
597
|
+
set style line 8 lt 1 lc rgb '#B3B3B3' # grey
|
598
|
+
|
599
|
+
# palette
|
600
|
+
set palette maxcolors 8
|
601
|
+
set palette defined ( 0 '#66C2A5',\
|
602
|
+
1 '#FC8D62',\
|
603
|
+
2 '#8DA0CB',\
|
604
|
+
3 '#E78AC3',\
|
605
|
+
4 '#A6D854',\
|
606
|
+
5 '#FFD92F',\
|
607
|
+
6 '#E5C494',\
|
608
|
+
7 '#B3B3B3' )
|
609
|
+
|
610
|
+
used(total, free, cached, buffers, srecl) = \\
|
611
|
+
( (total - free - cache(cached, srecl) - buffers < 0) ? \\
|
612
|
+
(total - free) : \\
|
613
|
+
(total - free - cache(cached, srecl) - buffers) )
|
614
|
+
|
615
|
+
cache(cached, srecl) = cached + srecl
|
616
|
+
|
617
|
+
plot "#{dat_filename}" usi 1:($4/s+$5/s+cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 8 ti "free", \\
|
618
|
+
"#{dat_filename}" usi 1:($5/s+cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 3 ti "buffers", \\
|
619
|
+
"#{dat_filename}" usi 1:(cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 5 ti "cached", \\
|
620
|
+
"#{dat_filename}" usi 1:($16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 6 ti "shared", \\
|
621
|
+
"#{dat_filename}" usi 1:(used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 2 ti "used", \\
|
622
|
+
"#{dat_filename}" usi 1:(($27-$28)*$31/s) wi lines dt (4,4) lc rgb 'black' lw 2.5 ti 'used (hugepage)'
|
623
|
+
|
624
|
+
EOS
|
625
|
+
|
626
|
+
gpfile.close
|
627
|
+
system("gnuplot #{gpfile.path}")
|
628
|
+
|
629
|
+
if @output_type != 'pdf'
|
630
|
+
system("convert -density 150 -background white #{pdf_filename} #{img_filename}")
|
631
|
+
end
|
632
|
+
end # chdir
|
633
|
+
|
634
|
+
copy_targets = []
|
635
|
+
copy_targets << pdf_filename
|
636
|
+
copy_targets << img_filename if img_filename
|
637
|
+
|
638
|
+
if @save_gpfiles
|
639
|
+
copy_targets << gp_filename
|
640
|
+
copy_targets << dat_filename
|
641
|
+
end
|
642
|
+
|
643
|
+
copy_targets.each do |target|
|
644
|
+
FileUtils.copy(File.join(@tmpdir, target), @output_dir)
|
645
|
+
end
|
646
|
+
end # def
|
647
|
+
|
505
648
|
private
|
506
649
|
def factors(n)
|
507
650
|
(2..([n, n / 2].max).to_i).select do |x|
|
@@ -31,7 +31,8 @@ class RecordCommand < BaseCommand
|
|
31
31
|
if @option.kill
|
32
32
|
unless session_pid
|
33
33
|
# There is nothing to be killed
|
34
|
-
|
34
|
+
$stderr.puts("[ERROR] No perfmonger record session is running.")
|
35
|
+
return false
|
35
36
|
end
|
36
37
|
|
37
38
|
begin
|
@@ -44,12 +45,32 @@ class RecordCommand < BaseCommand
|
|
44
45
|
f.flock(File::LOCK_UN)
|
45
46
|
end
|
46
47
|
end
|
48
|
+
|
49
|
+
# wait until the process surely exits
|
50
|
+
sleeptime = 0.05
|
51
|
+
try = 0
|
52
|
+
while true
|
53
|
+
begin
|
54
|
+
Process.kill(:INT, session_pid)
|
55
|
+
rescue Errno::ESRCH
|
56
|
+
# no such process
|
57
|
+
break
|
58
|
+
end
|
59
|
+
sleep(sleeptime)
|
60
|
+
sleeptime *= 2
|
61
|
+
try += 1
|
62
|
+
if try >= 5
|
63
|
+
$stderr.puts("[ERROR] Cannot stop perfmonger record session correctly. PID=#{session_pid}")
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
47
68
|
return true
|
48
69
|
end
|
49
70
|
|
50
71
|
if @option.status
|
51
72
|
unless session_pid
|
52
|
-
puts "[ERROR] No perfmonger
|
73
|
+
puts "[ERROR] No perfmonger record session is running."
|
53
74
|
return false
|
54
75
|
end
|
55
76
|
|
@@ -63,6 +63,12 @@ class RecordOption
|
|
63
63
|
if @no_intr
|
64
64
|
cmd << "-no-intr"
|
65
65
|
end
|
66
|
+
if @no_net
|
67
|
+
cmd << "-no-net"
|
68
|
+
end
|
69
|
+
if @no_mem
|
70
|
+
cmd << "-no-mem"
|
71
|
+
end
|
66
72
|
if @devices.size > 0
|
67
73
|
cmd << "-disks"
|
68
74
|
cmd << @devices.join(",")
|
@@ -98,6 +104,8 @@ class RecordOption
|
|
98
104
|
@no_cpu = false
|
99
105
|
@no_disk = false
|
100
106
|
@no_intr = true
|
107
|
+
@no_net = true
|
108
|
+
@no_mem = false
|
101
109
|
@devices = []
|
102
110
|
@logfile = "perfmonger.pgr"
|
103
111
|
@logfile_set = false
|
@@ -141,6 +149,14 @@ class RecordOption
|
|
141
149
|
@no_cpu = true
|
142
150
|
end
|
143
151
|
|
152
|
+
@parser.on('--no-net', 'Suppress recording network usage') do
|
153
|
+
@no_net = false
|
154
|
+
end
|
155
|
+
|
156
|
+
@parser.on('--no-mem', 'Suppress recording memory usage') do
|
157
|
+
@no_mem = true
|
158
|
+
end
|
159
|
+
|
144
160
|
@parser.on('-l', '--logfile FILE') do |file|
|
145
161
|
@logfile = file
|
146
162
|
@logfile_set = true
|
data/lib/perfmonger/version.rb
CHANGED
data/misc/werker-box/Dockerfile
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
FROM golang:1.
|
1
|
+
FROM golang:1.14
|
2
2
|
|
3
3
|
WORKDIR /app
|
4
4
|
|
5
5
|
## install packages
|
6
6
|
RUN apt-get update
|
7
7
|
RUN apt-get install -y build-essential libncurses-dev libreadline-dev libssl-dev gnuplot git gnupg2
|
8
|
+
RUN apt-get install -y autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev gawk libsqlite3-dev libtool sqlite3 libgmp-dev # ruby build dep
|
8
9
|
|
9
10
|
## get source code
|
10
11
|
RUN git clone https://github.com/hayamiz/perfmonger .
|
@@ -18,16 +19,16 @@ RUN bash rvm-installer stable
|
|
18
19
|
RUN ln -sf /bin/bash /bin/sh
|
19
20
|
|
20
21
|
## install ruby
|
21
|
-
RUN bash -l -c "rvm install 2.
|
22
|
-
RUN bash -l -c "rvm use 2.
|
22
|
+
RUN bash -l -c "rvm install 2.4.9"
|
23
|
+
RUN bash -l -c "rvm use 2.4.9 && gem install bundler && bundle"
|
23
24
|
|
24
|
-
RUN bash -l -c "rvm install 2.
|
25
|
-
RUN bash -l -c "rvm use 2.
|
25
|
+
RUN bash -l -c "rvm install 2.5.7"
|
26
|
+
RUN bash -l -c "rvm use 2.5.7 && gem install bundler && bundle"
|
26
27
|
|
27
|
-
RUN bash -l -c "rvm install 2.
|
28
|
-
RUN bash -l -c "rvm use 2.
|
28
|
+
RUN bash -l -c "rvm install 2.6.5"
|
29
|
+
RUN bash -l -c "rvm use 2.6.5 && gem install bundler && bundle"
|
29
30
|
|
30
|
-
RUN bash -l -c "rvm install 2.
|
31
|
-
RUN bash -l -c "rvm use 2.
|
31
|
+
RUN bash -l -c "rvm install 2.7.0"
|
32
|
+
RUN bash -l -c "rvm use 2.7.0 && gem install bundler && bundle"
|
32
33
|
|
33
34
|
CMD true
|
data/wercker.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
box: hayamiz/go-rvm:wercker-env
|
1
|
+
box: hayamiz/go-rvm:wercker-env-0.11.2
|
2
2
|
# Build definition
|
3
3
|
build:
|
4
4
|
# The steps that will be executed on build
|
@@ -9,14 +9,14 @@ build:
|
|
9
9
|
name: prepare perfmonger go subsystem
|
10
10
|
code: |
|
11
11
|
source /etc/profile.d/rvm.sh
|
12
|
-
rvm use 2.
|
12
|
+
rvm use 2.4.9
|
13
13
|
rake go_get
|
14
14
|
|
15
15
|
- script:
|
16
|
-
name: switch ruby to 2.
|
16
|
+
name: switch ruby to 2.4.9
|
17
17
|
code: |
|
18
18
|
source /etc/profile.d/rvm.sh
|
19
|
-
rvm use 2.
|
19
|
+
rvm use 2.4.9
|
20
20
|
- bundle-install
|
21
21
|
- script:
|
22
22
|
name: run rspec
|
@@ -25,10 +25,10 @@ build:
|
|
25
25
|
bundle exec rake spec
|
26
26
|
|
27
27
|
- script:
|
28
|
-
name: switch ruby to 2.
|
28
|
+
name: switch ruby to 2.5.7
|
29
29
|
code: |
|
30
30
|
source /etc/profile.d/rvm.sh
|
31
|
-
rvm use 2.
|
31
|
+
rvm use 2.5.7
|
32
32
|
- bundle-install
|
33
33
|
- script:
|
34
34
|
name: run rspec
|
@@ -37,10 +37,10 @@ build:
|
|
37
37
|
bundle exec rake spec
|
38
38
|
|
39
39
|
- script:
|
40
|
-
name: switch ruby to 2.
|
40
|
+
name: switch ruby to 2.6.5
|
41
41
|
code: |
|
42
42
|
source /etc/profile.d/rvm.sh
|
43
|
-
rvm use 2.
|
43
|
+
rvm use 2.6.5
|
44
44
|
- bundle-install
|
45
45
|
- script:
|
46
46
|
name: run rspec
|
@@ -49,10 +49,10 @@ build:
|
|
49
49
|
bundle exec rake spec
|
50
50
|
|
51
51
|
- script:
|
52
|
-
name: switch ruby to 2.
|
52
|
+
name: switch ruby to 2.7.0
|
53
53
|
code: |
|
54
54
|
source /etc/profile.d/rvm.sh
|
55
|
-
rvm use 2.
|
55
|
+
rvm use 2.7.0
|
56
56
|
- bundle-install
|
57
57
|
- script:
|
58
58
|
name: run rspec
|