perfmonger 0.11.2 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -5
  3. data/NEWS +38 -1
  4. data/Rakefile +18 -7
  5. data/core/Makefile +20 -21
  6. data/core/build.sh +4 -6
  7. data/core/{perfmonger-player.go → cmd/perfmonger-player/perfmonger-player.go} +53 -10
  8. data/core/cmd/perfmonger-plot-formatter/README.md +24 -0
  9. data/core/{perfmonger-plot-formatter.go → cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go} +116 -3
  10. data/core/{perfmonger-recorder.go → cmd/perfmonger-recorder/perfmonger-recorder.go} +6 -0
  11. data/core/{perfmonger-summarizer.go → cmd/perfmonger-summarizer/perfmonger-summarizer.go} +4 -2
  12. data/core/{perfmonger-viewer.go → cmd/perfmonger-viewer/perfmonger-viewer.go} +0 -0
  13. data/core/go.mod +10 -0
  14. data/core/go.sum +17 -0
  15. data/core/subsystem/Makefile +4 -0
  16. data/core/subsystem/perfmonger_linux.go +97 -0
  17. data/core/subsystem/perfmonger_linux_test.go +40 -0
  18. data/core/subsystem/stat.go +72 -0
  19. data/core/subsystem/stat_test.go +9 -0
  20. data/core/subsystem/usage.go +80 -0
  21. data/core/utils.go +2 -2
  22. data/lib/exec/perfmonger-player_darwin_amd64 +0 -0
  23. data/lib/exec/perfmonger-player_linux_amd64 +0 -0
  24. data/lib/exec/perfmonger-plot-formatter_darwin_amd64 +0 -0
  25. data/lib/exec/perfmonger-plot-formatter_linux_amd64 +0 -0
  26. data/lib/exec/perfmonger-recorder_darwin_amd64 +0 -0
  27. data/lib/exec/perfmonger-recorder_linux_amd64 +0 -0
  28. data/lib/exec/perfmonger-summarizer_darwin_amd64 +0 -0
  29. data/lib/exec/perfmonger-summarizer_linux_amd64 +0 -0
  30. data/lib/exec/perfmonger-viewer_darwin_amd64 +0 -0
  31. data/lib/exec/perfmonger-viewer_linux_amd64 +0 -0
  32. data/lib/perfmonger/command/play.rb +10 -0
  33. data/lib/perfmonger/command/plot.rb +146 -3
  34. data/lib/perfmonger/command/record.rb +23 -2
  35. data/lib/perfmonger/command/record_option.rb +16 -0
  36. data/lib/perfmonger/version.rb +1 -1
  37. data/misc/werker-box/Dockerfile +10 -9
  38. data/misc/werker-box/build-push.sh +2 -2
  39. data/wercker.yml +10 -10
  40. metadata +12 -27
data/core/utils.go CHANGED
@@ -1,4 +1,4 @@
1
- package main
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 newPerfmongerLogReader(source io.Reader) io.Reader {
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
@@ -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, "-cpufile", @cpu_dat,
145
- "-diskfile", @disk_dat]
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
- return true
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-recorder is running."
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
@@ -1,3 +1,3 @@
1
1
  module PerfMonger
2
- VERSION = "0.11.2"
2
+ VERSION = "0.14.0"
3
3
  end
@@ -1,10 +1,11 @@
1
- FROM golang:1.8
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.2.10"
22
- RUN bash -l -c "rvm use 2.2.10 && gem install bundler && bundle"
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.3.8"
25
- RUN bash -l -c "rvm use 2.3.8 && gem install bundler && bundle"
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.4.5"
28
- RUN bash -l -c "rvm use 2.4.5 && gem install bundler && bundle"
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.5.3"
31
- RUN bash -l -c "rvm use 2.5.3 && gem install bundler && bundle"
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
@@ -3,5 +3,5 @@
3
3
  set -e
4
4
 
5
5
  docker build -t go-rvm .
6
- docker tag go-rvm hayamiz/go-rvm:wercker-env
7
- docker push hayamiz/go-rvm:wercker-env
6
+ docker tag go-rvm hayamiz/go-rvm:wercker-env-0.11.2
7
+ docker push hayamiz/go-rvm:wercker-env-0.11.2
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.2.10
12
+ rvm use 2.4.9
13
13
  rake go_get
14
14
 
15
15
  - script:
16
- name: switch ruby to 2.2.10
16
+ name: switch ruby to 2.4.9
17
17
  code: |
18
18
  source /etc/profile.d/rvm.sh
19
- rvm use 2.2.10
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.3.8
28
+ name: switch ruby to 2.5.7
29
29
  code: |
30
30
  source /etc/profile.d/rvm.sh
31
- rvm use 2.3.8
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.4.5
40
+ name: switch ruby to 2.6.5
41
41
  code: |
42
42
  source /etc/profile.d/rvm.sh
43
- rvm use 2.4.5
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.5.3
52
+ name: switch ruby to 2.7.0
53
53
  code: |
54
54
  source /etc/profile.d/rvm.sh
55
- rvm use 2.5.3
55
+ rvm use 2.7.0
56
56
  - bundle-install
57
57
  - script:
58
58
  name: run rspec