mool 2.0.1 → 3.0.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.
data/Rakefile CHANGED
@@ -1 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/mool.rb CHANGED
@@ -1,30 +1,36 @@
1
- mydir = File.expand_path(File.dirname(__FILE__))
2
-
3
- require 'i18n'
4
- I18n.load_path += Dir[File.join(mydir, 'locales', '*.yml')]
5
-
6
- require 'mool/version'
7
- require 'mool/service'
8
- require 'mool/cpu'
9
- require 'mool/disk'
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
- BYTES = "Bytes"
16
- KBYTES = "KBytes"
17
- MBYTES = "MBytes"
18
- GBYTES = "GBytes"
19
- PARSE_TYPES = { BYTES => 1, KBYTES => 2**10, MBYTES => 2**20, GBYTES => 2**30 }
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 = ((obj.instance_variable_get(var).to_f * PARSE_TYPES[obj.unity]) / PARSE_TYPES[parse])
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
@@ -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
- class MoolCpu
2
- PATH_PROC_CPUINFO = "/proc/cpuinfo"
3
- PROCESSORS = File.read(PATH_PROC_CPUINFO).scan(/processor\t*: (\d+)/).flatten + ["all"]
4
-
5
- attr_reader :cpu_name, :model_name, :cores, :usr, :nice, :sys, :iowait, :irq, :soft, :steal, :guest, :gnice, :idle, :total
6
-
7
- # ["all", "1", "2"]
8
- def initialize(process_number, opt={})
9
- raise "Cpu name incorrect!. Posible values: #{MoolCpu::PROCESSORS.join(",")}" unless MoolCpu::PROCESSORS.include?(process_number.to_s)
10
- result = opt.empty? ? MoolCpu.cpu_info[process_number.to_s] : opt
11
- @cpu_name = "cpu_#{process_number.to_s}"
12
- @model_name = result["model_name"]
13
- @cores = result["cpu_cores"].to_i
14
- @usr = result["%usr"].to_f
15
- @nice = result["%nice"].to_f
16
- @sys = result["%sys"].to_f # This is kernel %
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
- def self.cpu_info
28
- cpu_info = {}
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
- File.read(PATH_PROC_CPUINFO).gsub(/([^\n])\n([^\n])/, '\1 \2').scan(/processor\t*: (\d+).*model name\t*: (.*) stepping.*cpu cores\t*: (\d+)/).each do |v|
41
- cpu_info[v[0]]["model_name"] = v[1]
42
- cpu_info[v[0]]["cpu_cores"] = v[2]
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
- cpu_info
46
- end
49
+ def self.cpuinfo
50
+ cpu_info = {}
47
51
 
48
- def self.processors
49
- File.read(PATH_PROC_CPUINFO).scan(/processor\t*: (\d+)/).flatten + ["all"]
50
- end
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
- def self.all
54
- MoolCpu.cpu_info.map{ |key, value| MoolCpu.new(key, value) }
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
- class MoolDisk
2
- PATH_DEV_BLOCK = Dir.glob('/sys/dev/block/*')
3
-
4
- attr_accessor :path, :major, :minor, :devname, :devtype, :size, :swap, :mount_point, :file_system, :total_block, :block_used, :block_free, :partitions, :slaves, :unity
5
-
6
- def initialize(dev_name)
7
- @path = PATH_DEV_BLOCK.select{ |entry| ( File.read("#{entry}/dev").include?(dev_name)) ||
8
- ( File.read("#{entry}/uevent").include?(dev_name)) ||
9
- ( File.exist?("#{entry}/dm/name") &&
10
- File.read("#{entry}/dm/name").include?(dev_name)) }.first
11
- raise "Does't exist #{dev_name}!" if @path.nil?
12
- read_uevent
13
- logical_name
14
- swap
15
- capacity
16
- @unity = Mool::BYTES
17
- mounting_point
18
- file_system
19
- end
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
- def mounting_point
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
- def file_system
26
- @file_system ||= (Dir.glob("/sys/fs/**/*").select{|a| a.include?(@devname)}.first.split("/")[3] rescue nil)
27
- end
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
- def logical_name
30
- @logical_name ||= File.exists?("#{@path}/dm/name")? File.read("#{@path}/dm/name").chomp : @devname
31
- end
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
- def read_uevent
34
- @major, @minor, @devname, @devtype = File.read("#{@path}/uevent").scan(/.*=(\d+)\n.*=(\d+)\n.*=(\S+)\n.*=(\w+)\n/).flatten
35
- end
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
- def dev; @major + @minor; end
68
+ def dev
69
+ @major + @minor
70
+ end
38
71
 
39
- def is_disk?; @devtype == "disk"; end
72
+ def is_disk?
73
+ @devtype == 'disk'
74
+ end
40
75
 
41
- def is_partition?; @devtype == "partition"; end
76
+ def is_partition?
77
+ @devtype == 'partition'
78
+ end
42
79
 
43
- def swap; @swap ||= File.read("/proc/swaps")[/#{@logical_name} /].present?; end
80
+ def swap
81
+ @swap ||= Mool::Command.swap_command(@logical_name).present?
82
+ end
44
83
 
45
- def capacity
46
- unless (defined?(@total_block) && defined?(@block_used) && defined?(@block_free))
47
- result = `df`.scan(/(#{@logical_name}|#{@devname})\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)/).flatten
48
- @total_block = File.read("#{@path}/size").chomp.to_f * Mool::BLOCK_SIZE
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
- def partitions
55
- unless defined? @partitions
56
- @partitions = []
57
- if is_disk?
58
- Dir.glob("#{@path}/#{@devname}*").each do |part|
59
- @partitions << MoolDisk.new(part.split("/").last)
60
- end
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
- def slaves
67
- unless defined? @slaves
68
- @slaves = []
69
- PATH_DEV_BLOCK.select{ |entry| File.directory?("#{entry}/slaves/#{@devname}") }.each do |slave|
70
- @slaves << MoolDisk.new(slave.split("/").last)
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
- def used_percent
77
- @block_used / @total_block
78
- end
117
+ def used_percent
118
+ @block_used / @total_block
119
+ end
79
120
 
80
- def free_percent
81
- @block_free / @total_block
82
- end
121
+ def free_percent
122
+ @block_free / @total_block
123
+ end
83
124
 
84
- def self.all
85
- disks = []
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
- PATH_DEV_BLOCK.each do |entry|
88
- real_path = `readlink -f #{entry}`.chomp
89
- disks << MoolDisk.new(entry.split("/").last) if (not real_path.include?("virtual")) &&
90
- (not real_path.include?("/sr")) &&
91
- (not File.exist?("#{real_path}/partition")) &&
92
- Dir.glob("#{real_path}/slaves/*").empty?
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
- disks.each{ |disk| disk.partitions.each { |part| part.partitions and part.slaves }}
96
- disks.each{ |disk| disk.slaves.each { |part| part.partitions and part.slaves }}
97
- disks
98
- end
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
- def to_b; Mool.parse_to(self, ["@total_block", "@block_used", "@block_free"], Mool::BYTES); end
101
- def to_kb; Mool.parse_to(self, ["@total_block", "@block_used", "@block_free"], Mool::KBYTES); end
102
- def to_mb; Mool.parse_to(self, ["@total_block", "@block_used", "@block_free"], Mool::MBYTES); end
103
- def to_gb; Mool.parse_to(self, ["@total_block", "@block_used", "@block_free"], Mool::GBYTES); end
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
- def self.swap
106
- result = File.read("/proc/swaps").scan(/.*\n\/dev\/(\S+)/).flatten.first
107
- MoolDisk.new(result) unless result.nil?
108
- end
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
- def self.all_usable
111
- result = MoolDisk.all
112
- result.each do |disk|
113
- result += (disk.partitions + disk.slaves + (disk.partitions + disk.slaves).collect{|p| p.partitions + p.slaves }.flatten)
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