perfmonger 0.11.2 → 0.14.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 +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
|