perfmonger 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/NEWS +10 -2
- data/core/Makefile +14 -2
- data/core/build.sh +1 -1
- data/core/perfmonger-plot-formatter.go +325 -0
- data/core/subsystem/usage.go +13 -1
- data/lib/perfmonger.rb +1 -0
- data/lib/perfmonger/command/core.rb +4 -0
- data/lib/perfmonger/command/fingerprint.rb +48 -0
- data/lib/perfmonger/command/init-shell.rb +51 -0
- data/lib/perfmonger/command/plot.rb +241 -195
- data/lib/perfmonger/command/summary.rb +1 -1
- data/lib/perfmonger/version.rb +1 -1
- data/misc/{perfmonger-completion.bash → perfmonger.bash} +0 -0
- data/misc/{_perfmonger → perfmonger.zsh} +24 -8
- data/perfmonger.gemspec +0 -1
- data/spec/fingerprint_spec.rb +7 -7
- data/spec/live_spec.rb +5 -4
- data/spec/perfmonger_spec.rb +7 -7
- data/spec/play_spec.rb +4 -3
- data/spec/plot_spec.rb +18 -17
- data/spec/record_spec.rb +3 -3
- data/spec/stat_spec.rb +2 -2
- data/spec/summary_spec.rb +4 -4
- data/spec/support/aruba.rb +1 -2
- metadata +9 -18
@@ -69,6 +69,18 @@ EOS
|
|
69
69
|
save_disk_info()
|
70
70
|
end
|
71
71
|
|
72
|
+
do_with_message("Saving fdisk info") do
|
73
|
+
save_fdisk_info()
|
74
|
+
end
|
75
|
+
|
76
|
+
do_with_message("Saving lsblk info") do
|
77
|
+
save_lsblk_info()
|
78
|
+
end
|
79
|
+
|
80
|
+
do_with_message("Saving LVM info") do
|
81
|
+
save_lvm_info()
|
82
|
+
end
|
83
|
+
|
72
84
|
do_with_message("Saving PCI/PCIe info") do
|
73
85
|
save_pci_info()
|
74
86
|
end
|
@@ -110,6 +122,8 @@ EOS
|
|
110
122
|
|
111
123
|
FileUtils.mv(tmptar_path, @output_tarball)
|
112
124
|
end
|
125
|
+
|
126
|
+
true
|
113
127
|
end
|
114
128
|
|
115
129
|
private
|
@@ -210,6 +224,40 @@ EOS
|
|
210
224
|
end
|
211
225
|
end
|
212
226
|
|
227
|
+
def save_fdisk_info()
|
228
|
+
fdisk_bin = find_executable("fdisk")
|
229
|
+
|
230
|
+
File.open("#{@output_dir}/fdisk.log", "w") do |f|
|
231
|
+
f.puts(`#{fdisk_bin} -l`)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def save_lsblk_info()
|
236
|
+
lsblk_bin = find_executable("lsblk")
|
237
|
+
|
238
|
+
File.open("#{@output_dir}/lsblk.log", "w") do |f|
|
239
|
+
f.puts(`#{lsblk_bin} -t`)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def save_lvm_info()
|
244
|
+
vgdisplay_bin = find_executable("vgdisplay")
|
245
|
+
lvdisplay_bin = find_executable("lvdisplay")
|
246
|
+
pvdisplay_bin = find_executable("pvdisplay")
|
247
|
+
|
248
|
+
File.open("#{@output_dir}/lvm-vgdisplay.log", "w") do |f|
|
249
|
+
f.puts(`#{vgdisplay_bin}`)
|
250
|
+
end
|
251
|
+
|
252
|
+
File.open("#{@output_dir}/lvm-lvdisplay.log", "w") do |f|
|
253
|
+
f.puts(`#{lvdisplay_bin}`)
|
254
|
+
end
|
255
|
+
|
256
|
+
File.open("#{@output_dir}/lvm-pvdisplay.log", "w") do |f|
|
257
|
+
f.puts(`#{pvdisplay_bin}`)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
213
261
|
def save_irq_info()
|
214
262
|
File.open("#{@output_dir}/irq-smp-affinity.log", "w") do |f|
|
215
263
|
Dir.glob('/proc/irq/*/smp_affinity').sort_by do |path|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
require 'optparse'
|
3
|
+
require 'json'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
module PerfMonger
|
8
|
+
module Command
|
9
|
+
|
10
|
+
class InitShellCommand < BaseCommand
|
11
|
+
register_command 'init-shell', "Generate shell script to init shell completion"
|
12
|
+
|
13
|
+
def run(argv)
|
14
|
+
gem_dir = File.expand_path("../../../", __dir__)
|
15
|
+
|
16
|
+
shell = `ps -p #{Process.ppid()} -o 'args='`.strip
|
17
|
+
shell = File.basename(shell.split.first)
|
18
|
+
|
19
|
+
case shell
|
20
|
+
when "zsh"
|
21
|
+
if argv.first == "-"
|
22
|
+
puts <<EOS
|
23
|
+
source #{File.expand_path("misc/perfmonger.zsh", gem_dir)}
|
24
|
+
EOS
|
25
|
+
else
|
26
|
+
puts <<EOS
|
27
|
+
# Add a following line to ~/.zshrc
|
28
|
+
|
29
|
+
eval "$(perfmonger init-shell -)"
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
when "bash"
|
33
|
+
if argv.first == "-"
|
34
|
+
puts <<EOS
|
35
|
+
source #{File.expand_path("misc/perfmonger.bash", gem_dir)}
|
36
|
+
EOS
|
37
|
+
else
|
38
|
+
puts <<EOS
|
39
|
+
# Add a following line to ~/.bashrc
|
40
|
+
|
41
|
+
eval "$(perfmonger init-shell -)"
|
42
|
+
EOS
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end # module Command
|
51
|
+
end # module PerfMonger
|
@@ -25,6 +25,9 @@ EOS
|
|
25
25
|
@output_prefix = ''
|
26
26
|
@save_gpfiles = false
|
27
27
|
@disk_only_regex = nil
|
28
|
+
@disk_plot_read = true
|
29
|
+
@disk_plot_write = true
|
30
|
+
@disk_numkey_threshold = 10
|
28
31
|
end
|
29
32
|
|
30
33
|
def parse_args(argv)
|
@@ -77,6 +80,25 @@ EOS
|
|
77
80
|
@disk_only_regex = Regexp.compile(regex)
|
78
81
|
end
|
79
82
|
|
83
|
+
@parser.on('--disk-read-only', "Plot only READ performance for disks") do
|
84
|
+
@disk_plot_read = true
|
85
|
+
@disk_plot_write = false
|
86
|
+
end
|
87
|
+
|
88
|
+
@parser.on('--disk-write-only', "Plot only WRITE performance for disks") do
|
89
|
+
@disk_plot_read = false
|
90
|
+
@disk_plot_write = true
|
91
|
+
end
|
92
|
+
|
93
|
+
@parser.on('--disk-read-write', "Plot READ and WRITE performance for disks") do
|
94
|
+
@disk_plot_read = true
|
95
|
+
@disk_plot_write = true
|
96
|
+
end
|
97
|
+
|
98
|
+
@parser.on('--disk-numkey-threshold NUM', "Legends of per-disk plots are turned off if the number of disks is larger than this value.") do |num|
|
99
|
+
@disk_numkey_threshold = num.to_i
|
100
|
+
end
|
101
|
+
|
80
102
|
@parser.parse!(argv)
|
81
103
|
|
82
104
|
if argv.size == 0
|
@@ -104,87 +126,133 @@ EOS
|
|
104
126
|
exit(false)
|
105
127
|
end
|
106
128
|
|
107
|
-
|
129
|
+
formatter_bin = ::PerfMonger::Command::CoreFinder.plot_formatter()
|
130
|
+
|
131
|
+
@tmpdir = Dir.mktmpdir
|
132
|
+
|
133
|
+
@disk_dat = File.expand_path("disk.dat", @tmpdir)
|
134
|
+
@cpu_dat = File.expand_path("cpu.dat", @tmpdir)
|
108
135
|
|
109
|
-
|
110
|
-
IO.popen([
|
111
|
-
|
136
|
+
meta_json = nil
|
137
|
+
IO.popen([formatter_bin, "-perfmonger", @data_file, "-cpufile", @cpu_dat, "-diskfile", @disk_dat], "r") do |io|
|
138
|
+
meta_json = io.read
|
112
139
|
end
|
113
|
-
|
140
|
+
if $?.exitstatus != 0
|
141
|
+
puts("ERROR: failed to run perfmonger-plot-formatter")
|
142
|
+
exit(false)
|
143
|
+
end
|
144
|
+
meta = JSON.parse(meta_json)
|
145
|
+
|
146
|
+
plot_disk(meta)
|
147
|
+
plot_cpu(meta)
|
114
148
|
|
115
|
-
|
116
|
-
plot_cpuinfo(tmpfile.path)
|
149
|
+
true
|
117
150
|
end
|
118
151
|
|
119
152
|
private
|
120
|
-
def
|
121
|
-
iops_pdf_filename = @output_prefix + 'iops.pdf'
|
122
|
-
transfer_pdf_filename = @output_prefix + 'transfer.pdf'
|
123
|
-
|
124
|
-
|
153
|
+
def plot_disk(meta)
|
154
|
+
iops_pdf_filename = @output_prefix + 'disk-iops.pdf'
|
155
|
+
transfer_pdf_filename = @output_prefix + 'disk-transfer.pdf'
|
156
|
+
total_iops_pdf_filename = @output_prefix + 'disk-total-iops.pdf'
|
157
|
+
total_transfer_pdf_filename = @output_prefix + 'disk-total-transfer.pdf'
|
158
|
+
gp_filename = @output_prefix + 'disk.gp'
|
159
|
+
dat_filename = @output_prefix + 'disk.dat'
|
125
160
|
if @output_type != 'pdf'
|
126
|
-
iops_img_filename = @output_prefix + 'iops.' + @output_type
|
127
|
-
transfer_img_filename = @output_prefix + 'transfer.' + @output_type
|
161
|
+
iops_img_filename = @output_prefix + 'disk-iops.' + @output_type
|
162
|
+
transfer_img_filename = @output_prefix + 'disk-transfer.' + @output_type
|
163
|
+
total_iops_img_filename = @output_prefix + 'disk-total-iops.' + @output_type
|
164
|
+
total_transfer_img_filename = @output_prefix + 'disk-total-transfer.' + @output_type
|
128
165
|
else
|
129
166
|
iops_img_filename = nil
|
130
167
|
transfer_img_filename = nil
|
168
|
+
total_iops_img_filename = nil
|
169
|
+
total_transfer_img_filename = nil
|
131
170
|
end
|
132
171
|
|
133
|
-
|
134
|
-
|
135
|
-
datafile = File.open(dat_filename, 'w')
|
136
|
-
gpfile = File.new(gp_filename, 'w')
|
172
|
+
start_time = meta["start_time"]
|
173
|
+
end_time = meta["end_time"]
|
137
174
|
|
138
|
-
|
139
|
-
|
175
|
+
Dir.chdir(@tmpdir) do
|
176
|
+
gpfile = File.new(gp_filename, 'w')
|
140
177
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
178
|
+
total_iops_plot_stmt_list = []
|
179
|
+
iops_plot_stmt_list = meta["disk"]["devices"].map do |dev_entry|
|
180
|
+
devname = dev_entry["name"]
|
181
|
+
idx = dev_entry["idx"]
|
182
|
+
|
183
|
+
if devname == "total"
|
184
|
+
if @disk_plot_read
|
185
|
+
total_iops_plot_stmt_list.push("\"disk.dat\" ind #{idx} usi 1:2 with lines lw 2 title \"#{devname} read\"")
|
186
|
+
end
|
187
|
+
if @disk_plot_write
|
188
|
+
total_iops_plot_stmt_list.push("\"disk.dat\" ind #{idx} usi 1:3 with lines lw 2 title \"#{devname} write\"")
|
189
|
+
end
|
146
190
|
|
147
|
-
|
148
|
-
|
191
|
+
[]
|
192
|
+
elsif @disk_only_regex && !(devname =~ @disk_only_regex)
|
193
|
+
[]
|
194
|
+
else
|
195
|
+
plot_stmt = []
|
149
196
|
|
150
|
-
if @
|
151
|
-
|
152
|
-
|
153
|
-
|
197
|
+
if @disk_plot_read
|
198
|
+
plot_stmt.push("\"disk.dat\" ind #{idx} usi 1:2 with lines lw 2 title \"#{devname} read\"")
|
199
|
+
end
|
200
|
+
if @disk_plot_write
|
201
|
+
plot_stmt.push("\"disk.dat\" ind #{idx} usi 1:3 with lines lw 2 title \"#{devname} write\"")
|
154
202
|
end
|
155
203
|
|
156
|
-
|
157
|
-
devices.map{|device|
|
158
|
-
[diskinfo[device]["riops"], diskinfo[device]["wiops"],
|
159
|
-
diskinfo[device]["rkbyteps"] * 512 / 1024 / 1024, # in MB/s
|
160
|
-
diskinfo[device]["wkbyteps"] * 512 / 1024 / 1024, # in MB/s
|
161
|
-
]
|
162
|
-
}].flatten.map(&:to_s).join("\t"))
|
204
|
+
plot_stmt
|
163
205
|
end
|
206
|
+
end.flatten
|
164
207
|
|
165
|
-
|
208
|
+
total_transfer_plot_stmt_list = []
|
209
|
+
transfer_plot_stmt_list = meta["disk"]["devices"].map do |dev_entry|
|
210
|
+
devname = dev_entry["name"]
|
211
|
+
idx = dev_entry["idx"]
|
166
212
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end.flatten
|
213
|
+
if devname == "total"
|
214
|
+
if @disk_plot_read
|
215
|
+
total_transfer_plot_stmt_list.push("\"disk.dat\" ind #{idx} usi 1:4 with lines lw 2 title \"#{devname} read\"")
|
216
|
+
end
|
217
|
+
if @disk_plot_write
|
218
|
+
total_transfer_plot_stmt_list.push("\"disk.dat\" ind #{idx} usi 1:5 with lines lw 2 title \"#{devname} write\"")
|
219
|
+
end
|
175
220
|
|
176
|
-
|
177
|
-
|
221
|
+
[]
|
222
|
+
elsif @disk_only_regex && !(devname =~ @disk_only_regex)
|
223
|
+
[]
|
224
|
+
else
|
178
225
|
plot_stmt = []
|
179
|
-
|
180
|
-
|
181
|
-
|
226
|
+
|
227
|
+
if @disk_plot_read
|
228
|
+
plot_stmt.push("\"disk.dat\" ind #{idx} usi 1:4 with lines lw 2 title \"#{devname} read\"")
|
229
|
+
end
|
230
|
+
if @disk_plot_write
|
231
|
+
plot_stmt.push("\"disk.dat\" ind #{idx} usi 1:5 with lines lw 2 title \"#{devname} write\"")
|
232
|
+
end
|
233
|
+
|
182
234
|
plot_stmt
|
183
|
-
end
|
235
|
+
end
|
236
|
+
end.flatten
|
237
|
+
|
238
|
+
if iops_plot_stmt_list.size == 0
|
239
|
+
puts("No plot target disk devices.")
|
240
|
+
return
|
241
|
+
end
|
184
242
|
|
185
|
-
|
243
|
+
num_dev = meta["disk"]["devices"].select do |dev_entry|
|
244
|
+
dev_entry["name"] != "total"
|
245
|
+
end.size
|
246
|
+
|
247
|
+
if num_dev > @disk_numkey_threshold
|
248
|
+
set_key_stmt = "unset key"
|
249
|
+
else
|
250
|
+
set_key_stmt = "set key below center"
|
251
|
+
end
|
252
|
+
|
253
|
+
gpfile.puts <<EOS
|
186
254
|
set term pdfcairo enhanced color
|
187
|
-
set title "IOPS
|
255
|
+
set title "IOPS"
|
188
256
|
set size 1.0, 1.0
|
189
257
|
set output "#{iops_pdf_filename}"
|
190
258
|
|
@@ -192,54 +260,67 @@ set xlabel "elapsed time [sec]"
|
|
192
260
|
set ylabel "IOPS"
|
193
261
|
|
194
262
|
set grid
|
195
|
-
set xrange [#{@offset_time}
|
263
|
+
set xrange [#{@offset_time}:#{end_time - start_time}]
|
196
264
|
set yrange [0:*]
|
197
265
|
|
198
|
-
|
199
|
-
|
266
|
+
#{set_key_stmt}
|
200
267
|
plot #{iops_plot_stmt_list.join(",\\\n ")}
|
201
268
|
|
269
|
+
set title "Total IOPS"
|
270
|
+
unset key
|
271
|
+
set output "#{total_iops_pdf_filename}"
|
272
|
+
plot #{total_iops_plot_stmt_list.join(",\\\n ")}
|
273
|
+
|
202
274
|
|
203
|
-
set title "Transfer rate
|
275
|
+
set title "Transfer rate"
|
204
276
|
set output "#{transfer_pdf_filename}"
|
205
277
|
set ylabel "transfer rate [MB/s]"
|
278
|
+
#{set_key_stmt}
|
206
279
|
plot #{transfer_plot_stmt_list.join(",\\\n ")}
|
207
|
-
EOS
|
208
280
|
|
209
|
-
|
281
|
+
set title "Total transfer rate"
|
282
|
+
set output "#{total_transfer_pdf_filename}"
|
283
|
+
unset key
|
284
|
+
plot #{total_transfer_plot_stmt_list.join(",\\\n ")}
|
285
|
+
EOS
|
286
|
+
gpfile.close
|
210
287
|
|
211
|
-
|
288
|
+
system("gnuplot #{gpfile.path}")
|
212
289
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
290
|
+
if @output_type != 'pdf'
|
291
|
+
system("convert -density 150 -background white #{iops_pdf_filename} #{iops_img_filename}")
|
292
|
+
system("convert -density 150 -background white #{transfer_pdf_filename} #{transfer_img_filename}")
|
293
|
+
system("convert -density 150 -background white #{total_iops_pdf_filename} #{total_iops_img_filename}")
|
294
|
+
system("convert -density 150 -background white #{total_transfer_pdf_filename} #{total_transfer_img_filename}")
|
295
|
+
end
|
217
296
|
|
218
|
-
|
297
|
+
end # chdir
|
219
298
|
|
220
|
-
|
221
|
-
|
222
|
-
|
299
|
+
copy_targets = []
|
300
|
+
copy_targets += [iops_pdf_filename, transfer_pdf_filename]
|
301
|
+
copy_targets += [total_iops_pdf_filename, total_transfer_pdf_filename]
|
302
|
+
copy_targets.push(iops_img_filename) if iops_img_filename
|
303
|
+
copy_targets.push(transfer_img_filename) if transfer_img_filename
|
304
|
+
copy_targets.push(total_iops_img_filename) if total_iops_img_filename
|
305
|
+
copy_targets.push(total_transfer_img_filename) if total_transfer_img_filename
|
223
306
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
307
|
+
if @save_gpfiles
|
308
|
+
copy_targets.push(dat_filename)
|
309
|
+
copy_targets.push(gp_filename)
|
310
|
+
end
|
228
311
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
end # mktempdir
|
312
|
+
copy_targets.each do |target|
|
313
|
+
FileUtils.copy(File.join(@tmpdir, target), @output_dir)
|
314
|
+
end
|
233
315
|
end # def
|
234
316
|
|
235
|
-
def
|
317
|
+
def plot_cpu(meta)
|
236
318
|
pdf_filename = @output_prefix + 'cpu.pdf'
|
237
319
|
gp_filename = @output_prefix + 'cpu.gp'
|
238
320
|
dat_filename = @output_prefix + 'cpu.dat'
|
239
321
|
|
240
322
|
all_pdf_filename = @output_prefix + 'allcpu.pdf'
|
241
323
|
all_gp_filename = @output_prefix + 'allcpu.gp'
|
242
|
-
all_dat_filename = @output_prefix + 'allcpu.dat'
|
243
324
|
|
244
325
|
if @output_type != 'pdf'
|
245
326
|
img_filename = @output_prefix + 'cpu.' + @output_type
|
@@ -249,52 +330,27 @@ EOS
|
|
249
330
|
all_img_filename = nil
|
250
331
|
end
|
251
332
|
|
252
|
-
|
253
|
-
|
254
|
-
datafile = File.open(dat_filename, 'w')
|
255
|
-
gpfile = File.open(gp_filename, 'w')
|
256
|
-
all_datafile = File.open(all_dat_filename, 'w')
|
257
|
-
all_gpfile = File.open(all_gp_filename, 'w')
|
258
|
-
|
259
|
-
start_time = nil
|
260
|
-
end_time = 0
|
261
|
-
devices = nil
|
262
|
-
nr_cpu = nil
|
263
|
-
|
264
|
-
File.open(json_file).each_line do |line|
|
265
|
-
record = JSON.parse(line)
|
266
|
-
|
267
|
-
time = record["time"]
|
268
|
-
cpuinfo = record["cpu"]
|
269
|
-
return unless cpuinfo
|
270
|
-
nr_cpu = cpuinfo['num_core']
|
271
|
-
|
272
|
-
cores = cpuinfo['cores']
|
333
|
+
start_time = meta["start_time"]
|
334
|
+
end_time = meta["end_time"]
|
273
335
|
|
274
|
-
|
275
|
-
|
336
|
+
Dir.chdir(@tmpdir) do
|
337
|
+
gpfile = File.open(gp_filename, 'w')
|
338
|
+
all_gpfile = File.open(all_gp_filename, 'w')
|
276
339
|
|
277
|
-
|
278
|
-
|
279
|
-
cores.map{|core| core[key]}.inject(&:+)
|
280
|
-
end].flatten.map(&:to_s).join("\t"))
|
281
|
-
end
|
282
|
-
datafile.close
|
340
|
+
devices = nil
|
341
|
+
nr_cpu = meta["cpu"]["num_core"]
|
283
342
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
plot_stmt_list << plot_stmt
|
291
|
-
col_idx += 1
|
292
|
-
end
|
343
|
+
plot_stmt_list = []
|
344
|
+
%w|%usr %nice %sys %iowait %hardirq %softirq %steal %guest|.each_with_index do |key, idx|
|
345
|
+
stack_columns = (0..idx).to_a.map{|x| x + 2}
|
346
|
+
plot_stmt = "\"cpu.dat\" ind 0 usi 1:(#{stack_columns.map{|i| "$#{i}"}.join("+")}) with filledcurve x1 lw 0 lc #{idx+1} title \"#{key}\""
|
347
|
+
plot_stmt_list << plot_stmt
|
348
|
+
end
|
293
349
|
|
294
|
-
|
295
|
-
|
350
|
+
pdf_file = File.join(@output_dir, "cpu.pdf")
|
351
|
+
gpfile.puts <<EOS
|
296
352
|
set term pdfcairo enhanced color
|
297
|
-
set title "CPU usage
|
353
|
+
set title "CPU usage (max: #{nr_cpu*100}%)"
|
298
354
|
set output "#{pdf_filename}"
|
299
355
|
set key outside center bottom horizontal
|
300
356
|
set size 1.0, 1.0
|
@@ -309,24 +365,30 @@ set yrange [0:*]
|
|
309
365
|
plot #{plot_stmt_list.reverse.join(",\\\n ")}
|
310
366
|
EOS
|
311
367
|
|
312
|
-
|
313
|
-
|
368
|
+
gpfile.close
|
369
|
+
system("gnuplot #{gpfile.path}")
|
314
370
|
|
315
|
-
|
316
|
-
|
317
|
-
|
371
|
+
if @output_type != 'pdf'
|
372
|
+
system("convert -density 150 -background white #{pdf_filename} #{img_filename}")
|
373
|
+
end
|
318
374
|
|
319
|
-
|
375
|
+
## Plot all CPUs in a single file
|
320
376
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
377
|
+
nr_cpu_factors = factors(nr_cpu)
|
378
|
+
nr_cols = nr_cpu_factors.select do |x|
|
379
|
+
x <= Math.sqrt(nr_cpu)
|
380
|
+
end.max
|
381
|
+
nr_cols ||= Math.sqrt(nr_cpu).ceil
|
382
|
+
nr_rows = nr_cpu / nr_cols
|
327
383
|
|
328
|
-
|
329
|
-
|
384
|
+
plot_height = 8
|
385
|
+
|
386
|
+
if nr_rows == 1
|
387
|
+
plot_height /= 2.0
|
388
|
+
end
|
389
|
+
|
390
|
+
all_gpfile.puts <<EOS
|
391
|
+
set term pdfcairo color enhanced size 8.5inch, #{plot_height}inch
|
330
392
|
set output "#{all_pdf_filename}"
|
331
393
|
set size 1.0, 1.0
|
332
394
|
set multiplot
|
@@ -336,28 +398,19 @@ set yrange [0:101]
|
|
336
398
|
|
337
399
|
EOS
|
338
400
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
record = JSON.parse(line)
|
344
|
-
time = record["time"]
|
345
|
-
cpurec = record["cpu"]["cores"][cpu_idx]
|
346
|
-
all_datafile.puts([time - start_time,
|
347
|
-
cpurec["usr"] + cpurec["nice"],
|
348
|
-
cpurec["sys"],
|
349
|
-
cpurec["hardirq"],
|
350
|
-
cpurec["softirq"],
|
351
|
-
cpurec["steal"] + cpurec["guest"],
|
352
|
-
cpurec["iowait"]].map(&:to_s).join("\t"))
|
353
|
-
end
|
354
|
-
all_datafile.puts("")
|
355
|
-
all_datafile.puts("")
|
401
|
+
legend_height = 0.04
|
402
|
+
nr_cpu.times do |cpu_idx|
|
403
|
+
xpos = (1.0 / nr_cols) * (cpu_idx % nr_cols)
|
404
|
+
ypos = ((1.0 - legend_height) / nr_rows) * (nr_rows - 1 - (cpu_idx / nr_cols).to_i) + legend_height
|
356
405
|
|
357
|
-
|
358
|
-
|
406
|
+
plot_stmt_list = []
|
407
|
+
%w|%usr %nice %sys %iowait %hardirq %softirq %steal %guest|.each_with_index do |key, idx|
|
408
|
+
stack_columns = (0..idx).to_a.map{|x| x + 2}
|
409
|
+
plot_stmt = "\"cpu.dat\" ind #{cpu_idx+1} usi 1:(#{stack_columns.map{|i| "$#{i}"}.join("+")}) with filledcurve x1 lw 0 lc #{idx+1} title \"#{key}\""
|
410
|
+
plot_stmt_list << plot_stmt
|
411
|
+
end
|
359
412
|
|
360
|
-
|
413
|
+
all_gpfile.puts <<EOS
|
361
414
|
set title 'cpu #{cpu_idx}' offset 0.0,-0.7 font 'Arial,16'
|
362
415
|
unset key
|
363
416
|
set origin #{xpos}, #{ypos}
|
@@ -369,20 +422,20 @@ set bmargin 1.3
|
|
369
422
|
set xtics offset 0.0,0.5
|
370
423
|
set ytics offset 0.5,0
|
371
424
|
set style fill noborder
|
372
|
-
plot
|
373
|
-
'#{all_datafile.path}' index #{cpu_idx} using 1:($2+$3+$4+$5+$6) with filledcurve x1 lw 0 lc 5 title '%other', \\
|
374
|
-
'#{all_datafile.path}' index #{cpu_idx} using 1:($2+$3+$4+$5) with filledcurve x1 lw 0 lc 4 title '%soft', \\
|
375
|
-
'#{all_datafile.path}' index #{cpu_idx} using 1:($2+$3+$4) with filledcurve x1 lw 0 lc 3 title '%irq', \\
|
376
|
-
'#{all_datafile.path}' index #{cpu_idx} using 1:($2+$3) with filledcurve x1 lw 0 lc 2 title '%sys', \\
|
377
|
-
'#{all_datafile.path}' index #{cpu_idx} using 1:2 with filledcurve x1 lw 0 lc 1 title '%usr'
|
425
|
+
plot #{plot_stmt_list.reverse.join(",\\\n ")}
|
378
426
|
|
379
427
|
EOS
|
428
|
+
end # times
|
380
429
|
|
381
|
-
|
382
|
-
|
383
|
-
|
430
|
+
# plot legends
|
431
|
+
plot_stmt_list = []
|
432
|
+
%w|%usr %nice %sys %iowait %hardirq %softirq %steal %guest|.each_with_index do |key, idx|
|
433
|
+
plot_stmt = "-1 with filledcurve x1 lw 0 lc #{idx+1} title \"#{key}\""
|
434
|
+
plot_stmt_list << plot_stmt
|
435
|
+
end
|
436
|
+
all_gpfile.puts <<EOS
|
384
437
|
unset title
|
385
|
-
set key center center horizontal font "Arial,
|
438
|
+
set key center center horizontal font "Arial,14"
|
386
439
|
set origin 0.0, 0.0
|
387
440
|
set size 1.0, #{legend_height}
|
388
441
|
set rmargin 0
|
@@ -394,45 +447,38 @@ set border 0
|
|
394
447
|
set yrange [0:1]
|
395
448
|
# plot -1 with filledcurve x1 title '%usr'
|
396
449
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
-1 with filledcurve x1 lw 0 lc 4 title '%soft', \\
|
401
|
-
-1 with filledcurve x1 lw 0 lc 5 title '%other', \\
|
402
|
-
-1 with filledcurve x1 lw 0 lc 6 title '%iowait'
|
450
|
+
set xlabel "elapsed time [sec]"
|
451
|
+
plot #{plot_stmt_list.reverse.join(",\\\n ")}
|
452
|
+
|
403
453
|
EOS
|
404
454
|
|
405
|
-
|
406
|
-
|
407
|
-
all_datafile.close
|
408
|
-
all_gpfile.close
|
455
|
+
all_gpfile.fsync
|
456
|
+
all_gpfile.close
|
409
457
|
|
410
|
-
|
458
|
+
system("gnuplot #{all_gpfile.path}")
|
411
459
|
|
412
|
-
|
413
|
-
|
414
|
-
|
460
|
+
if @output_type != 'pdf'
|
461
|
+
system("convert -density 150 -background white #{all_pdf_filename} #{all_img_filename}")
|
462
|
+
end
|
415
463
|
|
416
|
-
|
464
|
+
end # chdir
|
417
465
|
|
418
|
-
|
466
|
+
copy_targets = []
|
419
467
|
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
468
|
+
copy_targets << pdf_filename
|
469
|
+
copy_targets << img_filename if img_filename
|
470
|
+
copy_targets << all_pdf_filename
|
471
|
+
copy_targets << all_img_filename if all_img_filename
|
424
472
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
end
|
473
|
+
if @save_gpfiles
|
474
|
+
copy_targets << gp_filename
|
475
|
+
copy_targets << dat_filename
|
476
|
+
copy_targets << all_gp_filename
|
477
|
+
end
|
431
478
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
end # mktempdir
|
479
|
+
copy_targets.each do |target|
|
480
|
+
FileUtils.copy(File.join(@tmpdir, target), @output_dir)
|
481
|
+
end
|
436
482
|
end # def
|
437
483
|
|
438
484
|
private
|