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.
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  $-v = true
3
- %w(bundler/setup linux_stat irb).each(&method(:require))
3
+ %w(linux_stat irb).each(&method(:require))
4
4
  IRB.start(__FILE__)
data/bin/setup CHANGED
@@ -4,5 +4,3 @@ IFS=$'\n\t'
4
4
  set -vx
5
5
 
6
6
  bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -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
- require 'bundler/setup'
6
- require 'linux_stat'
7
+ abort "The Gem needs to be installed before this test can be run!"
7
8
  end
8
9
 
9
- $-v = true
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
- MARKDOWN = ARGV.any? { |x| x[/^\-\-markdown$/] || x[/^\-md$/] }
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
- puts "```\n\n" if MARKDOWN && meths.length > 0
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
@@ -1,7 +1,9 @@
1
1
  #include <sys/statvfs.h>
2
2
  #include "ruby.h"
3
+
3
4
  #pragma GCC optimize ("O3")
4
5
  #pragma clang optimize on
6
+ #pragma once
5
7
 
6
8
  static VALUE statfs(VALUE obj, VALUE dir) {
7
9
  struct statvfs buf ;
@@ -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 getPageSizeMax(VALUE obj) {
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, "page_size_max", getPageSizeMax, 0) ;
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
  }
@@ -1,7 +1,9 @@
1
1
  #include <sys/utsname.h>
2
2
  #include "ruby.h"
3
+
3
4
  #pragma GCC optimize ("O3")
4
5
  #pragma clang optimize on
6
+ #pragma once
5
7
 
6
8
  static struct utsname buf ;
7
9
  static short status ;
@@ -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
- require "linux_stat/process"
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"
@@ -1,8 +1,9 @@
1
1
  module LinuxStat
2
2
  module CPU
3
3
  class << self
4
- # stat(sleep = 0.075)
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 = 0.075)
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 => totald.-(idle_now - idle_then).fdiv(totald).*(100).round(2).abs
41
+ x => res
38
42
  )
39
43
  end
40
44
  end
41
45
 
42
- # total_usage(sleep = 0.075)
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 = 0.075)
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
@@ -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
@@ -1,7 +1,8 @@
1
1
  module LinuxStat
2
2
  module Mounts
3
3
  class << self
4
- # Reads /proc/mounts and returns list of devices.
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