mool 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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