linux_stat 0.4.2 → 0.6.3
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 +354 -57
- data/bin/console +1 -1
- data/bin/setup +0 -2
- data/{bin → exe}/linuxstat.rb +7 -9
- 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 +32 -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/net.rb +107 -1
- data/lib/linux_stat/prettify_bytes.rb +75 -0
- data/lib/linux_stat/process_info.rb +107 -48
- data/lib/linux_stat/user.rb +298 -0
- data/lib/linux_stat/version.rb +1 -1
- metadata +11 -6
data/bin/console
CHANGED
data/bin/setup
CHANGED
data/{bin → exe}/linuxstat.rb
RENAMED
@@ -1,16 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
$-v = true
|
3
|
+
|
2
4
|
begin
|
3
|
-
require 'linux_stat'
|
5
|
+
require 'linux_stat' unless defined?(LinuxStat)
|
4
6
|
rescue LoadError
|
5
|
-
|
7
|
+
abort "The Gem needs to be installed before this test can be run!"
|
6
8
|
end
|
7
9
|
|
8
|
-
$-v = true
|
9
|
-
|
10
|
-
# Print time each method takes unless --no-time or -nt option is passed
|
11
|
-
markdown = ARGV.any? { |x| x[/^\-(\-markdown|md)$/] }
|
12
|
-
html = ARGV.any? { |x| x[/^\-(\-html|html)$/] }
|
13
|
-
|
14
10
|
# Check which conflicting argument (e.g., `-md -html` together) is passed last
|
15
11
|
# Always use the last argument
|
16
12
|
conflicting, hash = [
|
@@ -38,6 +34,7 @@ end
|
|
38
34
|
|
39
35
|
MARKDOWN, HTML = hash[:markdown], hash[:html]
|
40
36
|
|
37
|
+
# Print time each method takes unless --no-time or -nt option is passed
|
41
38
|
PRINT_TIME = (MARKDOWN || HTML) ? false : !ARGV.any? { |x| x[/^\-\-no-time$/] || x[/^\-nt$/] }
|
42
39
|
|
43
40
|
%w(--markdown -md --no-time -nt --html -html).each(&ARGV.method(:delete))
|
@@ -99,10 +96,11 @@ execute.sort.each do |c|
|
|
99
96
|
puts
|
100
97
|
end
|
101
98
|
|
102
|
-
meths.length > 0
|
99
|
+
if meths.length > 0
|
103
100
|
if MARKDOWN
|
104
101
|
puts "```\n\n"
|
105
102
|
elsif HTML
|
106
103
|
puts "</pre>"
|
107
104
|
end
|
105
|
+
end
|
108
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,48 @@
|
|
1
|
+
# ----------------------------------------------------------------------------------------------------- #
|
2
|
+
# Don't edit this file unless you know what you are doing. #
|
3
|
+
# #
|
4
|
+
# A file can have reverse dependency. #
|
5
|
+
# For example, linux_stat/utsname is required before #
|
6
|
+
# linux_stat/os, which means utsname can be used by LinuxStat::OS and the files below. #
|
7
|
+
# #
|
8
|
+
# Once wrongly edited, you need to go through each method to know what #
|
9
|
+
# file is required by the module functions. Which can be very time consuming. #
|
10
|
+
# #
|
11
|
+
# If you are writng an independent module, just add them under "Independent" section #
|
12
|
+
# If you are writing a dependent module, just append that to the end of the file. #
|
13
|
+
# If you are writing something that is miscellaneous, just add it to miscellaneous section #
|
14
|
+
# ------------------------------------------------------------------------------------------------------ #
|
15
|
+
|
16
|
+
# Miscellaneous Modules
|
17
|
+
# Independed and LinuxStat's miscellaneous modules
|
1
18
|
require "linux_stat/version"
|
19
|
+
require 'linux_stat/prettify_bytes'
|
20
|
+
|
21
|
+
# Independed Modules
|
22
|
+
# Modules that doesn't have any dependency on its own
|
23
|
+
# But might be required by other module functions in "Dependent Modules" section
|
2
24
|
require "linux_stat/battery"
|
3
25
|
require "linux_stat/bios"
|
4
26
|
require "linux_stat/cpu"
|
5
27
|
require "linux_stat/memory"
|
6
28
|
require "linux_stat/net"
|
29
|
+
require "linux_stat/process"
|
30
|
+
require "linux_stat/swap"
|
31
|
+
|
32
|
+
# Dependent Modules
|
33
|
+
# Modules that can have reverse dependency
|
7
34
|
|
35
|
+
# LinuxStat::Uname dependent modules
|
8
36
|
require 'linux_stat/utsname'
|
9
37
|
require "linux_stat/os"
|
10
38
|
|
11
|
-
|
12
|
-
require "linux_stat/swap"
|
13
|
-
require "linux_stat/mounts"
|
14
|
-
|
39
|
+
# LinuxStat::FS dependent modules
|
15
40
|
require "linux_stat/fs_stat"
|
16
41
|
require "linux_stat/filesystem"
|
42
|
+
require "linux_stat/mounts"
|
17
43
|
|
44
|
+
# LinuxStat::Sysconf dependent modules
|
18
45
|
require "linux_stat/sysconf"
|
19
46
|
require "linux_stat/kernel"
|
47
|
+
require 'linux_stat/user'
|
20
48
|
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
|
data/lib/linux_stat/net.rb
CHANGED
@@ -1,13 +1,119 @@
|
|
1
1
|
module LinuxStat
|
2
2
|
module Net
|
3
3
|
class << self
|
4
|
+
DEV = '/proc/net/dev'.freeze
|
4
5
|
# Returns the local IP address of the system as a String.
|
5
6
|
# If the information isn't available, it will a frozen empty string.
|
6
7
|
def ipv4_private
|
7
|
-
require 'socket'
|
8
|
+
require 'socket' unless defined?(Socket)
|
8
9
|
ip = Socket.ip_address_list.find(&:ipv4_private?)
|
9
10
|
ip ? ip.ip? ? ip.ip_unpack[0].freeze : ''.freeze : ''.freeze
|
10
11
|
end
|
12
|
+
|
13
|
+
# Returns the total bytes received and transmitted as Hash.
|
14
|
+
# For example:
|
15
|
+
# {:received=>56602867, :transmitted=>6940922}
|
16
|
+
#
|
17
|
+
# But if the status isn't available it will return an empty Hash.
|
18
|
+
def total_bytes
|
19
|
+
return {} unless File.readable?(DEV)
|
20
|
+
|
21
|
+
data = IO.readlines(DEV).drop(2)
|
22
|
+
indices = find_index_of_bytes
|
23
|
+
data.reject! { |x| x.strip.start_with?('lo:') }
|
24
|
+
r, t = data.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
|
25
|
+
|
26
|
+
{
|
27
|
+
received: r,
|
28
|
+
transmitted: t
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the total bytes received as Integer.
|
33
|
+
#
|
34
|
+
# But if the status isn't available it will return nil.
|
35
|
+
def total_bytes_received
|
36
|
+
return nil unless File.readable?(DEV)
|
37
|
+
|
38
|
+
data = IO.readlines(DEV).drop(2)
|
39
|
+
index = find_index_of_bytes[0]
|
40
|
+
data.reject! { |x| x.strip.start_with?('lo:') }
|
41
|
+
data.map { |x| x.split[index].to_i }.sum
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the total bytes transmitted as Integer.
|
45
|
+
#
|
46
|
+
# But if the status isn't available it will return nil.
|
47
|
+
def total_bytes_transmitted
|
48
|
+
return nil unless File.readable?(DEV)
|
49
|
+
|
50
|
+
data = IO.readlines(DEV).drop(2)
|
51
|
+
index = find_index_of_bytes[-1]
|
52
|
+
data.reject! { |x| x.strip.start_with?('lo:') }
|
53
|
+
data.map { |x| x.split[index].to_i }.sum
|
54
|
+
end
|
55
|
+
|
56
|
+
# usage(interval = 0.1)
|
57
|
+
# Where interval is the time between polling in seconds. The default is 0.1 seconds.
|
58
|
+
#
|
59
|
+
# The return type is a Hash, containg the current internet usage (received, transmit) in B/s.
|
60
|
+
#
|
61
|
+
# For example:
|
62
|
+
# {:received=>436060.0, :transmitted=>50350.0}
|
63
|
+
#
|
64
|
+
# If the system transmits 100 kb in the interval,
|
65
|
+
# this method will return 1000 kb/s. That is, it estimates
|
66
|
+
# the data it will transmit in one second. Thus, a good and reliable interval is 1 second
|
67
|
+
# It will return an empty Hash if the info (/proc/net/dev) isn't available.
|
68
|
+
def usage(interval = 0.1)
|
69
|
+
return {} unless File.readable?(DEV)
|
70
|
+
|
71
|
+
data = IO.readlines(DEV).drop(2)
|
72
|
+
indices = find_index_of_bytes
|
73
|
+
data.reject! { |x| x.strip.start_with?('lo:') }
|
74
|
+
r, t = data.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
|
75
|
+
|
76
|
+
sleep(interval)
|
77
|
+
|
78
|
+
data2 = IO.readlines(DEV).drop(2)
|
79
|
+
data2.reject! { |x| x.strip.start_with?('lo:') }
|
80
|
+
r2, t2 = data2.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
|
81
|
+
|
82
|
+
# Measure the difference
|
83
|
+
dr, dt = r2.-(r).fdiv(interval), t2.-(t).fdiv(interval)
|
84
|
+
|
85
|
+
{
|
86
|
+
received: dr,
|
87
|
+
transmitted: dt
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
alias current_usage usage
|
92
|
+
|
93
|
+
private
|
94
|
+
# Returns the index containing the received and transmitted bytes
|
95
|
+
def find_index_of_bytes
|
96
|
+
@@index_of_bytes ||= nil
|
97
|
+
|
98
|
+
unless @@index_of_bytes
|
99
|
+
data = IO.foreach(DEV)
|
100
|
+
|
101
|
+
r, h = data.next.split, {}
|
102
|
+
|
103
|
+
r.each_with_index { |x, i|
|
104
|
+
downcased = x.downcase
|
105
|
+
h.merge!(:r => i) if downcased.start_with?('receive')
|
106
|
+
h.merge!(:t => i) if downcased.start_with?('transmit')
|
107
|
+
}
|
108
|
+
|
109
|
+
data_0 = data.next.gsub(?|.freeze, ' %'.freeze)
|
110
|
+
@@index_of_bytes = []
|
111
|
+
data_0.split.each_with_index { |x, i| @@index_of_bytes << i if x == '%bytes'.freeze }
|
112
|
+
h[:r] > h[:t] ? @@index_of_bytes.reverse : @@index_of_bytes
|
113
|
+
else
|
114
|
+
@@index_of_bytes
|
115
|
+
end
|
116
|
+
end
|
11
117
|
end
|
12
118
|
end
|
13
119
|
end
|