linux_stat 1.2.3 → 1.6.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,6 @@
1
1
  module LinuxStat
2
+ # Shows various battery related information of the current system.
3
+
2
4
  module Battery
3
5
  PATH = "/sys/class/power_supply/BAT0".freeze
4
6
 
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various BIOS related information of the current system.
3
+
2
4
  module BIOS
3
5
  class << self
4
6
  ##
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various CPU related information of the current system.
3
+
2
4
  module CPU
3
5
  class << self
4
6
  ##
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Filesystem related information of the current system.
3
+
2
4
  module Filesystem
3
5
  class << self
4
6
  ##
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Kernel related information of the current system.
3
+
2
4
  module Kernel
3
5
  class << self
4
6
  ##
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Memory related information of the current system.
3
+
2
4
  module Memory
3
5
  class << self
4
6
  ##
@@ -33,13 +35,23 @@ module LinuxStat
33
35
  end
34
36
 
35
37
  ##
36
- # Returns the total memory details reported by /proc/meminfo.
38
+ # Returns the total memory reported by LS::Sysinfo.totalram()
37
39
  # The value is in Kilobyte.
38
40
  #
39
41
  # It retuns an Integer but if the info is not available, it will return nil.
40
42
  def total
41
- return nil unless meminfo?
42
- IO.foreach('/proc/meminfo'.freeze).first.split[1].to_i
43
+ v = LinuxStat::Sysinfo.totalram
44
+ v ? v.fdiv(1024).to_i : nil
45
+ end
46
+
47
+ ##
48
+ # Returns the free memory reported by LS::Sysinfo.freeram()
49
+ # The value is in Kilobyte.
50
+ #
51
+ # It retuns an Integer but if the info is not available, it will return nil.
52
+ def free
53
+ v = LinuxStat::Sysinfo.freeram
54
+ v ? v.fdiv(1024).to_i : nil
43
55
  end
44
56
 
45
57
  ##
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Mounted device related information of the current system.
3
+
2
4
  module Mounts
3
5
  class << self
4
6
  ##
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Net related information of the current system.
3
+
2
4
  module Net
3
5
  class << self
4
6
  DEV = '/proc/net/dev'.freeze
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various OS related information of the current system.
3
+
2
4
  module OS
3
5
  class << self
4
6
  ##
@@ -138,6 +140,8 @@ module LinuxStat
138
140
  #
139
141
  # => {:hour=>10, :minute=>34, :second=>12.59}
140
142
  #
143
+ # Using uptime is 10x slower than using uptime_i
144
+ #
141
145
  # If the stat isn't available, an empty hash is returned.
142
146
  def uptime
143
147
  return {} unless uptime_readable?
@@ -156,6 +160,56 @@ module LinuxStat
156
160
  }.freeze
157
161
  end
158
162
 
163
+ ##
164
+ # Returns Float uptime of the system reported by /proc/uptime
165
+ # LinuxStat::OS.uptime_f
166
+ #
167
+ # => 28956.34
168
+ #
169
+ # The value is generally rounded to 2 decimal places.
170
+ #
171
+ # Using uptime_f is 10x slower than using uptime_i
172
+ #
173
+ # If the stat isn't available, nil is returned.
174
+ def uptime_f
175
+ return nil unless uptime_readable?
176
+ IO.foreach('/proc/uptime'.freeze, ' ').next.to_f
177
+ end
178
+
179
+ ##
180
+ # Returns uptime of the system reported by LinuxStat::Sysinfo.uptime()
181
+ # LinuxStat::OS.uptime_i
182
+ #
183
+ # => 28956
184
+ #
185
+ # If the stat isn't available, nil is returned.
186
+ def uptime_i
187
+ LinuxStat::Sysinfo.uptime
188
+ end
189
+
190
+ ##
191
+ # The first three fields in this file are load average
192
+ # figures giving the number of jobs in the run queue (state R)
193
+ # or waiting for disk I/O (state D) averaged over 1, 5,
194
+ # and 15 minutes. They are the same as the load average
195
+ # numbers given by uptime(1) and other programs.
196
+ # https://man7.org/linux/man-pages/man5/procfs.5.html
197
+ #
198
+ # The return type is an Hash containing the values
199
+ # that maps to 1, 5, and 15.
200
+ # This method calls LinuxStat::Sysinfo.loads() directly.
201
+ #
202
+ # However, if the info isn't available, it will return nil as values.
203
+ def loadavg
204
+ loads = LinuxStat::Sysinfo.loads
205
+
206
+ {
207
+ 1 => loads[0],
208
+ 5 => loads[1],
209
+ 15 => loads[2]
210
+ }
211
+ end
212
+
159
213
  alias distrib_version version
160
214
 
161
215
  private
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various PCI device related information of the current system.
3
+
2
4
  module PCI
3
5
  class << self
4
6
  ##
@@ -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
  ##
@@ -16,13 +23,13 @@ module LinuxStat
16
23
  # LinuxStat::PrettifyBytes.convert_decimal(1024 ** 3)
17
24
  #
18
25
  # => "1.07 gigabytes"
19
- def convert_decimal(n)
26
+ def convert_decimal(n, precision: 2)
20
27
  @@d_units ||= %W(#{''} kilo mega giga tera peta exa zetta)
21
28
  .map.with_index { |x, i| [x, 1000.**(i + 1)] }
22
29
  unit = @@d_units.find { |x| n < x[1] } || ['yotta'.freeze, 10 ** 27]
23
30
 
24
31
  converted = n.fdiv(unit[1] / 1000).round(2)
25
- "#{pad_left(converted)} #{unit[0]}byte#{?s.freeze if converted != 1}"
32
+ "#{pad_left(converted, precision)} #{unit[0]}byte#{?s.freeze if converted != 1}"
26
33
  end
27
34
 
28
35
  # Converts a number to binary byte units and outputs with the IEC prefix
@@ -39,13 +46,13 @@ module LinuxStat
39
46
  # LinuxStat::PrettifyBytes.convert_binary(1024 ** 3)
40
47
  #
41
48
  # => "1.0 gibibyte"
42
- def convert_binary(n)
49
+ def convert_binary(n, precision: 2)
43
50
  @@b_units ||= %W(#{''} kibi mebi gibi tebi pebi exbi zebi)
44
51
  .map.with_index { |x, i| [x, 1024.**(i + 1)] }
45
52
  unit = @@b_units.find { |x| n < x[1] } || ['yobi'.freeze, 10 ** 27]
46
53
 
47
54
  converted = n.fdiv(unit[1] / 1024).round(2)
48
- "#{pad_left(converted)} #{unit[0]}byte#{?s.freeze if converted != 1}"
55
+ "#{pad_left(converted, precision)} #{unit[0]}byte#{?s.freeze if converted != 1}"
49
56
  end
50
57
 
51
58
  # Converts a number to decimal byte units
@@ -62,13 +69,13 @@ module LinuxStat
62
69
  # LinuxStat::PrettifyBytes.convert_short_decimal(1024 ** 3)
63
70
  #
64
71
  # => "1.07 GB"
65
- def convert_short_decimal(n)
72
+ def convert_short_decimal(n, precision: 2)
66
73
  @@sd_units ||= %W(#{''} k M G T P E Z)
67
74
  .map.with_index { |x, i| [x, 1000.**(i + 1)] }
68
75
  unit = @@sd_units.find { |x| n < x[1] } || [?Y.freeze, 10 ** 27]
69
76
 
70
77
  converted = n.fdiv(unit[1] / 1000).round(2)
71
- "#{pad_left(converted)} #{unit[0]}B"
78
+ "#{pad_left(converted, precision)} #{unit[0]}B"
72
79
  end
73
80
 
74
81
  ##
@@ -87,15 +94,15 @@ module LinuxStat
87
94
  # LinuxStat::PrettifyBytes.convert_short_binary(1024 ** 3)
88
95
  #
89
96
  # => "1.0 GiB"
90
- def convert_short_binary(n)
91
- return "#{n} B" if n < 1024
97
+ def convert_short_binary(n, precision: 2)
98
+ return "#{pad_left(n, precision)} B" if n < 1024
92
99
 
93
100
  @@sb_units ||= %W(#{''} K M G T P E Z)
94
101
  .map.with_index { |x, i| [x, 1024.**(i + 1)] }
95
102
  unit = @@sb_units.find { |x| n < x[1] } || [?Y.freeze, 1024 ** 9]
96
103
 
97
104
  converted = n.fdiv(unit[1] / 1024).round(2)
98
- "#{pad_left(converted)} #{unit[0]}iB"
105
+ "#{pad_left(converted, precision)} #{unit[0]}iB"
99
106
  end
100
107
 
101
108
  private
@@ -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
  ##
@@ -28,7 +31,8 @@ module LinuxStat
28
31
  end
29
32
 
30
33
  ##
31
- # Returns all the id of processes mapped with their names as a Hash.
34
+ # Returns all the id of processes mapped with their executable names (comm) as a Hash.
35
+ # The names can be truncated to TASK_COMM_LEN or (16 - 1 = 15) places.
32
36
  def names
33
37
  h, i = {}, -1
34
38
 
@@ -39,7 +43,30 @@ module LinuxStat
39
43
  x = l[i]
40
44
 
41
45
  begin
42
- h.merge!( x => IO.foreach("/proc/#{x}/status").first.split[1])
46
+ h.merge!( x => IO.read("/proc/#{x}/comm").strip)
47
+ rescue StandardError
48
+ end
49
+ end
50
+ h
51
+ end
52
+
53
+ ##
54
+ # Returns all the id of processes mapped with their cmdline info as a Hash.
55
+ # The cmdlines aren't usually truncated like names, but they can contain
56
+ # arguments with the command.
57
+ def cmdlines
58
+ h, i = {}, -1
59
+
60
+ l = list
61
+ count = l.length
62
+
63
+ while(i += 1) < count
64
+ x = l[i]
65
+
66
+ begin
67
+ cmdlines = IO.read("/proc/#{x}/cmdline").strip
68
+ cmdlines.gsub!(?\u0000.freeze, ?\s.freeze)
69
+ h.merge!( x => cmdlines)
43
70
  rescue StandardError
44
71
  end
45
72
  end
@@ -59,11 +86,15 @@ module LinuxStat
59
86
 
60
87
  begin
61
88
  h.merge!(x =>
62
- case IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0]
89
+ case IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip
63
90
  when ?S.freeze then :sleeping
64
91
  when ?I.freeze then :idle
65
92
  when ?Z.freeze then :zombie
66
93
  when ?R.freeze then :running
94
+ when ?T.freeze then :stopped
95
+ when ?X.freeze then :dead
96
+ when ?D.freeze then :sleeping
97
+ when ?t.freeze then :stopped
67
98
  else :unknown
68
99
  end
69
100
  )
@@ -80,9 +111,9 @@ module LinuxStat
80
111
  def sleeping
81
112
  list.select { |x|
82
113
  begin
83
- IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?S.freeze
114
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?S.freeze
84
115
  rescue StandardError
85
- nil
116
+ false
86
117
  end
87
118
  }
88
119
  end
@@ -93,9 +124,9 @@ module LinuxStat
93
124
  def idle
94
125
  list.select { |x|
95
126
  begin
96
- IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?I.freeze
127
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?I.freeze
97
128
  rescue StandardError
98
- nil
129
+ false
99
130
  end
100
131
  }
101
132
  end
@@ -106,9 +137,9 @@ module LinuxStat
106
137
  def zombie
107
138
  list.select { |x|
108
139
  begin
109
- IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?Z.freeze
140
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?Z.freeze
110
141
  rescue StandardError
111
- nil
142
+ false
112
143
  end
113
144
  }
114
145
  end
@@ -119,9 +150,23 @@ module LinuxStat
119
150
  def running
120
151
  list.select { |x|
121
152
  begin
122
- IO.foreach("/proc/#{x}/stat", ' '.freeze).first(3)[-1][0] == ?R.freeze
153
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?R.freeze
154
+ rescue StandardError
155
+ false
156
+ end
157
+ }
158
+ end
159
+
160
+ ##
161
+ # Returns all the id of processes that are stopped.
162
+ # The return type is an Array of Integers.
163
+ def stopped
164
+ list.select { |x|
165
+ begin
166
+ v = IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip
167
+ v == ?T.freeze || v == ?t.freeze
123
168
  rescue StandardError
124
- nil
169
+ false
125
170
  end
126
171
  }
127
172
  end
@@ -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
  ##
@@ -62,6 +69,8 @@ module LinuxStat
62
69
 
63
70
  ##
64
71
  # = command_name(pid = $$)
72
+ # Not to be confused with process_name
73
+ # It just splits the cmdline to show the command name
65
74
  #
66
75
  # Where pid is the process ID.
67
76
  #
@@ -77,12 +86,40 @@ module LinuxStat
77
86
  # If the info isn't available it will return an empty frozen String.
78
87
  def command_name(pid = $$)
79
88
  # Do note that the /proc/ppid/comm may not contain the full name
80
- file = "/proc/#{pid}/cmdline".freeze
81
- return ''.freeze unless File.readable?(file)
89
+ # It's limited by TASK_COMM_LEN (16) characters
90
+ c = cmdline(pid).split[0]
91
+ return ''.freeze unless c
92
+ File.split(c)[-1]
93
+ end
82
94
 
83
- _cmdline = IO.read(file)
84
- _cmdline.gsub!(?\u0000, ?\s)
85
- File.split(_cmdline.tap(&:strip!).split[0])[-1]
95
+ ##
96
+ # = process_name(pid = $$)
97
+ # It shows the filename of the command
98
+ # Sometimes the filename is stripped
99
+ #
100
+ # Where pid is the process ID.
101
+ #
102
+ # By default it is the id of the current process ($$)
103
+ #
104
+ # It retuns the total command name of the process.
105
+ #
106
+ # The output is String. For example:
107
+ # LinuxStat::ProcessInfo.process_name
108
+ #
109
+ # "ruby"
110
+ #
111
+ # If the info isn't available it will return an empty frozen String.
112
+ def process_name(pid = $$)
113
+ file = "/proc/#{pid}/stat".freeze
114
+ return command_name unless File.readable?(file)
115
+
116
+ name = IO.read(file).split(/(\(.*\))/) &.[](1) &.[](1..-2)
117
+
118
+ if name && name.length > 0 && name.length < 15
119
+ name
120
+ else
121
+ command_name
122
+ end
86
123
  end
87
124
 
88
125
  ##
@@ -249,8 +286,11 @@ module LinuxStat
249
286
  ticks = get_ticks
250
287
 
251
288
  return {} unless File.readable?(file)
252
- utime, stime, starttime = IO.read(file)
253
- .split.values_at(13, 14, 21).map(&:to_f)
289
+
290
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
291
+ return {} unless stat
292
+
293
+ utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
254
294
 
255
295
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
256
296
 
@@ -260,9 +300,12 @@ module LinuxStat
260
300
  sleep(sleep)
261
301
 
262
302
  return {} unless File.readable?(file)
263
- stat = IO.read(file).split
264
303
 
265
- utime2, stime2, starttime2 = stat.values_at(13, 14, 21).map(&:to_f)
304
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
305
+ return {} unless stat
306
+
307
+ utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
308
+
266
309
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
267
310
 
268
311
  total_time2 = utime2 + stime2
@@ -273,8 +316,8 @@ module LinuxStat
273
316
 
274
317
  {
275
318
  cpu_usage: cpu_u > 100 ? 100.0 : cpu_u.round(2),
276
- threads: stat[19].to_i,
277
- last_executed_cpu: stat[38].to_i
319
+ threads: stat[17].to_i,
320
+ last_executed_cpu: stat[36].to_i
278
321
  }
279
322
  end
280
323
 
@@ -309,8 +352,11 @@ module LinuxStat
309
352
  ticks = get_ticks
310
353
 
311
354
  return nil unless File.readable?(file)
312
- utime, stime, starttime = IO.read(file)
313
- .split.values_at(13, 14, 21).map(&:to_f)
355
+
356
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
357
+ return nil unless stat
358
+
359
+ utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
314
360
 
315
361
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
316
362
 
@@ -320,9 +366,11 @@ module LinuxStat
320
366
  sleep(sleep)
321
367
 
322
368
  return nil unless File.readable?(file)
323
- utime2, stime2, starttime2 = IO.read(file)
324
- .split.values_at(13, 14, 21).map(&:to_f)
325
369
 
370
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
371
+ return nil unless stat
372
+
373
+ utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
326
374
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
327
375
 
328
376
  total_time2 = utime2 + stime2
@@ -361,8 +409,11 @@ module LinuxStat
361
409
  ticks = get_ticks
362
410
 
363
411
  return nil unless File.readable?(file)
364
- utime, stime, starttime = IO.read(file)
365
- .split.values_at(13, 14, 21).map(&:to_f)
412
+
413
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
414
+ return nil unless stat
415
+
416
+ utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
366
417
 
367
418
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
368
419
 
@@ -372,8 +423,11 @@ module LinuxStat
372
423
  sleep(sleep)
373
424
 
374
425
  return nil unless File.readable?(file)
375
- utime2, stime2, starttime2 = IO.read(file)
376
- .split.values_at(13, 14, 21).map(&:to_f)
426
+
427
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
428
+ return nil unless stat
429
+
430
+ utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
377
431
 
378
432
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
379
433
 
@@ -409,7 +463,7 @@ module LinuxStat
409
463
  file = "/proc/#{pid}/stat".freeze
410
464
  return nil unless File.readable?(file)
411
465
 
412
- data = IO.foreach(file, ' '.freeze).first(20)[-1]
466
+ data = IO.read(file).split(/(\(.*\))/)[-1] &.split &.at(17)
413
467
  data ? data.to_i : nil
414
468
  end
415
469
 
@@ -434,7 +488,8 @@ module LinuxStat
434
488
  file = "/proc/#{pid}/stat".freeze
435
489
  return nil unless File.readable?(file)
436
490
 
437
- IO.read(file).split[38].to_i
491
+ data = IO.read(file).split(/(\(.*\))/)[-1] &.split &.at(36)
492
+ data ? data.to_i : nil
438
493
  end
439
494
 
440
495
  ##
@@ -517,8 +572,11 @@ module LinuxStat
517
572
  @@u_readable ||= File.readable?(uptime)
518
573
  return nil unless @@u_readable && File.readable?(stat_file)
519
574
 
575
+ stat = IO.read(stat_file).split(/(\(.*\))/)[-1] &.split
576
+ return nil unless stat
577
+
520
578
  u = IO.foreach(uptime, ' '.freeze).next.to_f
521
- st = (IO.foreach(stat_file, ' '.freeze).first(22)[-1].to_f / get_ticks)
579
+ st = stat[19].to_f / get_ticks
522
580
 
523
581
  # Getting two Time objects and dealing with floating point numbers
524
582
  # Just to make sure the time goes monotonically
@@ -567,8 +625,11 @@ module LinuxStat
567
625
  @@u_readable ||= File.readable?(uptime)
568
626
  return nil unless @@u_readable && File.readable?(stat_file)
569
627
 
628
+ stat = IO.read(stat_file).split(/(\(.*\))/)[-1] &.split
629
+ return nil unless stat
630
+
570
631
  IO.foreach(uptime, ' '.freeze).next.to_f
571
- .-(IO.read(stat_file).split[21].to_f / get_ticks).round(2)
632
+ .-(stat[19].to_f / get_ticks).round(2)
572
633
  end
573
634
 
574
635
  ##
@@ -592,7 +653,11 @@ module LinuxStat
592
653
  def state(pid = $$)
593
654
  file = "/proc/#{pid}/stat".freeze
594
655
  return ''.freeze unless File.readable?(file)
595
- IO.foreach(file, ' '.freeze).first(3)[-1].tap(&:rstrip!).freeze
656
+
657
+ stat = IO.read(file).split(/(\(.*\))/)[-1]
658
+ return '' unless stat
659
+
660
+ stat[/\s.+?/].strip
596
661
  end
597
662
 
598
663
  ##
@@ -608,7 +673,10 @@ module LinuxStat
608
673
  file = "/proc/#{pid}/stat"
609
674
  return nil unless File.readable?(file)
610
675
 
611
- IO.foreach(file, ' ').first(19)[-1].to_i
676
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
677
+ return nil unless stat
678
+
679
+ stat[16].to_i
612
680
  end
613
681
 
614
682
  ##