linux_stat 1.3.1 → 2.0.1

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.
@@ -69,6 +69,8 @@ module LinuxStat
69
69
 
70
70
  ##
71
71
  # = command_name(pid = $$)
72
+ # Not to be confused with process_name
73
+ # It just splits the cmdline to show the command name
72
74
  #
73
75
  # Where pid is the process ID.
74
76
  #
@@ -84,12 +86,40 @@ module LinuxStat
84
86
  # If the info isn't available it will return an empty frozen String.
85
87
  def command_name(pid = $$)
86
88
  # Do note that the /proc/ppid/comm may not contain the full name
87
- file = "/proc/#{pid}/cmdline".freeze
88
- 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
89
94
 
90
- _cmdline = IO.read(file)
91
- _cmdline.gsub!(?\u0000, ?\s)
92
- 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
93
123
  end
94
124
 
95
125
  ##
@@ -119,20 +149,7 @@ module LinuxStat
119
149
  #
120
150
  # If the info isn't available it will return an empty Hash.
121
151
  def mem_stat(pid = $$)
122
- statm = "/proc/#{pid}/statm".freeze
123
- return {} unless File.readable?(statm)
124
-
125
- data = IO.read(statm).split
126
-
127
- _rss_anon = (data[1] && data[2]) ? data[1].to_i.-(data[2].to_i).*(pagesize).fdiv(1000) : nil
128
- _virtual_memory = data[0] ? data[0].to_i*(pagesize).fdiv(1000) : nil
129
- _resident_memory = data[1] ? data[1].to_i.*(pagesize).fdiv(1000) : nil
130
-
131
- {
132
- memory: _rss_anon,
133
- virtual_memory: _virtual_memory,
134
- resident_memory: _resident_memory
135
- }
152
+ LinuxStat::ProcFS.statm(pid)
136
153
  end
137
154
 
138
155
  ##
@@ -152,11 +169,7 @@ module LinuxStat
152
169
  #
153
170
  # If the info isn't available it will return nil.
154
171
  def memory(pid = $$)
155
- file = "/proc/#{pid}/statm".freeze
156
- return nil unless File.readable?(file)
157
-
158
- data = IO.read(file).split
159
- (data[1] && data[2]) ? data[1].to_i.-(data[2].to_i).*(pagesize).fdiv(1000) : nil
172
+ LinuxStat::ProcFS.statm_memory(pid) &.fdiv(1000)
160
173
  end
161
174
 
162
175
  ##
@@ -177,11 +190,7 @@ module LinuxStat
177
190
  #
178
191
  # If the info isn't available it will return nil.
179
192
  def virtual_memory(pid = $$)
180
- file = "/proc/#{pid}/statm".freeze
181
- return nil unless File.readable?(file)
182
-
183
- _virtual_memory = IO.read(file).split[0]
184
- _virtual_memory ? _virtual_memory.to_i.*(pagesize).fdiv(1000) : nil
193
+ LinuxStat::ProcFS.statm_virtual(pid) &.fdiv(1000)
185
194
  end
186
195
 
187
196
  ##
@@ -196,17 +205,34 @@ module LinuxStat
196
205
  # The value is in kilobytes.
197
206
  #
198
207
  # The output is an Integer. For example:
199
- # LinuxStat::ProcessInfo.cpu_stat
208
+ # LinuxStat::ProcessInfo.resident_memory
200
209
  #
201
210
  # => 13996.032
202
211
  #
203
212
  # If the info isn't available it will return nil.
204
213
  def resident_memory(pid = $$)
205
- file = "/proc/#{pid}/statm".freeze
206
- return nil unless File.readable?(file)
214
+ LinuxStat::ProcFS.statm_resident(pid) &.fdiv(1000)
215
+ end
207
216
 
208
- _vm_rss = IO.read(file).split[1]
209
- _vm_rss ? _vm_rss.to_i.*(pagesize).fdiv(1000) : nil
217
+ ##
218
+ # = shared_memory(pid = $$)
219
+ #
220
+ # Where pid is the process ID.
221
+ #
222
+ # By default it is the id of the current process ($$)
223
+ #
224
+ # It retuns the shared memory for the process.
225
+ #
226
+ # The value is in kilobytes.
227
+ #
228
+ # The output is an Integer. For example:
229
+ # LinuxStat::ProcessInfo.shared_memory
230
+ #
231
+ # => 13996.032
232
+ #
233
+ # If the info isn't available it will return nil.
234
+ def shared_memory(pid = $$)
235
+ LinuxStat::ProcFS.statm_shared(pid) &.fdiv(1000)
210
236
  end
211
237
 
212
238
  ##
@@ -252,25 +278,25 @@ module LinuxStat
252
278
  #
253
279
  # The :last_executed_cpu also returns an Integer indicating the last executed cpu of the process.
254
280
  def cpu_stat(pid: $$, sleep: ticks_to_ms_t5)
255
- file = "/proc/#{pid}/stat"
256
281
  ticks = get_ticks
282
+ stat = LinuxStat::ProcFS.ps_stat(pid)
283
+ uptime = LS::ProcFS.uptime_f
284
+ return {} unless uptime && !stat.empty?
257
285
 
258
- return {} unless File.readable?(file)
259
- utime, stime, starttime = IO.read(file)
260
- .split.values_at(13, 14, 21).map(&:to_f)
261
-
262
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
286
+ utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
287
+ uptime *= ticks
263
288
 
264
289
  total_time = utime + stime
265
290
  idle1 = uptime - starttime - total_time
266
291
 
267
292
  sleep(sleep)
268
293
 
269
- return {} unless File.readable?(file)
270
- stat = IO.read(file).split
294
+ stat = LinuxStat::ProcFS.ps_stat(pid)
295
+ uptime = LS::ProcFS.uptime_f
296
+ return {} unless uptime && !stat.empty?
271
297
 
272
- utime2, stime2, starttime2 = stat.values_at(13, 14, 21).map(&:to_f)
273
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
298
+ utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
299
+ uptime *= ticks
274
300
 
275
301
  total_time2 = utime2 + stime2
276
302
  idle2 = uptime - starttime2 - total_time2
@@ -280,8 +306,8 @@ module LinuxStat
280
306
 
281
307
  {
282
308
  cpu_usage: cpu_u > 100 ? 100.0 : cpu_u.round(2),
283
- threads: stat[19].to_i,
284
- last_executed_cpu: stat[38].to_i
309
+ threads: stat[17].to_i,
310
+ last_executed_cpu: stat[36].to_i
285
311
  }
286
312
  end
287
313
 
@@ -312,25 +338,25 @@ module LinuxStat
312
338
  #
313
339
  # This method is more efficient than running LinuxStat::ProcessInfo.cpu_stat()
314
340
  def cpu_usage(pid: $$, sleep: ticks_to_ms_t5)
315
- file = "/proc/#{pid}/stat"
316
341
  ticks = get_ticks
342
+ stat = LinuxStat::ProcFS.ps_stat(pid)
343
+ uptime = LS::ProcFS.uptime_f
344
+ return nil unless uptime && !stat.empty?
317
345
 
318
- return nil unless File.readable?(file)
319
- utime, stime, starttime = IO.read(file)
320
- .split.values_at(13, 14, 21).map(&:to_f)
321
-
322
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
346
+ utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
347
+ uptime *= ticks
323
348
 
324
349
  total_time = utime + stime
325
350
  idle1 = uptime - starttime - total_time
326
351
 
327
352
  sleep(sleep)
328
353
 
329
- return nil unless File.readable?(file)
330
- utime2, stime2, starttime2 = IO.read(file)
331
- .split.values_at(13, 14, 21).map(&:to_f)
354
+ stat = LinuxStat::ProcFS.ps_stat(pid)
355
+ uptime = LS::ProcFS.uptime_f
356
+ return nil unless uptime && !stat.empty?
332
357
 
333
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
358
+ utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
359
+ uptime *= ticks
334
360
 
335
361
  total_time2 = utime2 + stime2
336
362
  idle2 = uptime - starttime2 - total_time2
@@ -364,25 +390,25 @@ module LinuxStat
364
390
  #
365
391
  # But if the info isn't available, it will return nil.
366
392
  def thread_usage(pid: $$, sleep: ticks_to_ms_t5)
367
- file = "/proc/#{pid}/stat"
368
393
  ticks = get_ticks
394
+ stat = LinuxStat::ProcFS.ps_stat(pid)
395
+ uptime = LS::ProcFS.uptime_f
396
+ return nil unless uptime && !stat.empty?
369
397
 
370
- return nil unless File.readable?(file)
371
- utime, stime, starttime = IO.read(file)
372
- .split.values_at(13, 14, 21).map(&:to_f)
373
-
374
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
398
+ utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
399
+ uptime *= ticks
375
400
 
376
401
  total_time = utime + stime
377
402
  idle1 = uptime - starttime - total_time
378
403
 
379
404
  sleep(sleep)
380
405
 
381
- return nil unless File.readable?(file)
382
- utime2, stime2, starttime2 = IO.read(file)
383
- .split.values_at(13, 14, 21).map(&:to_f)
406
+ stat = LinuxStat::ProcFS.ps_stat(pid)
407
+ uptime = LS::ProcFS.uptime_f
408
+ return nil unless uptime && !stat.empty?
384
409
 
385
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
410
+ utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
411
+ uptime *= ticks
386
412
 
387
413
  total_time2 = utime2 + stime2
388
414
  idle2 = uptime - starttime2 - total_time2
@@ -413,11 +439,7 @@ module LinuxStat
413
439
  #
414
440
  # This method is way more efficient than running LinuxStat::ProcessInfo.cpu_stat()
415
441
  def threads(pid = $$)
416
- file = "/proc/#{pid}/stat".freeze
417
- return nil unless File.readable?(file)
418
-
419
- data = IO.foreach(file, ' '.freeze).first(20)[-1]
420
- data ? data.to_i : nil
442
+ LinuxStat::ProcFS.ps_stat(pid)[16]
421
443
  end
422
444
 
423
445
  ##
@@ -438,10 +460,7 @@ module LinuxStat
438
460
  #
439
461
  # This method is way more efficient than running LinuxStat::ProcessInfo.cpu_stat()
440
462
  def last_executed_cpu(pid = $$)
441
- file = "/proc/#{pid}/stat".freeze
442
- return nil unless File.readable?(file)
443
-
444
- IO.read(file).split[38].to_i
463
+ LinuxStat::ProcFS.ps_stat(pid)[35]
445
464
  end
446
465
 
447
466
  ##
@@ -518,18 +537,15 @@ module LinuxStat
518
537
  #
519
538
  # If the info isn't available or the argument passed doesn't exist as a process ID, it will return nil.
520
539
  def start_time_epoch(pid = $$)
521
- stat_file = "/proc/#{pid}/stat".freeze
522
- uptime = "/proc/uptime".freeze
540
+ uptime = LS::ProcFS.uptime_f
541
+ stat = LinuxStat::ProcFS.ps_stat(pid)[18]
523
542
 
524
- @@u_readable ||= File.readable?(uptime)
525
- return nil unless @@u_readable && File.readable?(stat_file)
526
-
527
- u = IO.foreach(uptime, ' '.freeze).next.to_f
528
- st = (IO.foreach(stat_file, ' '.freeze).first(22)[-1].to_f / get_ticks)
543
+ return nil unless uptime && stat
544
+ st = stat.to_f / get_ticks
529
545
 
530
546
  # Getting two Time objects and dealing with floating point numbers
531
- # Just to make sure the time goes monotonically
532
- Time.now.-(u - st).to_i
547
+ # Just to make sure the time goes monotonically unless the clock changes
548
+ Time.now.-(uptime - st).to_i
533
549
  end
534
550
 
535
551
  ##
@@ -568,14 +584,10 @@ module LinuxStat
568
584
  #
569
585
  # If the info isn't available or the argument passed doesn't exist as a process ID, it will return nil.
570
586
  def running_time(pid = $$)
571
- stat_file = "/proc/#{pid}/stat".freeze
572
- uptime = "/proc/uptime".freeze
573
-
574
- @@u_readable ||= File.readable?(uptime)
575
- return nil unless @@u_readable && File.readable?(stat_file)
576
-
577
- IO.foreach(uptime, ' '.freeze).next.to_f
578
- .-(IO.read(stat_file).split[21].to_f / get_ticks).round(2)
587
+ uptime = LS::ProcFS.uptime_f
588
+ stat = LinuxStat::ProcFS.ps_stat(pid)[18]
589
+ return nil unless uptime && stat
590
+ uptime.-(stat.to_f / get_ticks).round(2)
579
591
  end
580
592
 
581
593
  ##
@@ -597,9 +609,7 @@ module LinuxStat
597
609
  # If the info isn't available or the argument passed doesn't exist as a process ID,
598
610
  # it will return an empty String.
599
611
  def state(pid = $$)
600
- file = "/proc/#{pid}/stat".freeze
601
- return ''.freeze unless File.readable?(file)
602
- IO.foreach(file, ' '.freeze).first(3)[-1].tap(&:rstrip!).freeze
612
+ LinuxStat::ProcFS.ps_state(pid)
603
613
  end
604
614
 
605
615
  ##
@@ -612,10 +622,7 @@ module LinuxStat
612
622
  #
613
623
  # If the info isn't available or the argument passed doesn't exist as a process ID, it will return nil.
614
624
  def nice(pid = $$)
615
- file = "/proc/#{pid}/stat"
616
- return nil unless File.readable?(file)
617
-
618
- IO.foreach(file, ' ').first(19)[-1].to_i
625
+ LinuxStat::ProcFS.ps_stat(pid)[15]
619
626
  end
620
627
 
621
628
  ##
@@ -35,7 +35,10 @@ module LinuxStat
35
35
  return {} unless swaps_readable?
36
36
  values_t = read_usage
37
37
 
38
- total, used = values_t[0].sum, values_t[-1].sum
38
+ _total, _used = values_t[0], values_t[-1]
39
+ return {} if _total.empty? || _used.empty?
40
+
41
+ total, used = _total.reduce(:+), _used.reduce(:+)
39
42
  available = total - used
40
43
  percent_used = total == 0 ? 0.0 : used.*(100).fdiv(total).round(2)
41
44
  percent_available = total == 0.0 ? 0 : available.*(100).fdiv(total).round(2)
@@ -57,8 +60,19 @@ module LinuxStat
57
60
  #
58
61
  # The return type is a Integer but if the info isn't available, it will return nil.
59
62
  def total
60
- return nil unless swaps_readable?
61
- read_usage[0].sum
63
+ v = LinuxStat::Sysinfo.totalswap
64
+ v ? v.fdiv(1024).to_i : nil
65
+ end
66
+
67
+ ##
68
+ # Shows free swap.
69
+ #
70
+ # The value is in kilobytes.
71
+ #
72
+ # The return type is a Integer but if the info isn't available, it will return nil.
73
+ def free
74
+ v = LinuxStat::Sysinfo.freeswap
75
+ v ? v.fdiv(1024).to_i : nil
62
76
  end
63
77
 
64
78
  ##
@@ -70,7 +84,9 @@ module LinuxStat
70
84
  def available
71
85
  return nil unless swaps_readable?
72
86
  values_t = read_usage
73
- values_t[0].sum - values_t[1].sum
87
+ t = values_t[0].reduce(:+)
88
+ u = values_t[1].reduce(:+)
89
+ (t && u) ? t - u : nil
74
90
  end
75
91
 
76
92
  ##
@@ -81,7 +97,7 @@ module LinuxStat
81
97
  # The return type is a Integer but if the info isn't available, it will return nil.
82
98
  def used
83
99
  return nil unless swaps_readable?
84
- read_usage[-1].sum
100
+ read_usage[-1].reduce(:+)
85
101
  end
86
102
 
87
103
  ##
@@ -92,10 +108,16 @@ module LinuxStat
92
108
  return nil unless swaps_readable?
93
109
  values_t = read_usage
94
110
 
95
- total = values_t[0].sum
111
+ _total = values_t[0]
112
+ _used = values_t[-1]
113
+ return nil if _total.empty? || _used.empty?
114
+
115
+ total = _total.reduce(:+)
116
+ used = _used.reduce(:+)
117
+
96
118
  return 0.0 if total == 0
97
119
 
98
- values_t[-1].sum.*(100).fdiv(total).round(2)
120
+ used.*(100).fdiv(total).round(2)
99
121
  end
100
122
 
101
123
  ##
@@ -106,10 +128,15 @@ module LinuxStat
106
128
  return nil unless swaps_readable?
107
129
  values_t = read_usage
108
130
 
109
- total = values_t[0].sum
131
+ _total = values_t[0]
132
+ _used = values_t[-1]
133
+ return nil if _total.empty? || _used.empty?
134
+
135
+ total, used = _total.reduce(:+), _used.reduce(:+)
136
+
110
137
  return 0.0 if total == 0
111
138
 
112
- total.-(values_t[-1].sum).*(100).fdiv(total).round(2)
139
+ total.-(used).*(100).fdiv(total).round(2)
113
140
  end
114
141
 
115
142
  private
@@ -1,3 +1,3 @@
1
1
  module LinuxStat
2
- VERSION ||= "1.3.1"
2
+ VERSION ||= "2.0.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linux_stat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sourav Goswami
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-14 00:00:00.000000000 Z
11
+ date: 2021-02-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Linux only, efficient linux system utilization reporting and system monitoring
14
14
  gem
@@ -20,7 +20,9 @@ extensions:
20
20
  - ext/fs_stat/extconf.rb
21
21
  - ext/nproc/extconf.rb
22
22
  - ext/sysconf/extconf.rb
23
+ - ext/sysinfo/extconf.rb
23
24
  - ext/utsname/extconf.rb
25
+ - ext/procfs/extconf.rb
24
26
  extra_rdoc_files:
25
27
  - README.md
26
28
  files:
@@ -33,8 +35,16 @@ files:
33
35
  - ext/fs_stat/fs_stat.c
34
36
  - ext/nproc/extconf.rb
35
37
  - ext/nproc/nproc.c
38
+ - ext/procfs/extconf.rb
39
+ - ext/procfs/loadavg_pid.h
40
+ - ext/procfs/procfs.c
41
+ - ext/procfs/stat.h
42
+ - ext/procfs/statm.h
43
+ - ext/procfs/uptime.h
36
44
  - ext/sysconf/extconf.rb
37
45
  - ext/sysconf/sysconf.c
46
+ - ext/sysinfo/extconf.rb
47
+ - ext/sysinfo/sysinfo.c
38
48
  - ext/utsname/extconf.rb
39
49
  - ext/utsname/utsname.c
40
50
  - lib/linux_stat.rb
@@ -68,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
78
  requirements:
69
79
  - - ">="
70
80
  - !ruby/object:Gem::Version
71
- version: 2.5.0
81
+ version: 2.3.0
72
82
  required_rubygems_version: !ruby/object:Gem::Requirement
73
83
  requirements:
74
84
  - - ">="