Module: LinuxStat::CPU
- Defined in:
- lib/linux_stat/cpu.rb
Class Method Summary collapse
-
.available_governors ⇒ Object
Returns an array of governors for each CPU as a Hash.
-
.count ⇒ Object
Returns the total number of CPU available for the sysetm.
-
.count_online ⇒ Object
Returns the total number of CPU online in the sysetm.
-
.cur_freq ⇒ Object
Returns a Hash with current core frequencies corresponding to the CPUs.
-
.governor ⇒ Object
Returns the corresponding governor of each CPU.
-
.max_freq ⇒ Object
Returns a Hash with max core frequencies corresponding to the CPUs.
-
.min_freq ⇒ Object
Returns a Hash with max core frequencies corresponding to the CPUs.
-
.model ⇒ Object
Returns the model of processor.
-
.offline ⇒ Object
Returns the total number of CPU offline in the sysetm.
-
.online ⇒ Object
Returns the total number of CPU online in the sysetm.
-
.stat(sleep = ticks_to_ms_t5) ⇒ Object
(also: usages)
stat(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck * 5).
-
.total_usage(sleep = ticks_to_ms_t5) ⇒ Object
(also: usage)
total_usage(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck).
Class Method Details
.available_governors ⇒ Object
Returns an array of governors for each CPU as a Hash.
For example:
LinuxStat::CPU.available_governors
=> {"cpu0"=>["performance", "powersave"], "cpu1"=>["performance", "powersave"], "cpu2"=>["performance", "powersave"], "cpu3"=>["performance", "powersave"]}
If the information isn’t available, it will return an empty Hash.
287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/linux_stat/cpu.rb', line 287 def available_governors @@scaling_av_g ||= cpus.map { |x| [File.split(x)[-1], File.join(x, 'cpufreq/scaling_available_governors'.freeze)] } h = {} @@scaling_av_g.each { |id, file| h.merge!(id => IO.read(file).split.each(&:strip!)) if File.readable?(file) } h end |
.count ⇒ Object
Returns the total number of CPU available for the sysetm.
It returns an Integer.
If the information isn’t available, it will return nil.
86 87 88 |
# File 'lib/linux_stat/cpu.rb', line 86 def count @@cpu_count ||= LinuxStat::Sysconf.processor_configured end |
.count_online ⇒ Object
Returns the total number of CPU online in the sysetm.
It first reads /proc/stat, if that fails, it will read /sys/devices/system/cpu/online, if that fails it will open /proc/cpuinfo. If neither of the procedures work, it will get the LinuxStat::Sysconf.processor_online
It opens /sys/devices/system/cpu/offline and performs various job to get one Ruby array.
If the information isn’t available, it will return an empty Array.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/linux_stat/cpu.rb', line 103 def count_online @@cpuinfo_file ||= '/proc/cpuinfo'.freeze @@cpuinfo_readable ||= File.readable?(@@cpuinfo_file) @@stat_file ||= '/proc/stat'.freeze # Not much slow, not blazing fast, somewhat reliable get_online = online if !get_online.empty? get_online.length elsif @@cpuinfo_readable # Way slower but reliable! IO.readlines(@@cpuinfo_file).count { |x| x.strip[/\Aprocessor.*\d*\z/] } else # Way faster but absolutely unrealiable! LinuxStat::Sysconf.processor_online end end |
.cur_freq ⇒ Object
Returns a Hash with current core frequencies corresponding to the CPUs.
For example:
LinuxStat::CPU.cur_freq
=> {"cpu0"=>1999990, "cpu1"=>2000042, "cpu2"=>2000016, "cpu3"=>2000088}
If the information isn’t available, it will return an empty Hash.
197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/linux_stat/cpu.rb', line 197 def cur_freq @@cur_f ||= cpus.map { |x| [File.split(x)[-1], File.join(x, 'cpufreq/scaling_cur_freq'.freeze)] } h = {} @@cur_f.each { |id, file| h.merge!(id => IO.read(file).to_i) if File.readable?(file) } h end |
.governor ⇒ Object
Returns the corresponding governor of each CPU.
The return type is a Hash.
For example:
LinuxStat::CPU.governor
=> {"cpu0"=>"powersave", "cpu1"=>"powersave", "cpu2"=>"performance", "cpu3"=>"performance"}
If the information isn’t available, it will return an empty Hash.
265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/linux_stat/cpu.rb', line 265 def governor @@scaling_g ||= cpus.map { |x| [File.split(x)[-1], File.join(x, 'cpufreq/scaling_governor'.freeze)] } h = {} @@scaling_g.each { |id, file| h.merge!(id => IO.read(file).tap(&:strip!)) if File.readable?(file) } h end |
.max_freq ⇒ Object
Returns a Hash with max core frequencies corresponding to the CPUs.
For example:
LinuxStat::CPU.max_freq
=> {"cpu0"=>2000000, "cpu1"=>2000000, "cpu2"=>2000000, "cpu3"=>2000000}
If the information isn’t available, it will return an empty Hash.
241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/linux_stat/cpu.rb', line 241 def max_freq @@min_f ||= cpus.map { |x| [File.split(x)[-1], File.join(x, 'cpufreq/scaling_max_freq'.freeze)] } h = {} @@min_f.each { |id, file| h.merge!(id => IO.read(file).to_i) if File.readable?(file) } h end |
.min_freq ⇒ Object
Returns a Hash with max core frequencies corresponding to the CPUs.
For example:
LinuxStat::CPU.min_freq
=> {"cpu0"=>2000000, "cpu1"=>2000000, "cpu2"=>2000000, "cpu3"=>2000000}
If the information isn’t available, it will return an empty Hash.
219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/linux_stat/cpu.rb', line 219 def min_freq @@min_f ||= cpus.map { |x| [File.split(x)[-1], File.join(x, 'cpufreq/scaling_min_freq'.freeze)] } h = {} @@min_f.each { |id, file| h.merge!(id => IO.read(file).to_i) if File.readable?(file) } h end |
.model ⇒ Object
Returns the model of processor.
If the information isn’t available, it will return en empty string.
The output is also cached (memoized) ; as changing the value in runtime is unexpected.
184 185 186 |
# File 'lib/linux_stat/cpu.rb', line 184 def model @@name ||= cpuinfo.find { |x| x.start_with?('model name') }.to_s.split(?:)[-1].to_s.strip end |
.offline ⇒ Object
Returns the total number of CPU offline in the sysetm.
It opens /sys/devices/system/cpu/offline and performs various job to get one Ruby array.
If the information isn’t available, it will return an empty Array.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/linux_stat/cpu.rb', line 163 def offline @@offline_file ||= '/sys/devices/system/cpu/offline'.freeze @@offline_readable ||= File.readable?(@@offline_file) return [] unless @@offline_readable ret = [] IO.read(@@offline_file).split(?,.freeze).each { |x| x.strip! c = x.split(?-.freeze).map(&:to_i) ret.concat(c.length == 2 ? Range.new(*c).to_a : c) } ret end |
.online ⇒ Object
Returns the total number of CPU online in the sysetm.
It will read /proc/stat to get the info.
If the info isn’t available, it reads /sys/devices/system/cpu/onfline and performs various job to get one Ruby array.
If the information isn’t available, it will return an empty Array.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/linux_stat/cpu.rb', line 132 def online @@online_file ||= '/sys/devices/system/cpu/online'.freeze @@online_readable ||= File.readable?(@@online_file) @@stat_file ||= '/proc/stat'.freeze ret = [] if stat? IO.readlines(@@stat_file).map { |x| v = x.strip[/\Acpu\d*/] &.[](/\d/) ret << v.to_i if v } elsif @@online_readable IO.read(@@online_file).split(?,.freeze).each { |x| x.strip! c = x.split(?-.freeze).map(&:to_i) ret.concat(c.length == 2 ? Range.new(*c).to_a : c) } end ret end |
.stat(sleep = ticks_to_ms_t5) ⇒ Object Also known as: usages
stat(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck * 5)
Where sleep is the delay to gather the data.
The minimum possible value at anytime is 1.0 / LinuxStat::Sysconf.sc_clk_tck
This method returns the cpu usage of all threads.
The first one is aggregated CPU usage reported by the Linux kernel.
And the consecutive ones are the real core usages.
For example, on a system with 4 threads:
LinuxStat::CPU.stat
=> {0=>84.38, 1=>100.0, 2=>50.0, 3=>87.5, 4=>87.5}
If the information is not available, it will return an empty Hash
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/linux_stat/cpu.rb', line 23 def stat(sleep = ticks_to_ms_t5) return {} unless stat? data = IO.readlines('/proc/stat'.freeze).select { |x| x[/^cpu\d*/] }.map! { |x| x.split.map!(&:to_f) } sleep(sleep) data2 = IO.readlines('/proc/stat'.freeze).select { |x| x[/^cpu\d*/] }.map! { |x| x.split.map!(&:to_f) } # On devices like android, the core count can change anytime (hotplugging). # I had crashes on Termux. # So better just count the min number of CPU and iterate over that # If data.length is smaller than data2.length, we don't have enough data to compare. dl, d2l = data.length, data2.length min = dl > d2l ? d2l : dl min.times.reduce({}) do |h, x| user, nice, sys, idle, iowait, irq, softirq, steal = *data[x].drop(1) user2, nice2, sys2, idle2, iowait2, irq2, softirq2, steal2 = *data2[x].drop(1) idle_then, idle_now = idle + iowait, idle2 + iowait2 totald = idle_now.+(user2 + nice2 + sys2 + irq2 + softirq2 + steal2) - idle_then.+(user + nice + sys + irq + softirq + steal) res = totald.-(idle_now - idle_then).fdiv(totald).abs.*(100) res = res.nan? ? 0.0 : res > 100 ? 100.0 : res.round(2) h.merge!( x => res ) end end |
.total_usage(sleep = ticks_to_ms_t5) ⇒ Object Also known as: usage
total_usage(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck)
Where sleep is the delay to gather the data.
The minimum possible value at anytime is 1.0 / LinuxStat::Sysconf.sc_clk_tck
This method returns the cpu usage of all threads.
It’s like running LinuxStat::CPU.stat but it’s much more efficient and calculates just the aggregated usage which is available at the top of the /proc/stat file.
If the information is not available, it will return nil.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/linux_stat/cpu.rb', line 63 def total_usage(sleep = ticks_to_ms_t5) return nil unless stat? data = IO.foreach('/proc/stat'.freeze).first.split.tap(&:shift).map!(&:to_f) sleep(sleep) data2 = IO.foreach('/proc/stat'.freeze).first.split.tap(&:shift).map!(&:to_f) user, nice, sys, idle, iowait, irq, softirq, steal = *data user2, nice2, sys2, idle2, iowait2, irq2, softirq2, steal2 = *data2 idle_then, idle_now = idle + iowait, idle2 + iowait2 totald = idle_now.+(user2 + nice2 + sys2 + irq2 + softirq2 + steal2) - idle_then.+(user + nice + sys + irq + softirq + steal) u = totald.-(idle_now - idle_then).fdiv(totald).abs.*(100) u > 100 ? 100.0 : u.round(2) end |