linux_stat 2.0.1 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +54 -1042
- data/exe/linuxstat.rb +2 -2
- data/ext/procfs/procfs.c +1 -0
- data/ext/procfs/stat.h +29 -2
- data/ext/procfs/statm.h +25 -15
- data/lib/linux_stat/battery.rb +40 -7
- data/lib/linux_stat/os.rb +11 -5
- data/lib/linux_stat/process_info.rb +77 -57
- data/lib/linux_stat/version.rb +1 -1
- metadata +4 -4
data/exe/linuxstat.rb
CHANGED
@@ -150,9 +150,9 @@ execute.sort.each do |c|
|
|
150
150
|
disp_meth = "#{meth}"
|
151
151
|
disp_meth.concat(arg ? "(#{param})" : "(#{param})")
|
152
152
|
|
153
|
-
time =
|
153
|
+
time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
154
154
|
ret = arg ? e.send(meth, arg) : e.send(meth)
|
155
|
-
time2 =
|
155
|
+
time2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
156
156
|
time = time2.-(time).*(1_000_000).round(3)
|
157
157
|
|
158
158
|
v = ret.inspect
|
data/ext/procfs/procfs.c
CHANGED
data/ext/procfs/stat.h
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
VALUE ps_state(VALUE obj, VALUE pid) {
|
2
|
+
int _pid = FIX2INT(pid) ;
|
3
|
+
if (_pid < 0) return rb_str_new_cstr("") ;
|
4
|
+
|
2
5
|
char _path[22] ;
|
3
|
-
sprintf(_path, "/proc/%
|
6
|
+
sprintf(_path, "/proc/%d/stat", _pid) ;
|
4
7
|
|
5
8
|
FILE *f = fopen(_path, "r") ;
|
6
9
|
if (!f) return rb_str_new_cstr("") ;
|
@@ -14,9 +17,33 @@ VALUE ps_state(VALUE obj, VALUE pid) {
|
|
14
17
|
return rb_str_new_cstr(_s) ;
|
15
18
|
}
|
16
19
|
|
20
|
+
VALUE ps_times(VALUE obj, VALUE pid) {
|
21
|
+
int _pid = FIX2INT(pid) ;
|
22
|
+
if (_pid < 0) return Qnil ;
|
23
|
+
|
24
|
+
char _path[22] ;
|
25
|
+
sprintf(_path, "/proc/%d/stat", _pid) ;
|
26
|
+
|
27
|
+
FILE *f = fopen(_path, "r") ;
|
28
|
+
if (!f) return Qnil ;
|
29
|
+
|
30
|
+
unsigned long utime, stime ;
|
31
|
+
|
32
|
+
char status = fscanf(f, "%*llu (%*[^)]%*[)] %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %lu %lu", &utime, &stime) ;
|
33
|
+
fclose(f) ;
|
34
|
+
|
35
|
+
if (status != 2) return Qnil ;
|
36
|
+
double total_time = (utime + stime) / (float)sysconf(_SC_CLK_TCK);
|
37
|
+
|
38
|
+
return DBL2NUM(total_time) ;
|
39
|
+
}
|
40
|
+
|
17
41
|
VALUE ps_stat(VALUE obj, VALUE pid) {
|
42
|
+
int _pid = FIX2INT(pid) ;
|
43
|
+
if (_pid < 0) return rb_str_new_cstr("") ;
|
44
|
+
|
18
45
|
char _path[22] ;
|
19
|
-
sprintf(_path, "/proc/%
|
46
|
+
sprintf(_path, "/proc/%d/stat", _pid) ;
|
20
47
|
|
21
48
|
FILE *f = fopen(_path, "r") ;
|
22
49
|
|
data/ext/procfs/statm.h
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
#define PAGESIZE sysconf(_SC_PAGESIZE)
|
2
2
|
|
3
3
|
VALUE statm(VALUE obj, VALUE pid) {
|
4
|
-
|
5
|
-
sprintf(_path, "/proc/%lu/statm", FIX2UINT(pid)) ;
|
4
|
+
VALUE hash = rb_hash_new() ;
|
6
5
|
|
7
|
-
|
6
|
+
int _pid = FIX2INT(pid) ;
|
7
|
+
if (_pid < 0) return hash ;
|
8
8
|
|
9
|
-
|
9
|
+
char _path[22] ;
|
10
|
+
sprintf(_path, "/proc/%d/statm", _pid) ;
|
10
11
|
|
12
|
+
FILE *f = fopen(_path, "r") ;
|
11
13
|
if (!f) return hash ;
|
12
14
|
|
13
15
|
unsigned int _virtual, resident, shared ;
|
@@ -33,13 +35,15 @@ VALUE statm(VALUE obj, VALUE pid) {
|
|
33
35
|
}
|
34
36
|
|
35
37
|
VALUE statm_virtual(VALUE obj, VALUE pid) {
|
38
|
+
int _pid = FIX2INT(pid) ;
|
39
|
+
if (_pid < 0) return Qnil ;
|
40
|
+
|
36
41
|
char _path[22] ;
|
37
|
-
sprintf(_path, "/proc/%
|
42
|
+
sprintf(_path, "/proc/%d/statm", _pid) ;
|
38
43
|
|
39
44
|
FILE *f = fopen(_path, "r") ;
|
40
|
-
|
45
|
+
if (!f) return Qnil ;
|
41
46
|
|
42
|
-
if (!f) return hash ;
|
43
47
|
unsigned int _virtual ;
|
44
48
|
char status = fscanf(f, "%u", &_virtual) ;
|
45
49
|
fclose(f) ;
|
@@ -49,13 +53,15 @@ VALUE statm_virtual(VALUE obj, VALUE pid) {
|
|
49
53
|
}
|
50
54
|
|
51
55
|
VALUE statm_resident(VALUE obj, VALUE pid) {
|
56
|
+
int _pid = FIX2INT(pid) ;
|
57
|
+
if (_pid < 0) return Qnil ;
|
58
|
+
|
52
59
|
char _path[22] ;
|
53
|
-
sprintf(_path, "/proc/%
|
60
|
+
sprintf(_path, "/proc/%d/statm", _pid) ;
|
54
61
|
|
55
62
|
FILE *f = fopen(_path, "r") ;
|
56
|
-
|
63
|
+
if (!f) return Qnil ;
|
57
64
|
|
58
|
-
if (!f) return hash ;
|
59
65
|
unsigned int resident ;
|
60
66
|
char status = fscanf(f, "%*u %u", &resident) ;
|
61
67
|
fclose(f) ;
|
@@ -65,13 +71,15 @@ VALUE statm_resident(VALUE obj, VALUE pid) {
|
|
65
71
|
}
|
66
72
|
|
67
73
|
VALUE statm_shared(VALUE obj, VALUE pid) {
|
74
|
+
int _pid = FIX2INT(pid) ;
|
75
|
+
if (_pid < 0) return Qnil ;
|
76
|
+
|
68
77
|
char _path[22] ;
|
69
|
-
sprintf(_path, "/proc/%
|
78
|
+
sprintf(_path, "/proc/%d/statm", _pid) ;
|
70
79
|
|
71
80
|
FILE *f = fopen(_path, "r") ;
|
72
|
-
|
81
|
+
if (!f) return Qnil ;
|
73
82
|
|
74
|
-
if (!f) return hash ;
|
75
83
|
unsigned int shared ;
|
76
84
|
char status = fscanf(f, "%*u %*u %u", &shared) ;
|
77
85
|
fclose(f) ;
|
@@ -81,11 +89,13 @@ VALUE statm_shared(VALUE obj, VALUE pid) {
|
|
81
89
|
}
|
82
90
|
|
83
91
|
VALUE statm_memory(VALUE obj, VALUE pid) {
|
92
|
+
int _pid = FIX2INT(pid) ;
|
93
|
+
if (_pid < 0) return Qnil ;
|
94
|
+
|
84
95
|
char _path[22] ;
|
85
|
-
sprintf(_path, "/proc/%
|
96
|
+
sprintf(_path, "/proc/%d/statm", _pid) ;
|
86
97
|
|
87
98
|
FILE *f = fopen(_path, "r") ;
|
88
|
-
|
89
99
|
if (!f) return Qnil ;
|
90
100
|
|
91
101
|
unsigned int resident, shared ;
|
data/lib/linux_stat/battery.rb
CHANGED
@@ -105,11 +105,19 @@ module LinuxStat
|
|
105
105
|
#
|
106
106
|
# If the battery is not present or the information is not available, it will return nil.
|
107
107
|
def charge
|
108
|
-
@@charge_now_file ||= File.join(PATH, 'charge_now')
|
109
|
-
|
108
|
+
@@charge_now_file ||= if File.readable?(File.join(PATH, 'charge_now'))
|
109
|
+
File.join(PATH, 'charge_now').freeze
|
110
|
+
elsif File.readable?(File.join(PATH, 'energy_now'))
|
111
|
+
File.join(PATH, 'energy_now').freeze
|
112
|
+
end
|
113
|
+
|
114
|
+
@@charge_full_file ||= if File.readable?(File.join(PATH, 'charge_full'))
|
115
|
+
File.join(PATH, 'charge_full').freeze
|
116
|
+
elsif File.readable?(File.join(PATH, 'energy_full'))
|
117
|
+
File.join(PATH, 'energy_full').freeze
|
118
|
+
end
|
110
119
|
|
111
|
-
|
112
|
-
return nil unless @@charge_now_readable
|
120
|
+
return nil unless @@charge_now_file && @@charge_full_file
|
113
121
|
|
114
122
|
charge_now = IO.read(@@charge_now_file).to_i
|
115
123
|
charge_full = IO.read(@@charge_full_file).to_i
|
@@ -178,7 +186,14 @@ module LinuxStat
|
|
178
186
|
# For example, a sample output can be like this (taken on a test system):
|
179
187
|
#
|
180
188
|
# LinuxStat::Battery.devices_stat
|
181
|
-
# => {:AC=>{:type=>"Mains", :online=>1},
|
189
|
+
# => {:AC=>{:type=>"Mains", :online=>1},
|
190
|
+
# :BAT0=>{:model=>"DELL CYMGM77", :manufacturer=>"Samsung SDI",
|
191
|
+
# :type=>"Battery", :status=>"Full", :capacity=>100, :voltage_min_design=>11.4,
|
192
|
+
# :charge_full_design=>3.684, :charge_full_design_wh=>42.0,
|
193
|
+
# :voltage_now=>12.558, :charge_now=>2.087, :charge_now_wh=>26.21,
|
194
|
+
# :charge_full_wh=>23.79, :charge_percentage=>100.0},
|
195
|
+
# :hidpp_battery_0=>{:model=>"Wireless Keyboard", :manufacturer=>"Logitech",
|
196
|
+
# :type=>"Battery", :status=>"Discharging", :online=>1}}
|
182
197
|
#
|
183
198
|
# If you need info about lots of batteries, use this method.
|
184
199
|
# If the informations are not available, it will return empty Hash for each devices.
|
@@ -208,7 +223,16 @@ module LinuxStat
|
|
208
223
|
|
209
224
|
# charge now
|
210
225
|
cn_f = File.join(x, 'charge_now'.freeze).freeze
|
211
|
-
charge_now = File.readable?(cn_f)
|
226
|
+
charge_now = if File.readable?(cn_f)
|
227
|
+
IO.read(cn_f).to_i.fdiv(1_000_000)
|
228
|
+
else
|
229
|
+
en_f = File.join(x, 'energy_now'.freeze)
|
230
|
+
if File.readable?(en_f)
|
231
|
+
IO.read(en_f) .to_i.fdiv(1_000_000)
|
232
|
+
else
|
233
|
+
nil
|
234
|
+
end
|
235
|
+
end
|
212
236
|
|
213
237
|
# voltage min design
|
214
238
|
vmd_f = File.join(x, 'voltage_min_design'.freeze).freeze
|
@@ -220,7 +244,16 @@ module LinuxStat
|
|
220
244
|
|
221
245
|
# charge full
|
222
246
|
cf_f = File.join(x, 'charge_full'.freeze).freeze
|
223
|
-
charge_full = File.readable?(cf_f)
|
247
|
+
charge_full = if File.readable?(cf_f)
|
248
|
+
IO.read(cf_f).to_i.fdiv(1_000_000)
|
249
|
+
else
|
250
|
+
ef_f = File.join(x, 'energy_full'.freeze)
|
251
|
+
if File.readable?(ef_f)
|
252
|
+
IO.read(ef_f).to_i.fdiv(1_000_000)
|
253
|
+
else
|
254
|
+
nil
|
255
|
+
end
|
256
|
+
end
|
224
257
|
|
225
258
|
# status
|
226
259
|
s_f = File.join(x, 'status'.freeze).freeze
|
data/lib/linux_stat/os.rb
CHANGED
@@ -7,7 +7,11 @@ module LinuxStat
|
|
7
7
|
# Reads /etc/os-release and returns a Hash. For example:
|
8
8
|
# LinuxStat::OS.os_release
|
9
9
|
#
|
10
|
-
# => {:NAME=>"Arch Linux", :PRETTY_NAME=>"Arch Linux", :ID=>"arch", :BUILD_ID=>"rolling",
|
10
|
+
# => {:NAME=>"Arch Linux", :PRETTY_NAME=>"Arch Linux", :ID=>"arch", :BUILD_ID=>"rolling",
|
11
|
+
# :ANSI_COLOR=>"38;2;23;147;209", :HOME_URL=>"https://www.archlinux.org/",
|
12
|
+
# :DOCUMENTATION_URL=>"https://wiki.archlinux.org/",
|
13
|
+
# :SUPPORT_URL=>"https://bbs.archlinux.org/", :BUG_REPORT_URL=>"https://bugs.archlinux.org/",
|
14
|
+
# :LOGO=>"archlinux"}
|
11
15
|
#
|
12
16
|
# If the info isn't available, it will return an empty Hash.
|
13
17
|
#
|
@@ -127,7 +131,7 @@ module LinuxStat
|
|
127
131
|
#
|
128
132
|
# The return type is strictly Integer and doesn't fail.
|
129
133
|
def bits
|
130
|
-
@@bits ||= if
|
134
|
+
@@bits ||= if machine.end_with?('64') || RbConfig::CONFIG['host_cpu'].end_with?('64') || RUBY_PLATFORM.end_with?('64')
|
131
135
|
64
|
132
136
|
else
|
133
137
|
32
|
@@ -138,7 +142,7 @@ module LinuxStat
|
|
138
142
|
# Reads /proc/uptime and returns the system uptime:
|
139
143
|
# LinuxStat::OS.uptime
|
140
144
|
#
|
141
|
-
# => {:hour=>
|
145
|
+
# => {:hour=>16, :minute=>10, :second=>11, :jiffy=>20}
|
142
146
|
#
|
143
147
|
# Using uptime is 10x slower than using uptime_i
|
144
148
|
#
|
@@ -151,12 +155,14 @@ module LinuxStat
|
|
151
155
|
|
152
156
|
h = uptime_i / 3600
|
153
157
|
m = uptime_i % 3600 / 60
|
154
|
-
s =
|
158
|
+
s = uptime_i.%(60)
|
159
|
+
j = _uptime.-(uptime_i) * 100
|
155
160
|
|
156
161
|
{
|
157
162
|
hour: h,
|
158
163
|
minute: m,
|
159
|
-
second: s
|
164
|
+
second: s,
|
165
|
+
jiffy: j.to_i
|
160
166
|
}
|
161
167
|
end
|
162
168
|
|
@@ -283,7 +283,7 @@ module LinuxStat
|
|
283
283
|
uptime = LS::ProcFS.uptime_f
|
284
284
|
return {} unless uptime && !stat.empty?
|
285
285
|
|
286
|
-
utime, stime, starttime = *stat.values_at(
|
286
|
+
utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
|
287
287
|
uptime *= ticks
|
288
288
|
|
289
289
|
total_time = utime + stime
|
@@ -295,14 +295,14 @@ module LinuxStat
|
|
295
295
|
uptime = LS::ProcFS.uptime_f
|
296
296
|
return {} unless uptime && !stat.empty?
|
297
297
|
|
298
|
-
utime2, stime2, starttime2 = *stat.values_at(
|
298
|
+
utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
|
299
299
|
uptime *= ticks
|
300
300
|
|
301
301
|
total_time2 = utime2 + stime2
|
302
302
|
idle2 = uptime - starttime2 - total_time2
|
303
303
|
|
304
304
|
totald = idle2.+(total_time2).-(idle1 + total_time)
|
305
|
-
cpu_u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)./(
|
305
|
+
cpu_u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)./(LinuxStat::CPU.count)
|
306
306
|
|
307
307
|
{
|
308
308
|
cpu_usage: cpu_u > 100 ? 100.0 : cpu_u.round(2),
|
@@ -338,32 +338,10 @@ module LinuxStat
|
|
338
338
|
#
|
339
339
|
# This method is more efficient than running LinuxStat::ProcessInfo.cpu_stat()
|
340
340
|
def cpu_usage(pid: $$, sleep: ticks_to_ms_t5)
|
341
|
-
|
342
|
-
|
343
|
-
uptime = LS::ProcFS.uptime_f
|
344
|
-
return nil unless uptime && !stat.empty?
|
345
|
-
|
346
|
-
utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
|
347
|
-
uptime *= ticks
|
348
|
-
|
349
|
-
total_time = utime + stime
|
350
|
-
idle1 = uptime - starttime - total_time
|
351
|
-
|
352
|
-
sleep(sleep)
|
353
|
-
|
354
|
-
stat = LinuxStat::ProcFS.ps_stat(pid)
|
355
|
-
uptime = LS::ProcFS.uptime_f
|
356
|
-
return nil unless uptime && !stat.empty?
|
357
|
-
|
358
|
-
utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
|
359
|
-
uptime *= ticks
|
360
|
-
|
361
|
-
total_time2 = utime2 + stime2
|
362
|
-
idle2 = uptime - starttime2 - total_time2
|
341
|
+
u = cpu_usage_thread(pid, sleep)
|
342
|
+
return nil unless u
|
363
343
|
|
364
|
-
|
365
|
-
|
366
|
-
u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)./(cpu_count)
|
344
|
+
u /= LinuxStat::CPU.count
|
367
345
|
u > 100 ? 100.0 : u.round(2)
|
368
346
|
end
|
369
347
|
|
@@ -390,34 +368,10 @@ module LinuxStat
|
|
390
368
|
#
|
391
369
|
# But if the info isn't available, it will return nil.
|
392
370
|
def thread_usage(pid: $$, sleep: ticks_to_ms_t5)
|
393
|
-
|
394
|
-
|
395
|
-
uptime = LS::ProcFS.uptime_f
|
396
|
-
return nil unless uptime && !stat.empty?
|
397
|
-
|
398
|
-
utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
|
399
|
-
uptime *= ticks
|
400
|
-
|
401
|
-
total_time = utime + stime
|
402
|
-
idle1 = uptime - starttime - total_time
|
371
|
+
u = cpu_usage_thread(pid, sleep)
|
372
|
+
return nil unless u
|
403
373
|
|
404
|
-
|
405
|
-
|
406
|
-
stat = LinuxStat::ProcFS.ps_stat(pid)
|
407
|
-
uptime = LS::ProcFS.uptime_f
|
408
|
-
return nil unless uptime && !stat.empty?
|
409
|
-
|
410
|
-
utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
|
411
|
-
uptime *= ticks
|
412
|
-
|
413
|
-
total_time2 = utime2 + stime2
|
414
|
-
idle2 = uptime - starttime2 - total_time2
|
415
|
-
|
416
|
-
totald = idle2.+(total_time2).-(idle1 + total_time)
|
417
|
-
|
418
|
-
u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)
|
419
|
-
|
420
|
-
cpu_count_t100 = cpu_count * 100
|
374
|
+
cpu_count_t100 = LinuxStat::CPU.count * 100
|
421
375
|
u > cpu_count_t100 ? cpu_count_t100 : u.round(2)
|
422
376
|
end
|
423
377
|
|
@@ -655,6 +609,47 @@ module LinuxStat
|
|
655
609
|
LinuxStat::Nproc.count_cpu_for_pid(pid)
|
656
610
|
end
|
657
611
|
|
612
|
+
##
|
613
|
+
# = def cpu_times_i(pid = $$)
|
614
|
+
#
|
615
|
+
# Shows the CPU time used by the process.
|
616
|
+
#
|
617
|
+
# The return value is a Float.
|
618
|
+
# But if the info isn't available, it will return nil.
|
619
|
+
def cpu_time(pid = $$)
|
620
|
+
LinuxStat::ProcFS.ps_times(pid)
|
621
|
+
end
|
622
|
+
|
623
|
+
##
|
624
|
+
# = def cpu_times(pid = $$)
|
625
|
+
#
|
626
|
+
# Shows the CPU time used by the process.
|
627
|
+
#
|
628
|
+
# The return value is a Hash formatted like this:
|
629
|
+
# LS::ProcessInfo.cpu_times($$)
|
630
|
+
#
|
631
|
+
# => {:hour=>0, :minute=>39, :second=>12, :jiffy=>0.42}
|
632
|
+
#
|
633
|
+
# But if the info isn't available, it will return an empty Hash..
|
634
|
+
def cpu_times(pid = $$)
|
635
|
+
v = LinuxStat::ProcFS.ps_times(pid)
|
636
|
+
return {} unless v
|
637
|
+
|
638
|
+
v_i = v.to_i
|
639
|
+
|
640
|
+
hour = v_i / 3600
|
641
|
+
min = v_i % 3600 / 60
|
642
|
+
sec = v_i % 60
|
643
|
+
jiffy = v.-(v_i) * 100
|
644
|
+
|
645
|
+
{
|
646
|
+
hour: hour,
|
647
|
+
minute: min,
|
648
|
+
second: sec,
|
649
|
+
jiffy: jiffy.to_i
|
650
|
+
}
|
651
|
+
end
|
652
|
+
|
658
653
|
alias count_cpu nproc
|
659
654
|
|
660
655
|
private
|
@@ -674,8 +669,33 @@ module LinuxStat
|
|
674
669
|
@@pagesize ||= LinuxStat::Sysconf.pagesize.to_i
|
675
670
|
end
|
676
671
|
|
677
|
-
def
|
678
|
-
|
672
|
+
def cpu_usage_thread(pid, delay)
|
673
|
+
ticks = get_ticks
|
674
|
+
stat = LinuxStat::ProcFS.ps_stat(pid)
|
675
|
+
uptime = LS::ProcFS.uptime_f
|
676
|
+
return nil unless uptime && !stat.empty?
|
677
|
+
|
678
|
+
utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
|
679
|
+
uptime *= ticks
|
680
|
+
|
681
|
+
total_time = utime + stime
|
682
|
+
idle1 = uptime - starttime - total_time
|
683
|
+
|
684
|
+
sleep(delay)
|
685
|
+
|
686
|
+
stat = LinuxStat::ProcFS.ps_stat(pid)
|
687
|
+
uptime = LS::ProcFS.uptime_f
|
688
|
+
return nil unless uptime && !stat.empty?
|
689
|
+
|
690
|
+
utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
|
691
|
+
uptime *= ticks
|
692
|
+
|
693
|
+
total_time2 = utime2 + stime2
|
694
|
+
idle2 = uptime - starttime2 - total_time2
|
695
|
+
|
696
|
+
totald = idle2.+(total_time2).-(idle1 + total_time)
|
697
|
+
|
698
|
+
totald.-(idle2 - idle1).fdiv(totald).abs.*(100)
|
679
699
|
end
|
680
700
|
end
|
681
701
|
end
|