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.
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