class Duffy::System
Depending on your hardware, you may want to make decisions in your code. I use this to figure out how many processes I can launch in parallel.
Public Class Methods
The battery percentage 0.0 .. 100.0 nil if no battery or error reading value. Darwin: pmset -g batt Linux:
# File lib/duffy/system.rb, line 99 def battery_percent case RUBY_PLATFORM when /darwin/ then `pmset -g batt`.scan(/^.*\t(.*%);/)[0][0].to_f when /linux/ then File.read("/sys/class/power_supply/BAT0/charge_now").to_i * 100 / File.read("/sys/class/power_supply/BAT0/charge_full").to_i else nil end rescue nil end
How many actual CPU cores do we have not including Hyperthreading Linux: “cpu cores” in cpuinfo is on a per physical processor basis, so we multiply by the number of CPUs Mac: hw.physicalcpu
# File lib/duffy/system.rb, line 22 def cores case RUBY_PLATFORM when /linux/ then File.read('/proc/cpuinfo').scan(/(cpu cores)(\D)*(\d+)/)[0][2].to_i * cpus when /darwin/ then `sysctl -n hw.physicalcpu`.to_i else 1 end rescue 1 end
The system's current CPU utilization. Darwin: Get a list of all processes' CPU percentage and add them up. Linux: Read /proc/stat twice and take the difference to give cpu time used in that interval.
# File lib/duffy/system.rb, line 62 def cpu_percent case RUBY_PLATFORM when /darwin/ then `ps -A -o %cpu`.lines.map(&:to_f).inject(:+) / threads when /linux/ then proc_diff else 0 end rescue 0 end
How many Physical CPUs do you have. Linux: Detected by counting unique physical IDs Mac: hw.packages
# File lib/duffy/system.rb, line 9 def cpus case RUBY_PLATFORM when /linux/ then File.read('/proc/cpuinfo').scan(/^physical id.*/).uniq.count when /darwin/ then `sysctl -n hw.packages`.to_i else 1 end rescue 1 end
Disk Freespace Looks at current working directory
# File lib/duffy/system.rb, line 74 def freespace case RUBY_PLATFORM when /darwin/ then `df -m #{Shellwords.shellescape(Dir.pwd)}`.lines[1].split[3].to_i when /linux/ then `df -m #{Shellwords.shellescape(Dir.pwd)}`.lines[1].split[3].to_i else 0 end end
Memory available for use in Megabytes Darwin: vm_stat (Pages Free + Pages Inactive) Linux: Read /proc/meminfo
# File lib/duffy/system.rb, line 112 def mem_available case RUBY_PLATFORM when /darwin/ then `vm_stat`.lines.grep(/(free:|inactive:)\s*(\d+)/){$2}.map(&:to_i).inject(:+) * 4 / 1024 when /linux/ then File.read("/proc/meminfo").lines.grep(/MemAvail|MemFree/).sort.first.split[1].to_i / 1024 else 0 end rescue 0 end
Percentage of Memory used, 0.0 .. 100.0
# File lib/duffy/system.rb, line 130 def mem_percent (100.0 * mem_used / mem_total).round(1) rescue 0 end
Total system memory in Megabytes Darwin: hw.memsize (bytes) Linux: Read /proc/meminfo
# File lib/duffy/system.rb, line 85 def mem_total case RUBY_PLATFORM when /darwin/ then `sysctl -n hw.memsize`.to_i / 1024 / 1024 when /linux/ then File.read("/proc/meminfo").scan(/MemTotal:\s*(\d+)/)[0][0].to_i / 1024 else 0 end rescue 0 end
Memory used Subtract mem_available
from mem_total. This ignores file cache etc that is not actually used by programs.
# File lib/duffy/system.rb, line 125 def mem_used mem_total - mem_available end
What is a sane number of threads to use for data processing. You want to leave some headroom for your database etc running in other processes.
# File lib/duffy/system.rb, line 55 def sane_load threads * 3 / 4 end
How many threads does the system have.
# File lib/duffy/system.rb, line 33 def threads case RUBY_PLATFORM when /linux/ then File.read('/proc/cpuinfo').scan(/^processor\s*:/).size when /darwin/ then `sysctl -n hw.ncpu`.to_i else 1 end rescue 1 end
# File lib/duffy/system.rb, line 43 def virtual? case RUBY_PLATFORM when /linux/ then !!File.read('/proc/cpuinfo').scan(/^flags.*(hypervisor)/)[0] when /darwin/ then false # PENDING else false end rescue false end
Private Class Methods
Poll proc_stat
twice and find the usage in that time. Higher Sleep is more accurate, but obviously slower. LINUX
# File lib/duffy/system.rb, line 149 def proc_diff s = proc_stat sleep 0.2 f = proc_stat (f[0] - s[0]) * 100.0 / (f[1] - s[1]) end
- CPU USE, CPU IDLE
-
LINUX
# File lib/duffy/system.rb, line 141 def proc_stat cpu = File.open("/proc/stat", "r").read.lines.first [cpu.split[1..3].map(&:to_i).inject(:+), cpu.split[1..4].map(&:to_i).inject(:+)] end