linux_stat 1.1.1 → 1.3.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.
@@ -1,4 +1,11 @@
1
1
  module LinuxStat
2
+ # Helps you convert bytes to a unit like:
3
+ #
4
+ # 1. kilobyte, megabyte, gigabyte, terabyte, petabyte, exabyte, zettabyte, yottabyte
5
+ # 2. kibibyte, mebibyte, gibibyte, tebibyte, pebibyte, exbibyte, zebibyte, yobibyte
6
+ # 3. kB, MB, GB, TB, PB, EB, ZB, YB
7
+ # 4. kiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB
8
+
2
9
  module PrettifyBytes
3
10
  class << self
4
11
  ##
@@ -1,4 +1,7 @@
1
1
  module LinuxStat
2
+ # Shows various information about a process that is either
3
+ # running, sleeping, idle or a zombie.
4
+
2
5
  module Process
3
6
  class << self
4
7
  ##
@@ -6,10 +9,17 @@ module LinuxStat
6
9
  #
7
10
  # The return type is an Array of Integers.
8
11
  def list
9
- Dir['/proc/*'].select { |x|
10
- pid = File.split(x)[1]
11
- pid.to_i.to_s == pid
12
- }.map! { |x| File.split(x)[-1].to_i }
12
+ d = Dir['/proc/*'.freeze]
13
+ ret, i = [], -1
14
+ count = d.length
15
+
16
+ while(i += 1) < count
17
+ pid = File.split(d[i])[1]
18
+ pid_i = pid.to_i
19
+ ret << pid_i if pid_i.to_s == pid
20
+ end
21
+
22
+ ret
13
23
  end
14
24
 
15
25
  ##
@@ -17,28 +27,42 @@ module LinuxStat
17
27
  #
18
28
  # The return type is Integer.
19
29
  def count
20
- list.count
30
+ list.length
21
31
  end
22
32
 
23
33
  ##
24
34
  # Returns all the id of processes mapped with their names as a Hash.
25
35
  def names
26
- list.reduce({}) { |h, x|
36
+ h, i = {}, -1
37
+
38
+ l = list
39
+ count = l.length
40
+
41
+ while(i += 1) < count
42
+ x = l[i]
43
+
27
44
  begin
28
- h.merge!( x => IO.foreach(File.join('/proc', x.to_s, 'status')).first.split[1] )
29
- rescue Exception
30
- h
45
+ h.merge!( x => IO.foreach("/proc/#{x}/status").first.split[1])
46
+ rescue StandardError
31
47
  end
32
- }
48
+ end
49
+ h
33
50
  end
34
51
 
35
52
  ##
36
53
  # Returns all the id of processes mapped with their status as a Hash.
37
54
  def types
38
- list.reduce({}) { |h, x|
55
+ h, i = {}, -1
56
+
57
+ l = list
58
+ count = l.length
59
+
60
+ while(i += 1) < count
61
+ x = l[i]
62
+
39
63
  begin
40
64
  h.merge!(x =>
41
- case IO.read(File.join('/proc', x.to_s, 'stat')).split[2]
65
+ case IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0]
42
66
  when ?S.freeze then :sleeping
43
67
  when ?I.freeze then :idle
44
68
  when ?Z.freeze then :zombie
@@ -46,10 +70,11 @@ module LinuxStat
46
70
  else :unknown
47
71
  end
48
72
  )
49
- rescue Exception
50
- h
73
+ rescue StandardError
51
74
  end
52
- }
75
+ end
76
+
77
+ h
53
78
  end
54
79
 
55
80
  ##
@@ -58,8 +83,8 @@ module LinuxStat
58
83
  def sleeping
59
84
  list.select { |x|
60
85
  begin
61
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?S
62
- rescue Exception
86
+ IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?S.freeze
87
+ rescue StandardError
63
88
  nil
64
89
  end
65
90
  }
@@ -71,8 +96,8 @@ module LinuxStat
71
96
  def idle
72
97
  list.select { |x|
73
98
  begin
74
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?I
75
- rescue Exception
99
+ IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?I.freeze
100
+ rescue StandardError
76
101
  nil
77
102
  end
78
103
  }
@@ -84,8 +109,8 @@ module LinuxStat
84
109
  def zombie
85
110
  list.select { |x|
86
111
  begin
87
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?Z
88
- rescue Exception
112
+ IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?Z.freeze
113
+ rescue StandardError
89
114
  nil
90
115
  end
91
116
  }
@@ -97,8 +122,8 @@ module LinuxStat
97
122
  def running
98
123
  list.select { |x|
99
124
  begin
100
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?R
101
- rescue Exception
125
+ IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?R.freeze
126
+ rescue StandardError
102
127
  nil
103
128
  end
104
129
  }
@@ -1,4 +1,11 @@
1
1
  module LinuxStat
2
+ # Shows various information about a process that is either
3
+ # running, sleeping, idle or a zombie.
4
+ # Most methods can take a PID, but some uses polling to calculate
5
+ # something, they can accept options instead of arguments.
6
+ # Consult the documentation on the specific methods
7
+ # for more details on that.
8
+
2
9
  module ProcessInfo
3
10
  class << self
4
11
  ##
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Swap devices related information of the current system.
3
+
2
4
  module Swap
3
5
  class << self
4
6
  ##
@@ -8,7 +10,7 @@ module LinuxStat
8
10
  def list
9
11
  return {} unless swaps_readable?
10
12
 
11
- file = IO.readlines('/proc/swaps').drop(1)
13
+ file = IO.readlines('/proc/swaps'.freeze).drop(1)
12
14
  file.reduce({}) do |h, x|
13
15
  name, *stats = x.strip.split
14
16
  h.merge!(name => stats.map! { |v| v.to_i.to_s == v ? v.to_i : v.to_sym })
@@ -20,7 +22,7 @@ module LinuxStat
20
22
  #
21
23
  # If the info isn't available, it will return an empty Hash.
22
24
  def any?
23
- !!IO.foreach('/proc/swaps').drop(1).first
25
+ !!IO.foreach('/proc/swaps'.freeze).first(2)[1]
24
26
  end
25
27
 
26
28
  # Show aggregated used and available swap.
@@ -114,7 +116,7 @@ module LinuxStat
114
116
  def read_usage
115
117
  return [[], []] unless swaps_readable?
116
118
 
117
- val = IO.readlines('/proc/swaps').drop(1)
119
+ val = IO.readlines('/proc/swaps'.freeze).drop(1)
118
120
  return [[], []] if val.empty?
119
121
 
120
122
  val.map! { |x|
@@ -123,7 +125,7 @@ module LinuxStat
123
125
  end
124
126
 
125
127
  def swaps_readable?
126
- @@swaps_readable ||= File.readable?('/proc/swaps')
128
+ @@swaps_readable ||= File.readable?('/proc/swaps'.freeze)
127
129
  end
128
130
  end
129
131
  end
@@ -0,0 +1,122 @@
1
+ module LinuxStat
2
+ # Sensors are available to /sys/class/hwmon
3
+ # This module just reads the files inside them to get the sensor information.
4
+ #
5
+ # https://www.kernel.org/doc/Documentation/thermal/sysfs-api.txt
6
+
7
+ module Thermal
8
+ class << self
9
+ ##
10
+ # Get temperatures from all sensors.
11
+ #
12
+ # The return value is an Array of Hashes.
13
+ #
14
+ # It opens various files from /sys/, and it should be
15
+ # considered very slow.
16
+ #
17
+ # Each hash may contain information including:
18
+ #
19
+ # path, name, label
20
+ # temperature, temp_crit, temp_max
21
+ #
22
+ # But if the info isn't available, it will return an empty Array.
23
+ def temperatures
24
+ query_hwmon('temp'.freeze, :temperature, true)
25
+ end
26
+
27
+ ##
28
+ # Get RPM from all fans.
29
+ #
30
+ # The return value is an Array of Hashes.
31
+ #
32
+ # It opens various files from /sys/, and it should be
33
+ # considered very slow.
34
+ #
35
+ # Each hash may contain information including:
36
+ #
37
+ # path, name, label
38
+ # rpm, temp_crit, temp_max
39
+ #
40
+ # But if the info isn't available, it will return an empty Array.
41
+ def fans
42
+ query_hwmon('fan'.freeze, :rpm)
43
+ end
44
+
45
+ ##
46
+ # Counts the number of sensors (fans are not counted)
47
+ #
48
+ # The return type is an Integer.
49
+ def count_sensors
50
+ return 0 unless hwmon_readable?
51
+
52
+ Dir["/sys/class/hwmon/hwmon[0-9]*/temp[0-9]*_input".freeze].size
53
+ end
54
+
55
+ ##
56
+ # Counts the number of fans (sensors are not counted)
57
+ #
58
+ # The return type is an Integer.
59
+ def count_fans
60
+ return 0 unless hwmon_readable?
61
+
62
+ Dir["/sys/class/hwmon/hwmon[0-9]*/fan[0-9]*_input".freeze].size
63
+ end
64
+
65
+ private
66
+ def hwmon_readable?
67
+ @@hwmon_readable ||= File.readable?("/sys/class/hwmon/")
68
+ end
69
+
70
+ def query_hwmon(mon, key, div = false)
71
+ return [] unless hwmon_readable?
72
+
73
+ name = dir = ''.freeze
74
+
75
+ files = Dir["/sys/class/hwmon/hwmon[0-9]*/#{mon}[0-9]*_input".freeze]
76
+ i = -1
77
+ ret = []
78
+
79
+ while x = files[i += 1]
80
+ splitted = File.split(x)
81
+ path = File.join(splitted[0..-2])
82
+
83
+ n = splitted[-1][/.*_/]
84
+
85
+ label_f = "#{path}/#{n}label"
86
+ label = File.readable?(label_f) ? IO.read(label_f, encoding: 'ASCII-8BIT'.freeze).strip : nil
87
+
88
+ temp_crit_f = "#{path}/#{n}crit"
89
+ temp_crit = File.readable?(temp_crit_f) ? IO.read(temp_crit_f, encoding: 'ASCII-8BIT'.freeze).to_i : nil
90
+
91
+ temp_max_f = "#{path}/#{n}max"
92
+ temp_max = File.readable?(temp_max_f) ? IO.read(temp_max_f, encoding: 'ASCII-8BIT'.freeze).to_i : nil
93
+
94
+ value = File.readable?(x) ? IO.read(x).to_i : nil
95
+
96
+ if dir != path
97
+ dir = path
98
+ name_f = "#{path}/name"
99
+ name = File.readable?(name_f) ? IO.read(name_f, encoding: 'ASCII-8BIT'.freeze).tap(&:strip!) : ''.freeze
100
+ end
101
+
102
+ if div
103
+ value /= 1000.0
104
+ temp_max /= 1000.0 if temp_max
105
+ temp_crit /= 1000.0 if temp_crit
106
+ end
107
+
108
+ h = {path: path, name: name}
109
+
110
+ h.merge!(label: label) if label
111
+ h.merge!(key => value)
112
+ h.merge!(temp_crit: temp_crit) if temp_crit
113
+ h.merge!(temp_crit: temp_max) if temp_max
114
+
115
+ ret.push(h)
116
+ end
117
+
118
+ ret
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various USB device related information of the current system.
3
+
2
4
  module USB
3
5
  class << self
4
6
  ##
@@ -49,73 +51,75 @@ module LinuxStat
49
51
  return [] unless @@sys_usb_readable
50
52
 
51
53
  Dir['/sys/bus/usb/devices/*/'.freeze].sort!.map! { |x|
52
- id_vendor_file = File.join(x, 'idVendor'.freeze)
53
- next unless File.readable?(id_vendor_file)
54
- id_vendor = IO.read(id_vendor_file).strip
54
+ begin
55
+ id_vendor_file = File.join(x, 'idVendor'.freeze)
56
+ next unless File.readable?(id_vendor_file)
57
+ id_vendor = IO.read(id_vendor_file).strip
55
58
 
56
- id_product_file = File.join(x, 'idProduct'.freeze)
57
- next unless File.readable?(id_vendor_file)
58
- id_product = IO.read(id_product_file).strip
59
+ id_product_file = File.join(x, 'idProduct'.freeze)
60
+ next unless File.readable?(id_vendor_file)
61
+ id_product = IO.read(id_product_file).strip
59
62
 
60
- bus_num_file = File.join(x, 'busnum'.freeze)
61
- bus_num = File.readable?(bus_num_file) ? IO.read(bus_num_file).strip : ''.freeze
63
+ bus_num_file = File.join(x, 'busnum'.freeze)
64
+ bus_num = File.readable?(bus_num_file) ? IO.read(bus_num_file).strip : ''.freeze
62
65
 
63
- dev_num_file = File.join(x, 'devnum'.freeze)
64
- dev_num = File.readable?(dev_num_file) ? IO.read(dev_num_file).strip : ''.freeze
66
+ dev_num_file = File.join(x, 'devnum'.freeze)
67
+ dev_num = File.readable?(dev_num_file) ? IO.read(dev_num_file).strip : ''.freeze
65
68
 
66
- serial_file = File.join(x, 'serial'.freeze)
67
- serial = File.readable?(serial_file) ? IO.read(serial_file).strip : ''.freeze
69
+ serial_file = File.join(x, 'serial'.freeze)
70
+ serial = File.readable?(serial_file) ? IO.read(serial_file).strip : ''.freeze
68
71
 
69
- product_file = File.join(x, 'product'.freeze)
70
- product = File.readable?(product_file) ? IO.read(product_file).strip : ''.freeze
72
+ product_file = File.join(x, 'product'.freeze)
73
+ product = File.readable?(product_file) ? IO.read(product_file).strip : ''.freeze
71
74
 
72
- manufacturer_file = File.join(x, 'manufacturer'.freeze)
73
- manufacturer = File.readable?(manufacturer_file) ? IO.read(manufacturer_file).strip : ''.freeze
75
+ manufacturer_file = File.join(x, 'manufacturer'.freeze)
76
+ manufacturer = File.readable?(manufacturer_file) ? IO.read(manufacturer_file).strip : ''.freeze
74
77
 
75
- removable_file = File.join(x, 'removable'.freeze)
76
- removable = File.readable?(removable_file) ? IO.read(removable_file).strip : ''.freeze
78
+ removable_file = File.join(x, 'removable'.freeze)
79
+ removable = File.readable?(removable_file) ? IO.read(removable_file).strip.downcase : ''.freeze
77
80
 
78
- authorized_file = File.join(x, 'authorized'.freeze)
79
- authorized = File.readable?(authorized_file) ? IO.read(authorized_file).to_i : ''.freeze
81
+ authorized_file = File.join(x, 'authorized'.freeze)
82
+ authorized = File.readable?(authorized_file) ? IO.read(authorized_file).to_i : ''.freeze
80
83
 
81
- b_max_power_file = File.join(x, 'bMaxPower'.freeze)
82
- b_max_power = File.readable?(b_max_power_file) ? IO.read(b_max_power_file).strip : ''.freeze
84
+ b_max_power_file = File.join(x, 'bMaxPower'.freeze)
85
+ b_max_power = File.readable?(b_max_power_file) ? IO.read(b_max_power_file).strip : ''.freeze
83
86
 
84
- b_max_packet_size0_file = File.join(x, 'bMaxPacketSize0'.freeze)
85
- b_max_packet_size0 = File.readable?(b_max_packet_size0_file) ? IO.read(b_max_packet_size0_file).to_i : ''.freeze
87
+ b_max_packet_size0_file = File.join(x, 'bMaxPacketSize0'.freeze)
88
+ b_max_packet_size0 = File.readable?(b_max_packet_size0_file) ? IO.read(b_max_packet_size0_file).to_i : ''.freeze
86
89
 
87
- query = hwdata ? query_hwdata(id_vendor, id_product) : {}
90
+ query = hwdata ? query_hwdata(id_vendor, id_product) : {}
88
91
 
89
- removable.downcase!
90
- is_removable = if removable == 'removable'.freeze
91
- true
92
- elsif removable == 'unknown'.freeze
93
- nil
94
- else
95
- false
96
- end
92
+ is_removable = if removable == 'removable'.freeze
93
+ true
94
+ elsif removable == 'unknown'.freeze
95
+ nil
96
+ else
97
+ false
98
+ end
97
99
 
98
- ret = {
99
- path: x, id: "#{id_vendor}:#{id_product}",
100
- vendor_id: id_vendor, product_id: id_product
101
- }
100
+ ret = {
101
+ path: x, id: "#{id_vendor}:#{id_product}",
102
+ vendor_id: id_vendor, product_id: id_product
103
+ }
102
104
 
103
- ret.merge!(bus_num: bus_num.to_i) unless bus_num.empty?
104
- ret.merge!(dev_num: dev_num.to_i) unless dev_num.empty?
105
+ ret.merge!(bus_num: bus_num.to_i) unless bus_num.empty?
106
+ ret.merge!(dev_num: dev_num.to_i) unless dev_num.empty?
105
107
 
106
- ret.merge!(serial: serial) unless serial.empty?
108
+ ret.merge!(serial: serial) unless serial.empty?
107
109
 
108
- ret.merge!(hwdata: query) unless query.empty?
109
- ret.merge!(product: product) unless product.empty?
110
- ret.merge!(manufacturer: manufacturer) unless manufacturer.empty?
110
+ ret.merge!(hwdata: query) unless query.empty?
111
+ ret.merge!(product: product) unless product.empty?
112
+ ret.merge!(manufacturer: manufacturer) unless manufacturer.empty?
111
113
 
112
- ret.merge!(removable: is_removable) unless is_removable.nil?
113
- ret.merge!(authorized: authorized == 1)
114
+ ret.merge!(removable: is_removable) unless is_removable.nil?
115
+ ret.merge!(authorized: authorized == 1)
114
116
 
115
- ret.merge!(b_max_power: b_max_power) unless b_max_power.empty?
116
- ret.merge!(b_max_packet_size0: b_max_packet_size0) if b_max_packet_size0
117
+ ret.merge!(b_max_power: b_max_power) unless b_max_power.empty?
118
+ ret.merge!(b_max_packet_size0: b_max_packet_size0) if b_max_packet_size0
117
119
 
118
- ret
120
+ ret
121
+ rescue StandardError
122
+ end
119
123
  }.tap(&:compact!)
120
124
  end
121
125