mool 2.0.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -1
- data/LICENSE.txt +17 -18
- data/README.md +394 -128
- data/Rakefile +9 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/mool.rb +24 -18
- data/lib/mool/command.rb +86 -0
- data/lib/mool/cpu.rb +74 -47
- data/lib/mool/disk.rb +159 -87
- data/lib/mool/memory.rb +48 -15
- data/lib/mool/process.rb +129 -0
- data/lib/mool/system.rb +54 -36
- data/lib/mool/version.rb +1 -1
- data/mool.gemspec +32 -17
- metadata +72 -53
- data/lib/mool/load_average.rb +0 -13
- data/lib/mool/service.rb +0 -80
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "mool"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/mool.rb
CHANGED
@@ -1,30 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
require
|
9
|
-
|
10
|
-
require 'mool/memory'
|
11
|
-
require 'mool/system'
|
1
|
+
%w[command
|
2
|
+
cpu
|
3
|
+
disk
|
4
|
+
memory
|
5
|
+
system
|
6
|
+
process
|
7
|
+
version].each do |file|
|
8
|
+
require "mool/#{file}"
|
9
|
+
end
|
12
10
|
|
13
11
|
module Mool
|
14
12
|
BLOCK_SIZE = 512
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
|
14
|
+
BYTES = 'Bytes'.freeze
|
15
|
+
KBYTES = 'KBytes'.freeze
|
16
|
+
MBYTES = 'MBytes'.freeze
|
17
|
+
GBYTES = 'GBytes'.freeze
|
18
|
+
|
19
|
+
PARSE_TYPES = {
|
20
|
+
BYTES => 1,
|
21
|
+
KBYTES => 2**10,
|
22
|
+
MBYTES => 2**20,
|
23
|
+
GBYTES => 2**30
|
24
|
+
}.freeze
|
20
25
|
|
21
26
|
def self.parse_to(obj, vars, parse)
|
22
27
|
vars.each do |var|
|
23
|
-
value = (
|
28
|
+
value = (obj.instance_variable_get(var).to_f *
|
29
|
+
PARSE_TYPES[obj.unity]) /
|
30
|
+
PARSE_TYPES[parse]
|
24
31
|
obj.instance_variable_set(var, value)
|
25
32
|
end
|
26
33
|
obj.unity = parse
|
27
34
|
obj
|
28
35
|
end
|
29
|
-
|
30
36
|
end
|
data/lib/mool/command.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
module Mool
|
2
|
+
module Command
|
3
|
+
|
4
|
+
def self.cpuinfo_command
|
5
|
+
File.read('/proc/cpuinfo')
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.mpstat_command
|
9
|
+
File.read('|mpstat -P ALL 1 1')
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.df_command
|
13
|
+
`df`
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.mount_command
|
17
|
+
File.read('/proc/mounts')
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.file_system_command
|
21
|
+
Dir.glob('/sys/fs/**/*')
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.logical_name_command(path)
|
25
|
+
File.exist?("#{path}/dm/name") ? File.read("#{path}/dm/name").chomp : nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.uevent_command(path)
|
29
|
+
File.read("#{path}/uevent")
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.swap_command(lname = nil)
|
33
|
+
result = File.read('/proc/swaps')
|
34
|
+
lname.present? ? result[/#{lname} /] : result
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.capacity_partition_command(path)
|
38
|
+
File.read("#{path}/size")
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.partitions_command(path, devname)
|
42
|
+
Dir.glob("#{path}/#{devname}*")
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.dev_block_command
|
46
|
+
Dir.glob('/sys/dev/block/*')
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.real_path_block_command(entry)
|
50
|
+
`readlink -f #{entry}`.chomp
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.real_path_command_exist?(real_path)
|
54
|
+
File.exist?("#{real_path}/partition")
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.slaves_command(real_path)
|
58
|
+
Dir.glob("#{real_path}/slaves/*")
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.meminfo_command
|
62
|
+
File.read('/proc/meminfo')
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.ps_command
|
66
|
+
# `ps --no-headers -o pid,user,pcpu,pmem,rss,priority,time,stat,nice,args -A`
|
67
|
+
`ps --no-headers -o ruser,user,rgroup,group,pid,ppid,pgid,pcpu,vsz,nice,etime,time,tty,comm,args=HEADER -A`
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.top_command
|
71
|
+
`top -c -b -n1`
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.uname_command
|
75
|
+
`uname -r`.chomp
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.uptime_command
|
79
|
+
`cat /proc/uptime`.chomp
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.loadavg_command
|
83
|
+
File.read('/proc/loadavg').chomp
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/mool/cpu.rb
CHANGED
@@ -1,56 +1,83 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@iowait = result["%iowait"].to_f
|
18
|
-
@irq = result["%irq"].to_f
|
19
|
-
@soft = result["%soft"].to_f
|
20
|
-
@steal = result["%steal"].to_f
|
21
|
-
@guest = result["%guest"].to_f
|
22
|
-
@gnice = result["%gnice"].to_f
|
23
|
-
@idle = result["%idle"].to_f
|
24
|
-
@total = @usr + @nice + @sys + @iowait + @irq + @soft + @steal + @guest
|
25
|
-
end
|
1
|
+
module Mool
|
2
|
+
class Cpu
|
3
|
+
attr_reader :cpu_name,
|
4
|
+
:model_name,
|
5
|
+
:cores,
|
6
|
+
:usr,
|
7
|
+
:nice,
|
8
|
+
:sys,
|
9
|
+
:iowait,
|
10
|
+
:irq,
|
11
|
+
:soft,
|
12
|
+
:steal,
|
13
|
+
:guest,
|
14
|
+
:gnice,
|
15
|
+
:idle,
|
16
|
+
:total
|
26
17
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
mpstat = File.read("|mpstat -P ALL 1 1").split("\n\n")[2].split("\n").map{|i| i.gsub(/^\S+:/, '').strip.split(/\s+/) }
|
31
|
-
mpstat_vars = mpstat.shift
|
32
|
-
mpstat_vars.shift
|
33
|
-
mpstat.each do |data|
|
34
|
-
res = {}
|
35
|
-
core_name = data.shift
|
36
|
-
data.each_with_index { |d, i| res.merge!(mpstat_vars[i] => d) }
|
37
|
-
cpu_info.merge!(core_name => res)
|
38
|
-
end
|
18
|
+
# ["all", "1", "2"]
|
19
|
+
def initialize(process_number, opt={})
|
20
|
+
result = Mool::Cpu.processors
|
39
21
|
|
40
|
-
|
41
|
-
|
42
|
-
|
22
|
+
unless result.include?(process_number.to_s)
|
23
|
+
raise "Cpu name incorrect!. Posible values: #{result.join(', ')}"
|
24
|
+
end
|
25
|
+
result = opt.empty? ? Mool::Command.cpuinfo[process_number.to_s] : opt
|
26
|
+
@cpu_name = "cpu_#{process_number}"
|
27
|
+
@model_name = result['model_name']
|
28
|
+
@cores = result['cpu_cores'].to_i
|
29
|
+
@usr = result['%usr'].to_f
|
30
|
+
@nice = result['%nice'].to_f
|
31
|
+
@sys = result['%sys'].to_f # This is kernel %
|
32
|
+
@iowait = result['%iowait'].to_f
|
33
|
+
@irq = result['%irq'].to_f
|
34
|
+
@soft = result['%soft'].to_f
|
35
|
+
@steal = result['%steal'].to_f
|
36
|
+
@guest = result['%guest'].to_f
|
37
|
+
@gnice = result['%gnice'].to_f
|
38
|
+
@idle = result['%idle'].to_f
|
39
|
+
@total = [@usr,
|
40
|
+
@nice,
|
41
|
+
@sys,
|
42
|
+
@iowait,
|
43
|
+
@irq,
|
44
|
+
@soft,
|
45
|
+
@steal,
|
46
|
+
@guest].sum
|
43
47
|
end
|
44
48
|
|
45
|
-
|
46
|
-
|
49
|
+
def self.cpuinfo
|
50
|
+
cpu_info = {}
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
mpstat = Mool::Command.mpstat_command.split("\n\n")[2].split("\n").map do |i|
|
53
|
+
i.gsub(/^\S+:/, '').strip.split(/\s+/)
|
54
|
+
end
|
55
|
+
|
56
|
+
mpstat_vars = mpstat.shift
|
57
|
+
mpstat_vars.shift
|
58
|
+
|
59
|
+
mpstat.each do |data|
|
60
|
+
res = {}
|
61
|
+
core_name = data.shift
|
62
|
+
data.each_with_index { |d, i| res.merge!(mpstat_vars[i] => d) }
|
63
|
+
cpu_info.merge!(core_name => res)
|
64
|
+
end
|
51
65
|
|
66
|
+
Mool::Command.cpuinfo_command.gsub(/([^\n])\n([^\n])/,
|
67
|
+
'\1 \2').scan(/processor\t*: (\d+).*model name\t*: (.*) stepping.*cpu cores\t*: (\d+)/).each do |v|
|
68
|
+
cpu_info[v[0]]['model_name'] = v[1]
|
69
|
+
cpu_info[v[0]]['cpu_cores'] = v[2]
|
70
|
+
end
|
52
71
|
|
53
|
-
|
54
|
-
|
72
|
+
cpu_info
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.processors
|
76
|
+
Mool::Command.cpuinfo_command.scan(/processor\t*: (\d+)/).flatten + ['all']
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.all
|
80
|
+
Mool::Cpu.cpuinfo.map { |key, value| Mool::Cpu.new(key, value) }
|
81
|
+
end
|
55
82
|
end
|
56
83
|
end
|
data/lib/mool/disk.rb
CHANGED
@@ -1,117 +1,189 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
1
|
+
module Mool
|
2
|
+
class Disk
|
3
|
+
attr_accessor :path,
|
4
|
+
:major,
|
5
|
+
:minor,
|
6
|
+
:devname,
|
7
|
+
:devtype,
|
8
|
+
:size,
|
9
|
+
:swap,
|
10
|
+
:mount_point,
|
11
|
+
:file_system,
|
12
|
+
:total_block,
|
13
|
+
:block_used,
|
14
|
+
:block_free,
|
15
|
+
:partitions,
|
16
|
+
:slaves,
|
17
|
+
:unity
|
18
|
+
|
19
|
+
def initialize(dev_name)
|
20
|
+
paths = Mool::Command.dev_block_command.select do |entry|
|
21
|
+
Mool::Disk.dev_name_command(entry).include?(dev_name) ||
|
22
|
+
Mool::Disk.uevent_command(entry).include?(dev_name) ||
|
23
|
+
Mool::Disk.logical_name_command(entry)
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
@mount_point ||= File.read("/proc/mounts").scan(/#{@logical_name} (\S+)/).flatten.first if File.read("/proc/mounts").include?(@logical_name)
|
23
|
-
end
|
26
|
+
@path = paths.first
|
24
27
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
raise "Does't exist #{dev_name}!" if @path.nil?
|
29
|
+
read_uevent
|
30
|
+
logical_name
|
31
|
+
swap
|
32
|
+
capacity
|
33
|
+
@unity = Mool::BYTES
|
34
|
+
mounting_point
|
35
|
+
file_system
|
36
|
+
end
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
|
38
|
+
def mounting_point
|
39
|
+
Mool::Command.mount_command.include?(@logical_name) &&
|
40
|
+
@mount_point ||= Mool::Command.mount_command.scan(
|
41
|
+
/#{@logical_name} (\S+)/
|
42
|
+
).flatten.first
|
43
|
+
end
|
32
44
|
|
33
|
-
|
34
|
-
|
35
|
-
|
45
|
+
def file_system
|
46
|
+
files = Mool::Command.file_system_command.select do |a|
|
47
|
+
a.include?(@devname)
|
48
|
+
end
|
49
|
+
|
50
|
+
files.first.present? &&
|
51
|
+
@file_system ||= files.first.split('/')[3]
|
52
|
+
end
|
53
|
+
|
54
|
+
def logical_name
|
55
|
+
lname = Mool::Command.logical_name_command(@path)
|
56
|
+
@logical_name = lname.present? ? lname : @devname
|
57
|
+
end
|
58
|
+
|
59
|
+
def read_uevent
|
60
|
+
@major,
|
61
|
+
@minor,
|
62
|
+
@devname,
|
63
|
+
@devtype = Mool::Command.uevent_command(@path).scan(
|
64
|
+
/.*=(\d+)\n.*=(\d+)\n.*=(\S+)\n.*=(\w+)\n/
|
65
|
+
).flatten
|
66
|
+
end
|
36
67
|
|
37
|
-
|
68
|
+
def dev
|
69
|
+
@major + @minor
|
70
|
+
end
|
38
71
|
|
39
|
-
|
72
|
+
def is_disk?
|
73
|
+
@devtype == 'disk'
|
74
|
+
end
|
40
75
|
|
41
|
-
|
76
|
+
def is_partition?
|
77
|
+
@devtype == 'partition'
|
78
|
+
end
|
42
79
|
|
43
|
-
|
80
|
+
def swap
|
81
|
+
@swap ||= Mool::Command.swap_command(@logical_name).present?
|
82
|
+
end
|
44
83
|
|
45
|
-
|
46
|
-
|
47
|
-
result =
|
48
|
-
|
84
|
+
def capacity
|
85
|
+
return if defined?(@total_block) && defined?(@block_used) && defined?(@block_free)
|
86
|
+
result = Mool::Command.df_command.scan(
|
87
|
+
/(#{@logical_name}|#{@devname})\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)/
|
88
|
+
).flatten
|
89
|
+
@total_block = Mool::Command.capacity_partition_command(@path).chomp.to_f *
|
90
|
+
Mool::BLOCK_SIZE
|
49
91
|
@block_used = result[2].to_f * Mool::BLOCK_SIZE
|
50
92
|
@block_free = @total_block - @block_used
|
51
93
|
end
|
52
|
-
end
|
53
94
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
95
|
+
def partitions
|
96
|
+
return @partitions if defined? @partitions
|
97
|
+
return unless is_disk?
|
98
|
+
@partitions = Mool::Command.partitions_command(
|
99
|
+
@path,
|
100
|
+
@devname
|
101
|
+
).map do |part|
|
102
|
+
MoolDisk.new(part.split('/').last)
|
61
103
|
end
|
62
104
|
end
|
63
|
-
@partitions
|
64
|
-
end
|
65
105
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
106
|
+
def slaves
|
107
|
+
return @slaves if defined? @slaves
|
108
|
+
blocks = Mool::Command.dev_block_command.select do |entry|
|
109
|
+
File.directory?("#{entry}/slaves/#{@devname}")
|
110
|
+
end
|
111
|
+
|
112
|
+
@slaves = blocks.map do |slave|
|
113
|
+
MoolDisk.new(slave.split('/').last)
|
71
114
|
end
|
72
115
|
end
|
73
|
-
@slaves
|
74
|
-
end
|
75
116
|
|
76
|
-
|
77
|
-
|
78
|
-
|
117
|
+
def used_percent
|
118
|
+
@block_used / @total_block
|
119
|
+
end
|
79
120
|
|
80
|
-
|
81
|
-
|
82
|
-
|
121
|
+
def free_percent
|
122
|
+
@block_free / @total_block
|
123
|
+
end
|
83
124
|
|
84
|
-
|
85
|
-
|
125
|
+
def to_b
|
126
|
+
Mool.parse_to(self,
|
127
|
+
['@total_block',
|
128
|
+
'@block_used',
|
129
|
+
'@block_free'],
|
130
|
+
Mool::BYTES)
|
131
|
+
end
|
86
132
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
133
|
+
def to_kb
|
134
|
+
Mool.parse_to(self,
|
135
|
+
['@total_block',
|
136
|
+
'@block_used',
|
137
|
+
'@block_free'],
|
138
|
+
Mool::KBYTES)
|
93
139
|
end
|
94
140
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
141
|
+
def to_mb
|
142
|
+
Mool.parse_to(self,
|
143
|
+
['@total_block',
|
144
|
+
'@block_used',
|
145
|
+
'@block_free'],
|
146
|
+
Mool::MBYTES)
|
147
|
+
end
|
99
148
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
149
|
+
def to_gb
|
150
|
+
Mool.parse_to(self,
|
151
|
+
['@total_block',
|
152
|
+
'@block_used',
|
153
|
+
'@block_free'],
|
154
|
+
Mool::GBYTES)
|
155
|
+
end
|
104
156
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
157
|
+
def self.all
|
158
|
+
disks = []
|
159
|
+
|
160
|
+
Mool::Command.dev_block_command.each do |entry|
|
161
|
+
real_path = Mool::Command.real_path_block_command(entry)
|
162
|
+
next unless !real_path.include?('virtual') &&
|
163
|
+
!real_path.include?('/sr') &&
|
164
|
+
!Mool::Command.real_path_command_exist?(real_path) &&
|
165
|
+
Mool::Command.slaves_command(real_path).empty?
|
166
|
+
disks << Mool::Disk.new(entry.split('/').last)
|
167
|
+
end
|
109
168
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
169
|
+
disks.each { |disk| disk.partitions.each { |part| part.partitions && part.slaves }}
|
170
|
+
disks.each { |disk| disk.slaves.each { |part| part.partitions && part.slaves }}
|
171
|
+
disks
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.swap
|
175
|
+
result = Mool::Command.swap_command.scan(%r{/.*\n\/dev\/(\S+)/}).flatten.first
|
176
|
+
Mool::Disk.new(result) unless result.nil?
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.all_usable
|
180
|
+
result = MoolDisk.all
|
181
|
+
result.each do |disk|
|
182
|
+
result += (disk.partitions +
|
183
|
+
disk.slaves +
|
184
|
+
(disk.partitions + disk.slaves).collect { |p| p.partitions + p.slaves }.flatten)
|
185
|
+
end
|
186
|
+
result.reject(&:blank?).select { |d| (d.partitions + d.slaves).blank? }
|
114
187
|
end
|
115
|
-
result.reject(&:blank?).select{|d| (d.partitions + d.slaves).blank? }
|
116
188
|
end
|
117
189
|
end
|