linux_stat 0.4.0 → 0.6.2
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/LICENSE.txt +21 -0
- data/README.md +465 -52
- data/bin/console +1 -1
- data/bin/setup +0 -2
- data/{bin → exe}/linuxstat.rb +42 -7
- data/ext/fs_stat/fs_stat.c +2 -0
- data/ext/sysconf/sysconf.c +30 -2
- data/ext/utsname/utsname.c +2 -0
- data/lib/linux_stat.rb +11 -4
- data/lib/linux_stat/cpu.rb +14 -5
- data/lib/linux_stat/kernel.rb +1 -2
- data/lib/linux_stat/mounts.rb +152 -1
- data/lib/linux_stat/prettify_bytes.rb +75 -0
- data/lib/linux_stat/process_info.rb +108 -46
- data/lib/linux_stat/user.rb +298 -0
- data/lib/linux_stat/version.rb +1 -1
- metadata +11 -9
data/bin/console
CHANGED
data/bin/setup
CHANGED
data/{bin → exe}/linuxstat.rb
RENAMED
@@ -1,18 +1,43 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
$-v = true
|
3
|
+
|
2
4
|
begin
|
3
5
|
require 'linux_stat'
|
4
6
|
rescue LoadError
|
5
|
-
|
6
|
-
require 'linux_stat'
|
7
|
+
abort "The Gem needs to be installed before this test can be run!"
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
+
# Check which conflicting argument (e.g., `-md -html` together) is passed last
|
11
|
+
# Always use the last argument
|
12
|
+
conflicting, hash = [
|
13
|
+
"markdown|html", /^\-(\-markdown|md)$/, /^\-(\-html|html)$/
|
14
|
+
].each_slice(3).to_a, {}
|
15
|
+
|
16
|
+
conflicting.each do |x, y, z|
|
17
|
+
o1, o2 = *x.split(?|.freeze).map(&:to_sym)
|
18
|
+
m1, m2 = ARGV.any? { |_x| _x[y] }, ARGV.any? { |_x| _x[z] }
|
19
|
+
|
20
|
+
if m1 && m2
|
21
|
+
rev = ARGV.reverse
|
22
|
+
|
23
|
+
if rev.index { |_x| _x[y] } < rev.index { |_x| _x[z] }
|
24
|
+
hash.merge!(o1 => true)
|
25
|
+
else
|
26
|
+
hash.merge!(o2 => true)
|
27
|
+
end
|
28
|
+
elsif m1
|
29
|
+
hash.merge!(o1 => true)
|
30
|
+
elsif m2
|
31
|
+
hash.merge!(o2 => true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
MARKDOWN, HTML = hash[:markdown], hash[:html]
|
10
36
|
|
11
37
|
# Print time each method takes unless --no-time or -nt option is passed
|
12
|
-
|
13
|
-
PRINT_TIME = MARKDOWN ? false : !ARGV.any? { |x| x[/^\-\-no-time$/] || x[/^\-nt$/] }
|
38
|
+
PRINT_TIME = (MARKDOWN || HTML) ? false : !ARGV.any? { |x| x[/^\-\-no-time$/] || x[/^\-nt$/] }
|
14
39
|
|
15
|
-
%w(--markdown -md --no-time -nt).each(&ARGV.method(:delete))
|
40
|
+
%w(--markdown -md --no-time -nt --html -html).each(&ARGV.method(:delete))
|
16
41
|
|
17
42
|
# Run only desired classes / modules
|
18
43
|
constants = LinuxStat.constants
|
@@ -34,6 +59,8 @@ execute.sort.each do |c|
|
|
34
59
|
if meths.length > 0
|
35
60
|
if MARKDOWN
|
36
61
|
puts "### LinuxStat::#{c}\n```"
|
62
|
+
elsif HTML
|
63
|
+
puts "<h3>LinuxStat::#{c}</h3>\n<pre>"
|
37
64
|
else
|
38
65
|
puts "\e[1;4;38;2;255;240;0mLinuxStat::#{c}\e[0m"
|
39
66
|
end
|
@@ -50,6 +77,8 @@ execute.sort.each do |c|
|
|
50
77
|
|
51
78
|
if MARKDOWN
|
52
79
|
puts "#{e}.#{meth}\n=> #{dis}"
|
80
|
+
elsif HTML
|
81
|
+
puts "#{e}.#{meth}\n=> #{dis}"
|
53
82
|
else
|
54
83
|
puts "\e[1;38;2;80;80;255m#{e}.#{meth}\e[0m\n=> #{dis}"
|
55
84
|
end
|
@@ -67,5 +96,11 @@ execute.sort.each do |c|
|
|
67
96
|
puts
|
68
97
|
end
|
69
98
|
|
70
|
-
|
99
|
+
if meths.length > 0
|
100
|
+
if MARKDOWN
|
101
|
+
puts "```\n\n"
|
102
|
+
elsif HTML
|
103
|
+
puts "</pre>"
|
104
|
+
end
|
105
|
+
end
|
71
106
|
end
|
data/ext/fs_stat/fs_stat.c
CHANGED
data/ext/sysconf/sysconf.c
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
#include <unistd.h>
|
2
2
|
#include "ruby.h"
|
3
3
|
|
4
|
+
#pragma GCC optimize ("O3")
|
5
|
+
#pragma clang optimize on
|
6
|
+
#pragma once
|
7
|
+
|
4
8
|
static VALUE getTick(VALUE obj) {
|
5
9
|
return INT2FIX(sysconf(_SC_CLK_TCK)) ;
|
6
10
|
}
|
@@ -21,7 +25,7 @@ static VALUE getOpenMax(VALUE obj) {
|
|
21
25
|
return INT2FIX(sysconf(_SC_OPEN_MAX)) ;
|
22
26
|
}
|
23
27
|
|
24
|
-
static VALUE
|
28
|
+
static VALUE getPageSize(VALUE obj) {
|
25
29
|
return INT2FIX(sysconf(_SC_PAGESIZE)) ;
|
26
30
|
}
|
27
31
|
|
@@ -37,6 +41,23 @@ static VALUE getPosixVersion(VALUE obj) {
|
|
37
41
|
return INT2FIX(sysconf(_SC_VERSION)) ;
|
38
42
|
}
|
39
43
|
|
44
|
+
static VALUE getUser(VALUE obj) {
|
45
|
+
char *name = getlogin() ;
|
46
|
+
return name ? rb_str_new_cstr(name) : rb_str_new_cstr("") ;
|
47
|
+
}
|
48
|
+
|
49
|
+
static VALUE getUID(VALUE obj) {
|
50
|
+
return INT2FIX(getuid()) ;
|
51
|
+
}
|
52
|
+
|
53
|
+
static VALUE getGID(VALUE obj) {
|
54
|
+
return INT2FIX(getgid()) ;
|
55
|
+
}
|
56
|
+
|
57
|
+
static VALUE getEUID(VALUE obj) {
|
58
|
+
return INT2FIX(geteuid()) ;
|
59
|
+
}
|
60
|
+
|
40
61
|
void Init_sysconf() {
|
41
62
|
VALUE _linux_stat = rb_define_module("LinuxStat") ;
|
42
63
|
VALUE _sysconf = rb_define_module_under(_linux_stat, "Sysconf") ;
|
@@ -46,8 +67,15 @@ void Init_sysconf() {
|
|
46
67
|
rb_define_module_function(_sysconf, "hostname_max", getHostnameMax, 0) ;
|
47
68
|
rb_define_module_function(_sysconf, "login_name_max", getLoginNameMax, 0) ;
|
48
69
|
rb_define_module_function(_sysconf, "open_max", getOpenMax, 0) ;
|
49
|
-
rb_define_module_function(_sysconf, "
|
70
|
+
rb_define_module_function(_sysconf, "pagesize", getPageSize, 0) ;
|
50
71
|
rb_define_module_function(_sysconf, "stream_max", getStreamMax, 0) ;
|
51
72
|
rb_define_module_function(_sysconf, "tty_name_max", getTTYNameMax, 0) ;
|
52
73
|
rb_define_module_function(_sysconf, "posix_version", getPosixVersion, 0) ;
|
74
|
+
|
75
|
+
rb_define_module_function(_sysconf, "get_uid", getUID, 0) ;
|
76
|
+
rb_define_module_function(_sysconf, "get_gid", getGID, 0) ;
|
77
|
+
rb_define_module_function(_sysconf, "get_euid", getEUID, 0) ;
|
78
|
+
|
79
|
+
rb_define_module_function(_sysconf, "get_user", getUser, 0) ;
|
80
|
+
rb_define_module_function(_sysconf, "get_login", getUser, 0) ;
|
53
81
|
}
|
data/ext/utsname/utsname.c
CHANGED
data/lib/linux_stat.rb
CHANGED
@@ -1,20 +1,27 @@
|
|
1
|
+
# Independed and LinuxStat specific unrelated modules
|
1
2
|
require "linux_stat/version"
|
3
|
+
require 'linux_stat/prettify_bytes'
|
4
|
+
|
5
|
+
# Independed and LinuxStat related modules
|
2
6
|
require "linux_stat/battery"
|
3
7
|
require "linux_stat/bios"
|
4
8
|
require "linux_stat/cpu"
|
5
9
|
require "linux_stat/memory"
|
6
10
|
require "linux_stat/net"
|
11
|
+
require "linux_stat/process"
|
12
|
+
require "linux_stat/swap"
|
7
13
|
|
14
|
+
# LinuxStat::Uname dependent modules
|
8
15
|
require 'linux_stat/utsname'
|
9
16
|
require "linux_stat/os"
|
10
17
|
|
11
|
-
|
12
|
-
require "linux_stat/swap"
|
13
|
-
require "linux_stat/mounts"
|
14
|
-
|
18
|
+
# LinuxStat::FS dependent modules
|
15
19
|
require "linux_stat/fs_stat"
|
16
20
|
require "linux_stat/filesystem"
|
21
|
+
require "linux_stat/mounts"
|
17
22
|
|
23
|
+
# LinuxStat::Sysconf dependent modules
|
18
24
|
require "linux_stat/sysconf"
|
19
25
|
require "linux_stat/kernel"
|
26
|
+
require 'linux_stat/user'
|
20
27
|
require "linux_stat/process_info"
|
data/lib/linux_stat/cpu.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
module LinuxStat
|
2
2
|
module CPU
|
3
3
|
class << self
|
4
|
-
# stat(sleep = 0.
|
4
|
+
# stat(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck)
|
5
5
|
# Where sleep is the delay to gather the data.
|
6
|
+
# The minimum possible value at anytime is 1.0 / LinuxStat::Sysconf.sc_clk_tck
|
6
7
|
# This method returns the cpu usage of all threads.
|
7
8
|
#
|
8
9
|
# The first one is aggregated CPU usage reported by the Linux kernel.
|
@@ -12,7 +13,7 @@ module LinuxStat
|
|
12
13
|
# {0=>84.38, 1=>100.0, 2=>50.0, 3=>87.5, 4=>87.5}
|
13
14
|
#
|
14
15
|
# If the information is not available, it will return an empty Hash
|
15
|
-
def stat(sleep =
|
16
|
+
def stat(sleep = ticks_to_ms)
|
16
17
|
return {} unless stat?
|
17
18
|
|
18
19
|
data = IO.readlines('/proc/stat').select! { |x| x[/^cpu\d*/] }.map! { |x| x.split.map!(&:to_f) }
|
@@ -33,20 +34,24 @@ module LinuxStat
|
|
33
34
|
idle_then, idle_now = idle + iowait, idle2 + iowait2
|
34
35
|
totald = idle_now.+(user2 + nice2 + sys2 + irq2 + softirq2 + steal2) - idle_then.+(user + nice + sys + irq + softirq + steal)
|
35
36
|
|
37
|
+
res = totald.-(idle_now - idle_then).fdiv(totald).*(100).round(2).abs
|
38
|
+
res = 0.0 if res.nan?
|
39
|
+
|
36
40
|
h.merge!(
|
37
|
-
x =>
|
41
|
+
x => res
|
38
42
|
)
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
|
-
# total_usage(sleep = 0.
|
46
|
+
# total_usage(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck)
|
43
47
|
# Where sleep is the delay to gather the data.
|
48
|
+
# The minimum possible value at anytime is 1.0 / LinuxStat::Sysconf.sc_clk_tck
|
44
49
|
# This method returns the cpu usage of all threads.
|
45
50
|
#
|
46
51
|
# It's like running LinuxStat::CPU.stat[0] but it's much more efficient and calculates just the aggregated usage which is available at the top of the /proc/stat file.
|
47
52
|
#
|
48
53
|
# If the information is not available, it will return nil.
|
49
|
-
def total_usage(sleep =
|
54
|
+
def total_usage(sleep = ticks_to_ms)
|
50
55
|
return nil unless stat?
|
51
56
|
|
52
57
|
data = IO.foreach('/proc/stat').first.split.tap(&:shift).map!(&:to_f)
|
@@ -113,6 +118,10 @@ module LinuxStat
|
|
113
118
|
def stat?
|
114
119
|
@@stat_readable ||= File.readable?('/proc/stat')
|
115
120
|
end
|
121
|
+
|
122
|
+
def ticks_to_ms
|
123
|
+
@@ms ||= 1.0 / LinuxStat::Sysconf.sc_clk_tck
|
124
|
+
end
|
116
125
|
end
|
117
126
|
end
|
118
127
|
end
|
data/lib/linux_stat/kernel.rb
CHANGED
@@ -133,8 +133,6 @@ module LinuxStat
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
-
alias release version
|
137
|
-
|
138
136
|
# Reads maximum 1024 bytes from /proc/version and returns the string.
|
139
137
|
# The output is also cached ; as changing the value in runtime is unexpected.
|
140
138
|
def string
|
@@ -148,6 +146,7 @@ module LinuxStat
|
|
148
146
|
@@tick ||= LinuxStat::Sysconf.sc_clk_tck
|
149
147
|
end
|
150
148
|
|
149
|
+
alias release version
|
151
150
|
alias clk_tck ticks
|
152
151
|
|
153
152
|
private
|
data/lib/linux_stat/mounts.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module LinuxStat
|
2
2
|
module Mounts
|
3
3
|
class << self
|
4
|
-
# Reads /proc/mounts and returns
|
4
|
+
# Reads /proc/mounts and returns the output splitted with \n.
|
5
|
+
# In other words, it's same as running IO.readlines('/proc/mounts').each(&:strip!)
|
5
6
|
#
|
6
7
|
# It returns an Array.
|
7
8
|
# If the info isn't available or /proc/mounts is not readable, it will return an empty Array.
|
@@ -9,6 +10,14 @@ module LinuxStat
|
|
9
10
|
mounts
|
10
11
|
end
|
11
12
|
|
13
|
+
# Reads /proc/mounts and returns list of devices.
|
14
|
+
#
|
15
|
+
# It returns an Array.
|
16
|
+
# If the info isn't available or /proc/mounts is not readable, it will return an empty Array.
|
17
|
+
def list_devices
|
18
|
+
mounts.map { |x| x.split(?\s.freeze).first }
|
19
|
+
end
|
20
|
+
|
12
21
|
# Reads /proc/mounts and returns partition name of the device mounted at /.
|
13
22
|
#
|
14
23
|
# It returns a String.
|
@@ -45,6 +54,135 @@ module LinuxStat
|
|
45
54
|
ret
|
46
55
|
end
|
47
56
|
|
57
|
+
# mount_point(dev = root)
|
58
|
+
# Where device = block device.
|
59
|
+
# The default argument is the root block device.
|
60
|
+
#
|
61
|
+
# It helps you find the mountpoint of a block device.
|
62
|
+
# For example:
|
63
|
+
# LinuxStat::Mounts.mount_point('/dev/sdb1')
|
64
|
+
# => "/run/media/sourav/5c2b7af7-d4c3-4ab4-a035-06d18ffc8e6f"
|
65
|
+
#
|
66
|
+
# The return type is String.
|
67
|
+
# But if the status isn't available or the device isn't mounted, it will return an empty String.
|
68
|
+
def mount_point(dev = root)
|
69
|
+
m = ''
|
70
|
+
mounts.each do |x|
|
71
|
+
x.strip!
|
72
|
+
|
73
|
+
unless x.empty?
|
74
|
+
_x = x.split
|
75
|
+
if _x[0] == dev
|
76
|
+
m.replace(_x[1])
|
77
|
+
break
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
m
|
82
|
+
end
|
83
|
+
|
84
|
+
# list_devices_mount_point()
|
85
|
+
#
|
86
|
+
# It shows all the block devices corresponding to mount points.
|
87
|
+
#
|
88
|
+
# For example:
|
89
|
+
# LinuxStat::Mounts.list_devices_mount_point
|
90
|
+
# => {"proc"=>"/proc", "sys"=>"/sys", "dev"=>"/dev", "run"=>"/run", "/dev/sda2"=>"/", "securityfs"=>"/sys/kernel/security", "tmpfs"=>"/run/user/1000", "devpts"=>"/dev/pts", "cgroup2"=>"/sys/fs/cgroup/unified", "cgroup"=>"/sys/fs/cgroup/perf_event", "pstore"=>"/sys/fs/pstore", "none"=>"/sys/fs/bpf", "systemd-1"=>"/proc/sys/fs/binfmt_misc", "debugfs"=>"/sys/kernel/debug", "mqueue"=>"/dev/mqueue", "hugetlbfs"=>"/dev/hugepages", "tracefs"=>"/sys/kernel/tracing", "configfs"=>"/sys/kernel/config", "fusectl"=>"/sys/fs/fuse/connections", "gvfsd-fuse"=>"/run/user/1000/gvfs", "/dev/sdb1"=>"/run/media/sourav/5c2b7af7-d4c3-4ab4-a035-06d18ffc8e6f", "binfmt_misc"=>"/proc/sys/fs/binfmt_misc"}
|
91
|
+
#
|
92
|
+
# The return type is Hash.
|
93
|
+
# But if the status isn't available or the device isn't mounted, it will return an empty String.
|
94
|
+
def list_devices_mount_point
|
95
|
+
m = {}
|
96
|
+
mounts.each do |x|
|
97
|
+
x.strip!
|
98
|
+
|
99
|
+
unless x.empty?
|
100
|
+
_x = x.split
|
101
|
+
m.merge!(_x[0] => _x[1])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
m
|
105
|
+
end
|
106
|
+
|
107
|
+
# devices_stat
|
108
|
+
# [ Not to confuse this method with device_stat(dev) which shows only one device's info ]
|
109
|
+
#
|
110
|
+
# It shows all the block devices corresponding to mount points and data from LinuxStat::FS.stat(arg)
|
111
|
+
#
|
112
|
+
# For example:
|
113
|
+
# LinuxStat::Mounts.devices_stat
|
114
|
+
# => {"proc"=>{:mountpoint=>"/proc", :total=>0, :free=>0, :available=>0, :used=>0, :percent_used=>NaN, :percent_free=>NaN, :percent_available=>NaN}, "/dev/sdb1"=>{:mountpoint=>"/run/media/sourav/5c2b7af7-d4c3-4ab4-a035-06d18ffc8e6f", :total=>31466008576, :free=>2693931008, :available=>2693931008, :used=>28772077568, :percent_used=>91.44, :percent_free=>8.56, :percent_available=>8.56}}
|
115
|
+
#
|
116
|
+
# The return type is Hash.
|
117
|
+
# But if the status isn't available, it will return an empty Hash.
|
118
|
+
def devices_stat
|
119
|
+
# Code duplication is fine if it gives maximum performance
|
120
|
+
m = {}
|
121
|
+
mounts.each do |x|
|
122
|
+
x.strip!
|
123
|
+
|
124
|
+
unless x.empty?
|
125
|
+
_x = x.split
|
126
|
+
total, free, available, used = fs_info(_x[1])
|
127
|
+
|
128
|
+
m.merge!(_x[0] => {
|
129
|
+
mountpoint: _x[1],
|
130
|
+
|
131
|
+
total: total,
|
132
|
+
free: free,
|
133
|
+
available: available,
|
134
|
+
used: used,
|
135
|
+
|
136
|
+
percent_used: used.*(100).fdiv(total).round(2),
|
137
|
+
percent_free: free.*(100).fdiv(total).round(2),
|
138
|
+
percent_available: available.*(100).fdiv(total).round(2),
|
139
|
+
})
|
140
|
+
end
|
141
|
+
end
|
142
|
+
m
|
143
|
+
end
|
144
|
+
|
145
|
+
# device_stat(dev = root)
|
146
|
+
# [ Not to confuse this method with devices_stat() which shows all devices ]
|
147
|
+
# It shows all the block devices corresponding to mount points and data from LinuxStat::FS.stat(arg)
|
148
|
+
#
|
149
|
+
# For example:
|
150
|
+
# LinuxStat::Mounts.device_stat('/dev/sda2')
|
151
|
+
# => {"/dev/sda2"=>{:mountpoint=>"/", :total=>119981191168, :free=>35298562048, :available=>35298562048, :used=>84682629120, :percent_used=>70.58, :percent_free=>29.42, :percent_available=>29.42}}
|
152
|
+
#
|
153
|
+
# The return type is Hash.
|
154
|
+
# But if the status isn't available, it will return an empty Hash.
|
155
|
+
def device_stat(dev = root)
|
156
|
+
# Code duplication is fine if it gives maximum performance
|
157
|
+
m = {}
|
158
|
+
mounts.each do |x|
|
159
|
+
x.strip!
|
160
|
+
|
161
|
+
unless x.empty?
|
162
|
+
_x = x.split
|
163
|
+
next if _x[0] != dev
|
164
|
+
|
165
|
+
total, free, available, used = fs_info(_x[1])
|
166
|
+
|
167
|
+
m.merge!({
|
168
|
+
mountpoint: _x[1],
|
169
|
+
|
170
|
+
total: total,
|
171
|
+
free: free,
|
172
|
+
available: available,
|
173
|
+
used: used,
|
174
|
+
|
175
|
+
percent_used: used.*(100).fdiv(total).round(2),
|
176
|
+
percent_free: free.*(100).fdiv(total).round(2),
|
177
|
+
percent_available: available.*(100).fdiv(total).round(2),
|
178
|
+
})
|
179
|
+
|
180
|
+
break
|
181
|
+
end
|
182
|
+
end
|
183
|
+
m
|
184
|
+
end
|
185
|
+
|
48
186
|
private
|
49
187
|
def mount_readable?
|
50
188
|
@@mount_readable ||= File.readable?('/proc/mounts')
|
@@ -59,6 +197,19 @@ module LinuxStat
|
|
59
197
|
return [] unless mount_readable?
|
60
198
|
@@root ||= IO.foreach('/proc/mounts').find { |x| x.split[1] == '/'.freeze }.split
|
61
199
|
end
|
200
|
+
|
201
|
+
def fs_info(dev)
|
202
|
+
# => [total, free, available, used]
|
203
|
+
s = LinuxStat::FS.stat(dev)
|
204
|
+
s.default = 0
|
205
|
+
|
206
|
+
[
|
207
|
+
s[:block_size] * s[:blocks],
|
208
|
+
s[:block_size] * s[:block_free],
|
209
|
+
s[:block_size] * s[:block_avail_unpriv],
|
210
|
+
s[:blocks].-(s[:block_free]) * s[:block_size]
|
211
|
+
]
|
212
|
+
end
|
62
213
|
end
|
63
214
|
end
|
64
215
|
end
|