linux_stat 0.3.3 → 0.6.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.
@@ -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
@@ -29,10 +54,13 @@ execute.sort.each do |c|
29
54
  next if e.class != Module && e.class != Class
30
55
 
31
56
  meths = e.methods(false).sort
57
+ next if meths.any? { |a| e.method(a).arity > 0 }
32
58
 
33
59
  if meths.length > 0
34
60
  if MARKDOWN
35
61
  puts "### LinuxStat::#{c}\n```"
62
+ elsif HTML
63
+ puts "<h3>LinuxStat::#{c}</h3>\n<pre>"
36
64
  else
37
65
  puts "\e[1;4;38;2;255;240;0mLinuxStat::#{c}\e[0m"
38
66
  end
@@ -49,6 +77,8 @@ execute.sort.each do |c|
49
77
 
50
78
  if MARKDOWN
51
79
  puts "#{e}.#{meth}\n=> #{dis}"
80
+ elsif HTML
81
+ puts "#{e}.#{meth}\n=> #{dis}"
52
82
  else
53
83
  puts "\e[1;38;2;80;80;255m#{e}.#{meth}\e[0m\n=> #{dis}"
54
84
  end
@@ -66,5 +96,11 @@ execute.sort.each do |c|
66
96
  puts
67
97
  end
68
98
 
69
- 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
70
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 ;
@@ -25,6 +27,7 @@ static VALUE statfs(VALUE obj, VALUE dir) {
25
27
  }
26
28
 
27
29
  void Init_fs_stat() {
28
- VALUE fs = rb_define_module("FS") ;
30
+ VALUE _linux_stat = rb_define_module("LinuxStat") ;
31
+ VALUE fs = rb_define_module_under(_linux_stat, "FS") ;
29
32
  rb_define_module_function(fs, "stat", statfs, 1) ;
30
33
  }
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+
3
+ unless (have_header('sys/unistd.h') && have_header('ruby.h'))
4
+ abort('Missing header')
5
+ end
6
+
7
+ create_makefile 'linux_stat/sysconf'
@@ -0,0 +1,81 @@
1
+ #include <unistd.h>
2
+ #include "ruby.h"
3
+
4
+ #pragma GCC optimize ("O3")
5
+ #pragma clang optimize on
6
+ #pragma once
7
+
8
+ static VALUE getTick(VALUE obj) {
9
+ return INT2FIX(sysconf(_SC_CLK_TCK)) ;
10
+ }
11
+
12
+ static VALUE getChildMax(VALUE obj) {
13
+ return INT2FIX(sysconf(_SC_CHILD_MAX)) ;
14
+ }
15
+
16
+ static VALUE getHostnameMax(VALUE obj) {
17
+ return INT2FIX(sysconf(_SC_HOST_NAME_MAX)) ;
18
+ }
19
+
20
+ static VALUE getLoginNameMax(VALUE obj) {
21
+ return INT2FIX(sysconf(_SC_LOGIN_NAME_MAX)) ;
22
+ }
23
+
24
+ static VALUE getOpenMax(VALUE obj) {
25
+ return INT2FIX(sysconf(_SC_OPEN_MAX)) ;
26
+ }
27
+
28
+ static VALUE getPageSizeMax(VALUE obj) {
29
+ return INT2FIX(sysconf(_SC_PAGESIZE)) ;
30
+ }
31
+
32
+ static VALUE getStreamMax(VALUE obj) {
33
+ return INT2FIX(sysconf(_SC_STREAM_MAX)) ;
34
+ }
35
+
36
+ static VALUE getTTYNameMax(VALUE obj) {
37
+ return INT2FIX(sysconf(_SC_TTY_NAME_MAX)) ;
38
+ }
39
+
40
+ static VALUE getPosixVersion(VALUE obj) {
41
+ return INT2FIX(sysconf(_SC_VERSION)) ;
42
+ }
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
+
61
+ void Init_sysconf() {
62
+ VALUE _linux_stat = rb_define_module("LinuxStat") ;
63
+ VALUE _sysconf = rb_define_module_under(_linux_stat, "Sysconf") ;
64
+
65
+ rb_define_module_function(_sysconf, "sc_clk_tck", getTick, 0) ;
66
+ rb_define_module_function(_sysconf, "child_max", getChildMax, 0) ;
67
+ rb_define_module_function(_sysconf, "hostname_max", getHostnameMax, 0) ;
68
+ rb_define_module_function(_sysconf, "login_name_max", getLoginNameMax, 0) ;
69
+ rb_define_module_function(_sysconf, "open_max", getOpenMax, 0) ;
70
+ rb_define_module_function(_sysconf, "page_size_max", getPageSizeMax, 0) ;
71
+ rb_define_module_function(_sysconf, "stream_max", getStreamMax, 0) ;
72
+ rb_define_module_function(_sysconf, "tty_name_max", getTTYNameMax, 0) ;
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) ;
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 ;
@@ -10,9 +12,9 @@ void init_buf() {
10
12
  status = uname(&buf) ;
11
13
  }
12
14
 
13
- static VALUE getMachine(VALUE obj) {
14
- VALUE machine = status < 0 ? rb_str_new_cstr("") : rb_str_new_cstr(buf.machine) ;
15
- return machine ;
15
+ static VALUE getSysname(VALUE obj) {
16
+ VALUE sysname = status < 0 ? rb_str_new_cstr("") : rb_str_new_cstr(buf.sysname) ;
17
+ return sysname ;
16
18
  }
17
19
 
18
20
  static VALUE getNodename(VALUE obj) {
@@ -20,10 +22,30 @@ static VALUE getNodename(VALUE obj) {
20
22
  return nodename ;
21
23
  }
22
24
 
25
+ static VALUE getRelease(VALUE obj) {
26
+ VALUE release = status < 0 ? rb_str_new_cstr("") : rb_str_new_cstr(buf.release) ;
27
+ return release ;
28
+ }
29
+
30
+ static VALUE getVersion(VALUE obj) {
31
+ VALUE version = status < 0 ? rb_str_new_cstr("") : rb_str_new_cstr(buf.version) ;
32
+ return version ;
33
+ }
34
+
35
+ static VALUE getMachine(VALUE obj) {
36
+ VALUE machine = status < 0 ? rb_str_new_cstr("") : rb_str_new_cstr(buf.machine) ;
37
+ return machine ;
38
+ }
39
+
23
40
  void Init_utsname() {
24
41
  init_buf() ;
25
42
 
26
- VALUE _uname = rb_define_module("Uname") ;
27
- rb_define_module_function(_uname, "machine", getMachine, 0) ;
43
+ VALUE _linux_stat = rb_define_module("LinuxStat") ;
44
+ VALUE _uname = rb_define_module_under(_linux_stat, "Uname") ;
45
+
46
+ rb_define_module_function(_uname, "sysname", getSysname, 0) ;
28
47
  rb_define_module_function(_uname, "nodename", getNodename, 0) ;
48
+ rb_define_module_function(_uname, "release", getRelease, 0) ;
49
+ rb_define_module_function(_uname, "version", getVersion, 0) ;
50
+ rb_define_module_function(_uname, "machine", getMachine, 0) ;
29
51
  }
@@ -1,17 +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
- require "linux_stat/kernel"
6
9
  require "linux_stat/memory"
7
10
  require "linux_stat/net"
11
+ require "linux_stat/process"
12
+ require "linux_stat/swap"
8
13
 
14
+ # LinuxStat::Uname dependent modules
9
15
  require 'linux_stat/utsname'
10
16
  require "linux_stat/os"
11
17
 
12
- require "linux_stat/process"
13
- require "linux_stat/swap"
14
- require "linux_stat/mounts"
15
-
18
+ # LinuxStat::FS dependent modules
16
19
  require "linux_stat/fs_stat"
17
20
  require "linux_stat/filesystem"
21
+ require "linux_stat/mounts"
22
+
23
+ # LinuxStat::Sysconf dependent modules
24
+ require "linux_stat/sysconf"
25
+ require "linux_stat/kernel"
26
+ require 'linux_stat/user'
27
+ require "linux_stat/process_info"
@@ -9,7 +9,7 @@ module LinuxStat
9
9
  end
10
10
 
11
11
  # Returns the details of the battery.
12
- #If the battery is not present it will return an empty Hash.
12
+ # If the battery is not present it will return an empty Hash.
13
13
  def stat
14
14
  st = status.downcase
15
15
  return {} unless present?
@@ -27,7 +27,7 @@ module LinuxStat
27
27
  end
28
28
 
29
29
  # Returns the model of the battery.
30
- #If the battery is not present or the information isn't available it will return an empty String.
30
+ # If the battery is not present or the information isn't available it will return an empty String.
31
31
  def model
32
32
  return ''.freeze unless model_readable?
33
33
  IO.read(File.join(PATH, 'model_name')).tap(&:strip!)
@@ -3,9 +3,10 @@ module LinuxStat
3
3
  class << self
4
4
  # Returns the model of the BIOS.
5
5
  # If the information is not available it will return a frozen empty string.
6
- # The output is also cached ; as changing the value in runtime is unexpected.
6
+ #
7
+ # The output is also cached (memoized) ; as changing the value in runtime is unexpected.
7
8
  def model
8
- # Cached ; as changing the value in runtime is unexpected
9
+ # cached (memoized) ; as changing the value in runtime is unexpected
9
10
  @@model ||= if File.readable?('/sys/devices/virtual/dmi/id/product_name')
10
11
  IO.read('/sys/devices/virtual/dmi/id/product_name').tap(&:strip!)
11
12
  elsif File.readable?('/sys/firmware/devicetree/base/model')
@@ -17,9 +18,10 @@ module LinuxStat
17
18
 
18
19
  # Returns the vendor of the BIOS.
19
20
  # If the information is not available it will return a frozen empty string.
20
- # The output is also cached ; as changing the value in runtime is unexpected.
21
+ #
22
+ # The output is also cached (memoized) ; as changing the value in runtime is unexpected.
21
23
  def vendor
22
- # Cached ; as changing the value in runtime is unexpected
24
+ # cached (memoized) ; as changing the value in runtime is unexpected
23
25
  @@vendor ||= if File.readable?('/sys/devices/virtual/dmi/id/bios_vendor')
24
26
  IO.read('/sys/devices/virtual/dmi/id/bios_vendor').tap(&:strip!)
25
27
  else
@@ -29,7 +31,8 @@ module LinuxStat
29
31
 
30
32
  # Returns the version of the BIOS.
31
33
  # If the information is not available it will return a frozen empty string.
32
- # The output is also cached ; as changing the value in runtime is unexpected.
34
+ #
35
+ # The output is also cached (memoized) ; as changing the value in runtime is unexpected.
33
36
  def version
34
37
  @@version ||= if File.readable?('/sys/devices/virtual/dmi/id/bios_version')
35
38
  IO.read('/sys/devices/virtual/dmi/id/bios_version').tap(&:strip!)
@@ -40,7 +43,8 @@ module LinuxStat
40
43
 
41
44
  # Returns the date of the BIOS.
42
45
  # If the information is not available it will return a frozen empty string.
43
- # The output is also cached ; as changing the value in runtime is unexpected.
46
+ #
47
+ # The output is also cached (memoized) ; as changing the value in runtime is unexpected.
44
48
  def date
45
49
  @@date ||= if File.readable?('/sys/devices/virtual/dmi/id/bios_date')
46
50
  IO.read('/sys/devices/virtual/dmi/id/bios_date').tap(&:strip!)
@@ -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,34 +13,45 @@ 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) }
19
20
  sleep(sleep)
20
21
  data2 = IO.readlines('/proc/stat').select! { |x| x[/^cpu\d*/] }.map! { |x| x.split.map!(&:to_f) }
21
22
 
22
- data.size.times.reduce({}) do |h, x|
23
+ # On devices like android, the core count can change anytime.
24
+ # I had crashes on Termux.
25
+ # So better just count the min number of CPU and iterate over that
26
+ # If data.length is smaller than data2.length, we don't have enough data to compare.
27
+ dl, d2l = data.length, data2.length
28
+ min = dl > d2l ? d2l : dl
29
+
30
+ min.times.reduce({}) do |h, x|
23
31
  user, nice, sys, idle, iowait, irq, softirq, steal = *data[x].drop(1)
24
32
  user2, nice2, sys2, idle2, iowait2, irq2, softirq2, steal2 = *data2[x].drop(1)
25
33
 
26
34
  idle_then, idle_now = idle + iowait, idle2 + iowait2
27
35
  totald = idle_now.+(user2 + nice2 + sys2 + irq2 + softirq2 + steal2) - idle_then.+(user + nice + sys + irq + softirq + steal)
28
36
 
37
+ res = totald.-(idle_now - idle_then).fdiv(totald).*(100).round(2).abs
38
+ res = 0.0 if res.nan?
39
+
29
40
  h.merge!(
30
- x => totald.-(idle_now - idle_then).fdiv(totald).*(100).round(2).abs
41
+ x => res
31
42
  )
32
43
  end
33
44
  end
34
45
 
35
- # total_usage(sleep = 0.075)
46
+ # total_usage(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck)
36
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
37
49
  # This method returns the cpu usage of all threads.
38
50
  #
39
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.
40
52
  #
41
53
  # If the information is not available, it will return nil.
42
- def total_usage(sleep = 0.075)
54
+ def total_usage(sleep = ticks_to_ms)
43
55
  return nil unless stat?
44
56
 
45
57
  data = IO.foreach('/proc/stat').first.split.tap(&:shift).map!(&:to_f)
@@ -63,7 +75,8 @@ module LinuxStat
63
75
 
64
76
  # Returns the model of processor.
65
77
  # If the information isn't available, it will return en empty string.
66
- # The output is also cached ; as changing the value in runtime is unexpected.
78
+ #
79
+ # The output is also cached (memoized) ; as changing the value in runtime is unexpected.
67
80
  def model
68
81
  @@name ||= cpuinfo.find { |x| x.start_with?('model name') }.to_s.split(?:)[-1].to_s.strip
69
82
  end
@@ -105,6 +118,10 @@ module LinuxStat
105
118
  def stat?
106
119
  @@stat_readable ||= File.readable?('/proc/stat')
107
120
  end
121
+
122
+ def ticks_to_ms
123
+ @@ms ||= 1.0 / LinuxStat::Sysconf.sc_clk_tck
124
+ end
108
125
  end
109
126
  end
110
127
  end
@@ -1,7 +1,5 @@
1
1
  module LinuxStat
2
2
  module Filesystem
3
- prepend FS
4
-
5
3
  class << self
6
4
  # stat(fs = '/')
7
5
  # Where fs is the directory of the file system (like / or /tmp/ or /run/media/thumbdrive).
@@ -12,7 +10,7 @@ module LinuxStat
12
10
  # 3. used space (in kilobytes)
13
11
  #
14
12
  # In a hash format:
15
- # {:total=>119981191168, :free=>43155574784, :used=>76825616384, :available=>43155574784}
13
+ # {:total=>119981191168, :free=>43155574784, :used=>76825616384, :available=>43155574784}
16
14
  #
17
15
  # If the stat can't be acquired, this method will return an empty Hash.
18
16
  def stat(fs = ?/.freeze)
@@ -23,7 +21,7 @@ module LinuxStat
23
21
  {
24
22
  total: s[:block_size] * s[:blocks],
25
23
  free: s[:block_size] * s[:block_free],
26
- used: s[:blocks].-(s[:block_free]) * s[:block_size],
24
+ used: s[:blocks].-(s[:block_free]) * s[:block_size]
27
25
  }
28
26
  end
29
27
 
@@ -83,11 +81,11 @@ module LinuxStat
83
81
  # Where fs is the directory of the file system (like / or /tmp/ or /run/media/thumbdrive).
84
82
  #
85
83
  # It returns a Hash with the following data (for example):
86
- # {:block_size=>4096, :fragment_size=>4096, :blocks=>29292283, :block_free=>10535967, :block_avail_unpriv=>10535967, :inodes=>58612160, :free_inodes=>56718550, :filesystem_id=>2050, :mount_flags=>1024, :max_filename_length=>255}
84
+ # {:block_size=>4096, :fragment_size=>4096, :blocks=>29292283, :block_free=>10535967, :block_avail_unpriv=>10535967, :inodes=>58612160, :free_inodes=>56718550, :filesystem_id=>2050, :mount_flags=>1024, :max_filename_length=>255}
87
85
  #
88
86
  # If the stat can't be acquired, this method will return an empty Hash.
89
- def stat_raw(fs = '/'.freeze)
90
- FS.stat(fs)
87
+ def stat_raw(fs = ?/.freeze)
88
+ LinuxStat::FS.stat(fs)
91
89
  end
92
90
  end
93
91
  end