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.
- checksums.yaml +4 -4
- data/README.md +206 -106
- data/bin/console +7 -1
- data/exe/linuxstat.rb +8 -1
- data/ext/fs_stat/fs_stat.c +10 -10
- data/ext/nproc/nproc.c +2 -2
- data/ext/procfs/extconf.rb +11 -0
- data/ext/procfs/loadavg_pid.h +11 -0
- data/ext/procfs/procfs.c +42 -0
- data/ext/procfs/stat.h +92 -0
- data/ext/procfs/statm.h +99 -0
- data/ext/procfs/uptime.h +12 -0
- data/ext/sysconf/extconf.rb +1 -1
- data/ext/sysconf/sysconf.c +27 -27
- data/ext/sysinfo/extconf.rb +11 -0
- data/ext/sysinfo/sysinfo.c +177 -0
- data/ext/utsname/utsname.c +1 -1
- data/lib/linux_stat.rb +10 -4
- data/lib/linux_stat/memory.rb +13 -3
- data/lib/linux_stat/net.rb +5 -5
- data/lib/linux_stat/os.rb +56 -9
- data/lib/linux_stat/process.rb +55 -23
- data/lib/linux_stat/process_info.rb +106 -99
- data/lib/linux_stat/swap.rb +36 -9
- data/lib/linux_stat/version.rb +1 -1
- metadata +13 -3
@@ -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
|
-
|
88
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
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
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
206
|
-
|
214
|
+
LinuxStat::ProcFS.statm_resident(pid) &.fdiv(1000)
|
215
|
+
end
|
207
216
|
|
208
|
-
|
209
|
-
|
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
|
-
|
259
|
-
|
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
|
-
|
270
|
-
|
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(
|
273
|
-
uptime
|
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[
|
284
|
-
last_executed_cpu: stat[
|
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
|
-
|
319
|
-
|
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
|
-
|
330
|
-
|
331
|
-
|
354
|
+
stat = LinuxStat::ProcFS.ps_stat(pid)
|
355
|
+
uptime = LS::ProcFS.uptime_f
|
356
|
+
return nil unless uptime && !stat.empty?
|
332
357
|
|
333
|
-
|
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
|
-
|
371
|
-
|
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
|
-
|
382
|
-
|
383
|
-
|
406
|
+
stat = LinuxStat::ProcFS.ps_stat(pid)
|
407
|
+
uptime = LS::ProcFS.uptime_f
|
408
|
+
return nil unless uptime && !stat.empty?
|
384
409
|
|
385
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
522
|
-
|
540
|
+
uptime = LS::ProcFS.uptime_f
|
541
|
+
stat = LinuxStat::ProcFS.ps_stat(pid)[18]
|
523
542
|
|
524
|
-
|
525
|
-
|
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.-(
|
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
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
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
|
-
|
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
|
-
|
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
|
##
|
data/lib/linux_stat/swap.rb
CHANGED
@@ -35,7 +35,10 @@ module LinuxStat
|
|
35
35
|
return {} unless swaps_readable?
|
36
36
|
values_t = read_usage
|
37
37
|
|
38
|
-
|
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
|
-
|
61
|
-
|
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
|
-
|
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].
|
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
|
-
|
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
|
-
|
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
|
-
|
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.-(
|
139
|
+
total.-(used).*(100).fdiv(total).round(2)
|
113
140
|
end
|
114
141
|
|
115
142
|
private
|
data/lib/linux_stat/version.rb
CHANGED
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:
|
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-
|
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.
|
81
|
+
version: 2.3.0
|
72
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
83
|
requirements:
|
74
84
|
- - ">="
|