perfmonger 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.dir-locals.el +2 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.travis.yml +12 -0
- data/COPYING +674 -0
- data/Gemfile +5 -0
- data/HOWTO.md +15 -0
- data/NEWS +115 -0
- data/README.md +61 -0
- data/Rakefile +8 -0
- data/bin/perfmonger +6 -0
- data/data/NOTICE +8 -0
- data/data/Twitter_Bootstrap_LICENSE.txt +176 -0
- data/data/assets/css/bootstrap-responsive.css +1109 -0
- data/data/assets/css/bootstrap.css +6167 -0
- data/data/assets/css/perfmonger.css +17 -0
- data/data/assets/dashboard.erb +319 -0
- data/data/assets/img/glyphicons-halflings-white.png +0 -0
- data/data/assets/img/glyphicons-halflings.png +0 -0
- data/data/assets/js/bootstrap.js +2280 -0
- data/data/assets/js/bootstrap.min.js +6 -0
- data/data/assets/js/canvasjs.js +9042 -0
- data/data/assets/js/canvasjs.min.js +271 -0
- data/data/sysstat.ioconf +268 -0
- data/ext/perfmonger/extconf.rb +19 -0
- data/ext/perfmonger/perfmonger.h +58 -0
- data/ext/perfmonger/perfmonger_record.c +754 -0
- data/ext/perfmonger/sysstat/common.c +627 -0
- data/ext/perfmonger/sysstat/common.h +207 -0
- data/ext/perfmonger/sysstat/ioconf.c +515 -0
- data/ext/perfmonger/sysstat/ioconf.h +84 -0
- data/ext/perfmonger/sysstat/iostat.c +1100 -0
- data/ext/perfmonger/sysstat/iostat.h +121 -0
- data/ext/perfmonger/sysstat/libsysstat.h +19 -0
- data/ext/perfmonger/sysstat/mpstat.c +953 -0
- data/ext/perfmonger/sysstat/mpstat.h +79 -0
- data/ext/perfmonger/sysstat/rd_stats.c +2388 -0
- data/ext/perfmonger/sysstat/rd_stats.h +651 -0
- data/ext/perfmonger/sysstat/sysconfig.h +13 -0
- data/lib/perfmonger/cli.rb +115 -0
- data/lib/perfmonger/command/base_command.rb +39 -0
- data/lib/perfmonger/command/fingerprint.rb +453 -0
- data/lib/perfmonger/command/plot.rb +429 -0
- data/lib/perfmonger/command/record.rb +32 -0
- data/lib/perfmonger/command/record_option.rb +149 -0
- data/lib/perfmonger/command/server.rb +294 -0
- data/lib/perfmonger/command/stat.rb +60 -0
- data/lib/perfmonger/command/stat_option.rb +29 -0
- data/lib/perfmonger/command/summary.rb +402 -0
- data/lib/perfmonger/config.rb +6 -0
- data/lib/perfmonger/version.rb +5 -0
- data/lib/perfmonger.rb +12 -0
- data/misc/release-howto.txt +17 -0
- data/misc/sample-cpu.png +0 -0
- data/misc/sample-read-iops.png +0 -0
- data/perfmonger.gemspec +44 -0
- data/test/run-test.sh +39 -0
- data/test/spec/bin_spec.rb +37 -0
- data/test/spec/data/2devices.expected +42 -0
- data/test/spec/data/2devices.output +42 -0
- data/test/spec/spec_helper.rb +20 -0
- data/test/spec/summary_spec.rb +193 -0
- data/test/test-perfmonger.c +145 -0
- data/test/test.h +9 -0
- metadata +154 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module PerfMonger
|
5
|
+
module CLI
|
6
|
+
|
7
|
+
class Runner
|
8
|
+
def self.register_command(command_name, klass)
|
9
|
+
@@commands ||= Hash.new
|
10
|
+
@@aliases ||= Hash.new
|
11
|
+
|
12
|
+
@@commands[command_name] = klass
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.register_alias(alias_name, command_name)
|
16
|
+
if @@commands.nil?
|
17
|
+
raise RuntimeError.new("No command is registered yet.")
|
18
|
+
end
|
19
|
+
|
20
|
+
if ! @@commands.has_key?(command_name)
|
21
|
+
raise RuntimeError.new("Command '#{command_name}' is not registered.")
|
22
|
+
end
|
23
|
+
|
24
|
+
@@aliases[alias_name] = command_name
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def run(argv = ARGV)
|
32
|
+
parser = OptionParser.new
|
33
|
+
parser.banner = <<EOS
|
34
|
+
Usage: #{File.basename($0)} [options] COMMAND [args]
|
35
|
+
|
36
|
+
EOS
|
37
|
+
|
38
|
+
## make list of subcommands
|
39
|
+
commands = @@commands.values.sort_by do |command|
|
40
|
+
# important command first: sort by [priority, name]
|
41
|
+
command_name = command.command_name
|
42
|
+
case command_name
|
43
|
+
when "record"
|
44
|
+
[0, command_name]
|
45
|
+
when "stat"
|
46
|
+
[1, command_name]
|
47
|
+
when "plot"
|
48
|
+
[2, command_name]
|
49
|
+
else
|
50
|
+
[999, command_name]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
max_len = commands.map(&:command_name).map(&:size).max
|
55
|
+
command_list_str = commands.map do |command|
|
56
|
+
# pad command names
|
57
|
+
command_name = command.command_name
|
58
|
+
command_name = command_name + (" " * (max_len - command_name.size))
|
59
|
+
|
60
|
+
str = " " + command_name + " " + command.description
|
61
|
+
|
62
|
+
if command.aliases && command.aliases.size > 0
|
63
|
+
str += "\n" + " " + (" " * max_len) + " " +
|
64
|
+
"Aliases: " + command.aliases.join(", ")
|
65
|
+
end
|
66
|
+
|
67
|
+
str
|
68
|
+
end.join("\n")
|
69
|
+
|
70
|
+
subcommand_list = <<EOS
|
71
|
+
|
72
|
+
Commands:
|
73
|
+
#{command_list_str}
|
74
|
+
EOS
|
75
|
+
|
76
|
+
parser.summary_indent = " "
|
77
|
+
|
78
|
+
parser.on('-h', '--help', 'Show this help') do
|
79
|
+
puts(parser.help)
|
80
|
+
puts(subcommand_list)
|
81
|
+
exit(true)
|
82
|
+
end
|
83
|
+
|
84
|
+
parser.on('-v', '--version', 'Show version number') do
|
85
|
+
puts("PerfMonger version " + PerfMonger::VERSION)
|
86
|
+
exit(true)
|
87
|
+
end
|
88
|
+
|
89
|
+
parser.order!(argv)
|
90
|
+
|
91
|
+
if argv.size == 0
|
92
|
+
puts(parser.help)
|
93
|
+
puts(subcommand_list)
|
94
|
+
exit(false)
|
95
|
+
end
|
96
|
+
|
97
|
+
command_name = argv.shift
|
98
|
+
|
99
|
+
if @@aliases[command_name]
|
100
|
+
command_name = @@aliases[command_name]
|
101
|
+
end
|
102
|
+
command_class = @@commands[command_name]
|
103
|
+
|
104
|
+
unless command_class
|
105
|
+
puts("No such command: #{command_name}")
|
106
|
+
puts(subcommand_list)
|
107
|
+
exit(false)
|
108
|
+
end
|
109
|
+
|
110
|
+
command_class.new.run(argv)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module PerfMonger
|
3
|
+
module Command
|
4
|
+
|
5
|
+
class BaseCommand
|
6
|
+
class << self
|
7
|
+
attr_accessor :command_name
|
8
|
+
attr_accessor :description
|
9
|
+
attr_accessor :aliases
|
10
|
+
|
11
|
+
def register_command(command_name, description = "")
|
12
|
+
PerfMonger::CLI::Runner.register_command(command_name, self)
|
13
|
+
self.command_name = command_name
|
14
|
+
self.description = description
|
15
|
+
end
|
16
|
+
|
17
|
+
def register_alias(alias_name)
|
18
|
+
if self.command_name
|
19
|
+
RuntimeError.new("#{self} does not have registered command name.")
|
20
|
+
end
|
21
|
+
|
22
|
+
self.aliases ||= []
|
23
|
+
self.aliases.push(alias_name)
|
24
|
+
PerfMonger::CLI::Runner.register_alias(alias_name, self.command_name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@parser = OptionParser.new
|
30
|
+
@parser.banner = <<EOS
|
31
|
+
Usage: #{File.basename($0)} #{self.class.command_name} [options]
|
32
|
+
|
33
|
+
Options:
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,453 @@
|
|
1
|
+
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module PerfMonger
|
7
|
+
module Command
|
8
|
+
|
9
|
+
class FingerprintCommand < BaseCommand
|
10
|
+
register_command 'fingerprint', 'Gather all possible system config information'
|
11
|
+
register_alias 'bukko'
|
12
|
+
register_alias 'fp'
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@parser = OptionParser.new
|
16
|
+
@parser.banner = <<EOS
|
17
|
+
Usage: perfmonger fingerprint [options] OUTPUT_TARBALL
|
18
|
+
|
19
|
+
Options:
|
20
|
+
EOS
|
21
|
+
|
22
|
+
hostname = `hostname`.strip
|
23
|
+
@output_tarball = "./fingerprint.#{hostname}.tar.gz"
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_args(argv)
|
27
|
+
@parser.parse!(argv)
|
28
|
+
|
29
|
+
if argv.size == 0
|
30
|
+
puts("ERROR: output directory is required.")
|
31
|
+
puts(@parser.help)
|
32
|
+
exit(false)
|
33
|
+
end
|
34
|
+
|
35
|
+
@output_tarball = argv.shift
|
36
|
+
|
37
|
+
if ! @output_tarball =~ /\.(tar\.gz|tgz)$/
|
38
|
+
@output_tarball += ".tar.gz"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def run(argv)
|
43
|
+
parse_args(argv)
|
44
|
+
|
45
|
+
ENV['LANG'] = 'C'
|
46
|
+
|
47
|
+
$stderr.puts("System information is gathered into #{@output_tarball}")
|
48
|
+
|
49
|
+
Dir.mktmpdir do |tmpdir|
|
50
|
+
output_basename = File.basename(@output_tarball.gsub(/\.(tar\.gz|tgz)$/, ''))
|
51
|
+
|
52
|
+
@output_dir = File.join(tmpdir, output_basename)
|
53
|
+
FileUtils.mkdir(@output_dir)
|
54
|
+
|
55
|
+
## Collect generic info.
|
56
|
+
do_with_message("Saving /proc info") do
|
57
|
+
save_proc_info()
|
58
|
+
end
|
59
|
+
|
60
|
+
do_with_message("Saving IRQ info") do
|
61
|
+
save_irq_info()
|
62
|
+
end
|
63
|
+
|
64
|
+
do_with_message("Saving block device info") do
|
65
|
+
save_device_info()
|
66
|
+
end
|
67
|
+
|
68
|
+
do_with_message("Saving /dev/disk info") do
|
69
|
+
save_disk_info()
|
70
|
+
end
|
71
|
+
|
72
|
+
do_with_message("Saving PCI/PCIe info") do
|
73
|
+
save_pci_info()
|
74
|
+
end
|
75
|
+
|
76
|
+
do_with_message("Saving kernel module info") do
|
77
|
+
save_module_info()
|
78
|
+
end
|
79
|
+
|
80
|
+
do_with_message("Saving distro info") do
|
81
|
+
save_distro_info()
|
82
|
+
end
|
83
|
+
|
84
|
+
do_with_message("Saving sysctl info") do
|
85
|
+
save_sysctl_info()
|
86
|
+
end
|
87
|
+
|
88
|
+
do_with_message("Saving dmidecode info") do
|
89
|
+
save_dmidecode_info()
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
## Collect vendor specific info
|
94
|
+
|
95
|
+
# LSI MegaRAID
|
96
|
+
megacli_bin = "/opt/MegaRAID/MegaCli/MegaCli64"
|
97
|
+
if File.executable?(megacli_bin) && Process::UID.rid == 0
|
98
|
+
do_with_message("Saving MegaRAID settings") do
|
99
|
+
save_megaraid_info(megacli_bin)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
tmptar_path = Tempfile.new("fingerprint").path
|
104
|
+
|
105
|
+
Dir.chdir(tmpdir) do
|
106
|
+
if ! system("tar czf '#{tmptar_path}' #{output_basename}")
|
107
|
+
raise RuntimeError.new("Failed to execute tar(1)")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
FileUtils.mv(tmptar_path, @output_tarball)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
def do_with_message(message)
|
117
|
+
$stderr.print(message + " ... ")
|
118
|
+
$stderr.flush
|
119
|
+
|
120
|
+
@errors = []
|
121
|
+
|
122
|
+
begin
|
123
|
+
yield
|
124
|
+
rescue StandardError => err
|
125
|
+
$stderr.puts("failed")
|
126
|
+
@errors.push(err)
|
127
|
+
end
|
128
|
+
|
129
|
+
if @errors.empty?
|
130
|
+
$stderr.puts("done")
|
131
|
+
$stderr.puts("")
|
132
|
+
else
|
133
|
+
$stderr.puts("failed")
|
134
|
+
$stderr.puts("")
|
135
|
+
@errors.each do |error|
|
136
|
+
$stderr.puts(" ERROR: #{error.message}")
|
137
|
+
end
|
138
|
+
$stderr.puts("")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def read_file(src)
|
143
|
+
if File.exists?(src)
|
144
|
+
begin
|
145
|
+
return File.read(src)
|
146
|
+
rescue StandardError => err
|
147
|
+
@errors.push(err)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
|
154
|
+
def copy_file(src, dest)
|
155
|
+
content = read_file(src)
|
156
|
+
|
157
|
+
if content
|
158
|
+
File.open(dest, "w") do |f|
|
159
|
+
f.print(content)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def find_executable(command_name)
|
165
|
+
# try to find lspci
|
166
|
+
dirs = ["/sbin", "/usr/sbin", "/usr/local/sbin", "/usr/bin", "/usr/local/bin"]
|
167
|
+
dirs += ENV['PATH'].split(":")
|
168
|
+
|
169
|
+
bindir = dirs.find do |dir|
|
170
|
+
File.executable?(File.expand_path(command_name, dir))
|
171
|
+
end
|
172
|
+
|
173
|
+
if bindir
|
174
|
+
File.expand_path(command_name, bindir)
|
175
|
+
else
|
176
|
+
@errors << RuntimeError.new("#{command_name}(1) not found")
|
177
|
+
nil
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
def save_proc_info()
|
183
|
+
["cpuinfo", "meminfo", "mdstat", "mounts", "interrupts",
|
184
|
+
"diskstats", "partitions", "ioports",
|
185
|
+
].each do |entry|
|
186
|
+
copy_file("/proc/#{entry}", "#{@output_dir}/proc-#{entry}.log")
|
187
|
+
end
|
188
|
+
|
189
|
+
copy_file('/proc/scsi/scsi', "#{@output_dir}/proc-scsi.log")
|
190
|
+
|
191
|
+
File.open("#{@output_dir}/proc-sys-fs.log", "w") do |f|
|
192
|
+
Dir.glob("/proc/sys/fs/*").each do |path|
|
193
|
+
next unless File.file?(path)
|
194
|
+
begin
|
195
|
+
content = File.read(path)
|
196
|
+
rescue Errno::EACCES => err
|
197
|
+
@errors.push(err)
|
198
|
+
f.puts("## #{path}")
|
199
|
+
f.puts("permission denied")
|
200
|
+
f.puts("")
|
201
|
+
next
|
202
|
+
rescue StandardError => err
|
203
|
+
@errors.push(err)
|
204
|
+
next
|
205
|
+
end
|
206
|
+
f.puts("## #{path}")
|
207
|
+
f.puts(content)
|
208
|
+
f.puts("")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def save_irq_info()
|
214
|
+
File.open("#{@output_dir}/irq-smp-affinity.log", "w") do |f|
|
215
|
+
Dir.glob('/proc/irq/*/smp_affinity').sort_by do |path|
|
216
|
+
irqno = File.basename(File.dirname(path)).to_i
|
217
|
+
end.each do |path|
|
218
|
+
f.puts("## cat #{path}")
|
219
|
+
f.puts(`cat #{path}`)
|
220
|
+
f.puts("")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def save_device_info()
|
226
|
+
(Dir.glob('/sys/block/sd*') +
|
227
|
+
Dir.glob('/sys/block/xvd*')).each do |sd_dev|
|
228
|
+
File.open("#{@output_dir}/block-#{File.basename(sd_dev)}.log", "w") do |f|
|
229
|
+
f.puts("## ls -l #{sd_dev}")
|
230
|
+
f.puts(`ls -l #{sd_dev}`)
|
231
|
+
f.puts("")
|
232
|
+
['device/queue_depth',
|
233
|
+
'device/queue_type',
|
234
|
+
'device/iorequest_cnt',
|
235
|
+
'device/vendor',
|
236
|
+
'queue/scheduler',
|
237
|
+
'queue/nr_requests',
|
238
|
+
'queue/rq_affinity',
|
239
|
+
'queue/nomerges',
|
240
|
+
'queue/add_random',
|
241
|
+
'queue/rotational',
|
242
|
+
'queue/max_hw_sectors_kb',
|
243
|
+
'queue/physical_block_size',
|
244
|
+
'queue/optimal_io_size',
|
245
|
+
].each do |entity|
|
246
|
+
path = "#{sd_dev}/#{entity}"
|
247
|
+
if File.exists?(path)
|
248
|
+
f.puts("## #{path}")
|
249
|
+
f.puts(`cat #{path}`)
|
250
|
+
f.puts("")
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def save_disk_info()
|
258
|
+
File.open("#{@output_dir}/disk-by-path.log", "w") do |f|
|
259
|
+
f.puts(`ls -l /dev/disk/by-path/`)
|
260
|
+
end
|
261
|
+
|
262
|
+
File.open("#{@output_dir}/disk-by-uuid.log", "w") do |f|
|
263
|
+
f.puts(`ls -l /dev/disk/by-uuid/`)
|
264
|
+
end
|
265
|
+
|
266
|
+
File.open("#{@output_dir}/disk-by-id.log", "w") do |f|
|
267
|
+
f.puts(`ls -l /dev/disk/by-id/`)
|
268
|
+
end
|
269
|
+
|
270
|
+
File.open("#{@output_dir}/disk-multipath.log", "w") do |f|
|
271
|
+
f.puts(`/sbin/multipath -ll 2>&1`)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def save_pci_info()
|
276
|
+
lspci_bin = find_executable("lspci")
|
277
|
+
|
278
|
+
if lspci_bin
|
279
|
+
File.open("#{@output_dir}/lspci.log", "w") do |f|
|
280
|
+
f.puts(`#{lspci_bin} -D -vvv`)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
Dir.glob("/sys/devices/pci*/*/*/vendor") do |vendor|
|
285
|
+
pcidir = File.dirname(vendor)
|
286
|
+
|
287
|
+
prefix = [File.basename(File.dirname(File.dirname(pcidir))),
|
288
|
+
File.basename(File.dirname(pcidir)),
|
289
|
+
File.basename(pcidir)].join("-")
|
290
|
+
|
291
|
+
File.open("#{@output_dir}/#{prefix}.log", "w") do |f|
|
292
|
+
f.puts("## ls -l #{pcidir}")
|
293
|
+
f.puts(`ls -l #{pcidir}`)
|
294
|
+
f.puts("")
|
295
|
+
Dir.entries(pcidir).select do |filename|
|
296
|
+
! (["remove", "reset", "rescan", "rom", "uevent", "config",
|
297
|
+
"vpd"
|
298
|
+
].include?(filename) ||
|
299
|
+
filename =~ /\Aresource\d+\Z/ ||
|
300
|
+
filename =~ /\Aresource\d+_wc\Z/ # DDN device specific node (?)
|
301
|
+
)
|
302
|
+
end.each do |filename|
|
303
|
+
path = File.expand_path(filename, pcidir)
|
304
|
+
next unless File.file?(path)
|
305
|
+
content = read_file(path)
|
306
|
+
if content
|
307
|
+
f.puts("## #{path}")
|
308
|
+
f.puts(content)
|
309
|
+
f.puts("")
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
msi_irqs_dir = File.expand_path("msi_irqs", pcidir)
|
314
|
+
if File.directory?(msi_irqs_dir)
|
315
|
+
f.puts("## ls -l #{msi_irqs_dir}")
|
316
|
+
f.puts(`ls -l #{msi_irqs_dir}`)
|
317
|
+
f.puts("")
|
318
|
+
|
319
|
+
Dir.glob("#{msi_irqs_dir}/*/mode").each do |mode_path|
|
320
|
+
content = read_file(mode_path)
|
321
|
+
f.puts("## #{mode_path}")
|
322
|
+
f.puts(content)
|
323
|
+
f.puts("")
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def save_module_info()
|
331
|
+
modules = []
|
332
|
+
|
333
|
+
if lsmod_bin = find_executable("lsmod")
|
334
|
+
File.open("#{@output_dir}/lsmod.log", "w") do |f|
|
335
|
+
content = `#{lsmod_bin}`
|
336
|
+
f.puts(content)
|
337
|
+
|
338
|
+
lines = content.split("\n")
|
339
|
+
lines.shift # omit 1st line (label)
|
340
|
+
modules = lines.map do |line|
|
341
|
+
line.split[0]
|
342
|
+
end
|
343
|
+
end
|
344
|
+
else
|
345
|
+
return
|
346
|
+
end
|
347
|
+
|
348
|
+
modinfo_bin = find_executable("modinfo")
|
349
|
+
|
350
|
+
Dir.glob("/sys/module/*/parameters") do |params_dir|
|
351
|
+
module_name = File.basename(File.dirname(params_dir))
|
352
|
+
next unless modules.include?(module_name)
|
353
|
+
|
354
|
+
File.open("#{@output_dir}/module-#{module_name}.log", "w") do |f|
|
355
|
+
Dir.glob("#{params_dir}/*").each do |param_file|
|
356
|
+
param_name = File.basename(param_file)
|
357
|
+
# blacklisting
|
358
|
+
next if module_name == "apparmor" && param_name == "audit"
|
359
|
+
next if module_name == "apparmor" && param_name == "mode"
|
360
|
+
|
361
|
+
content = read_file(param_file)
|
362
|
+
f.puts("## #{param_file}")
|
363
|
+
f.puts(content)
|
364
|
+
f.puts("")
|
365
|
+
end
|
366
|
+
|
367
|
+
if modinfo_bin
|
368
|
+
content = `#{modinfo_bin} #{module_name}`
|
369
|
+
f.puts("## modinfo #{module_name}")
|
370
|
+
f.puts(content)
|
371
|
+
f.puts("")
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
def save_distro_info()
|
378
|
+
File.open("#{@output_dir}/distro.log", "w") do |f|
|
379
|
+
if system("which uname >/dev/null 2>&1")
|
380
|
+
content = `uname -a`
|
381
|
+
f.puts("## uname -a")
|
382
|
+
f.puts(content)
|
383
|
+
f.puts("")
|
384
|
+
end
|
385
|
+
|
386
|
+
if system("which lsb_release >/dev/null 2>&1")
|
387
|
+
content = `lsb_release -a 2>/dev/null`
|
388
|
+
f.puts("## lsb_release -a")
|
389
|
+
f.puts(content)
|
390
|
+
f.puts("")
|
391
|
+
end
|
392
|
+
|
393
|
+
if File.exists?("/etc/debian_version")
|
394
|
+
content = read_file("/etc/debian_version")
|
395
|
+
f.puts("## /etc/debian_version")
|
396
|
+
f.puts(content)
|
397
|
+
f.puts("")
|
398
|
+
end
|
399
|
+
|
400
|
+
if File.exists?("/etc/redhat-release")
|
401
|
+
content = read_file("/etc/redhat-release")
|
402
|
+
f.puts("## /etc/redhat-release")
|
403
|
+
f.puts(content)
|
404
|
+
f.puts("")
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
def save_sysctl_info()
|
410
|
+
sysctl_bin = find_executable("sysctl")
|
411
|
+
|
412
|
+
if sysctl_bin
|
413
|
+
File.open("#{@output_dir}/sysctl.log", "w") do |f|
|
414
|
+
content = `#{sysctl_bin} -a`
|
415
|
+
f.puts("## sysctl -a")
|
416
|
+
f.puts(content)
|
417
|
+
f.puts("")
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def save_dmidecode_info()
|
423
|
+
dmidecode_bin = find_executable("dmidecode")
|
424
|
+
|
425
|
+
if dmidecode_bin
|
426
|
+
File.open("#{@output_dir}/dmidecode.log", "w") do |f|
|
427
|
+
content = `#{dmidecode_bin} 2>&1`
|
428
|
+
f.puts("## dmidecode")
|
429
|
+
f.puts(content)
|
430
|
+
f.puts("")
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def save_megaraid_info(megacli_bin)
|
436
|
+
File.open("#{@output_dir}/megaraid.log", "w") do |f|
|
437
|
+
params_list = ["-AdpCount",
|
438
|
+
"-AdpAllinfo -aALL",
|
439
|
+
"-AdpBbuCmd -aALL",
|
440
|
+
"-LDInfo -Lall -aALL",
|
441
|
+
"-PDList -aALL"
|
442
|
+
].each do |params|
|
443
|
+
f.puts("## #{megacli_bin} #{params}")
|
444
|
+
f.puts(`#{megacli_bin} #{params}`.gsub(/\r/, ""))
|
445
|
+
f.puts("")
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
end # module Command
|
452
|
+
end # module PerfMonger
|
453
|
+
|