Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ gem 'sinatra-contrib'
gem 'statsd-instrument', '~> 3.11'
gem 'talentbox-delayed_job_sequel', '~> 4.4.0'
gem 'uri', '~> 1.1'
gem 'vmstat', '~> 2.3'

# Rails Components
gem 'actionpack', '~> 8.1.2'
Expand Down
2 changes: 0 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,6 @@ GEM
unicode-emoji (4.2.0)
uri (1.1.1)
useragent (0.16.11)
vmstat (2.3.1)
webmock (3.26.2)
addressable (>= 2.8.0)
crack (>= 0.3.2)
Expand Down Expand Up @@ -505,7 +504,6 @@ DEPENDENCIES
talentbox-delayed_job_sequel (~> 4.4.0)
timecop
uri (~> 1.1)
vmstat (~> 2.3)
webmock (> 2.3.1)
webrick (~> 1.9.2)

Expand Down
25 changes: 19 additions & 6 deletions lib/vcap/stats.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require 'vcap/pid_file'
require 'vmstat'

module VCAP
class Stats
Expand All @@ -16,21 +15,35 @@ def process_memory_bytes_and_cpu
end

def memory_used_bytes
mem = Vmstat.memory
mem.active_bytes + mem.wired_bytes
return 0 unless linux?

(meminfo_kb('MemTotal') - meminfo_kb('Inactive') - meminfo_kb('MemFree')) * 1024
end

def memory_free_bytes
mem = Vmstat.memory
mem.inactive_bytes + mem.free_bytes
return 0 unless linux?

(meminfo_kb('Inactive') + meminfo_kb('MemFree')) * 1024
end

def cpu_load_average
Vmstat.load_average.one_minute
return 0 unless linux?

File.read('/proc/loadavg').split.first.to_f
end

private

def linux?
RUBY_PLATFORM.match?(/linux/)
end

# Reads a kB-valued field from /proc/meminfo (e.g. "MemTotal: 16793990 kB").
def meminfo_kb(key)
line = File.read('/proc/meminfo').lines.find { |l| l.start_with?("#{key}:") }
line ? line.split[1].to_i : 0
end

def ps_pid
`ps -o rss=,pcpu= -p #{Process.pid}`
end
Expand Down
58 changes: 58 additions & 0 deletions spec/unit/lib/vcap/stats_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,62 @@
expect(pcpu).to eq(17)
end
end

describe 'system metrics on Linux' do
let(:meminfo) do
<<~MEMINFO
MemTotal: 16793990 kB
MemFree: 10810368 kB
MemAvailable: 13636608 kB
Buffers: 455475 kB
Cached: 2707660 kB
Active: 920268 kB
Inactive: 4609024 kB
MEMINFO
end
let(:loadavg) { "1.37 1.21 1.05 2/512 12345\n" }

before do
allow(VCAP::Stats).to receive(:linux?).and_return(true)
allow(File).to receive(:read).and_call_original
allow(File).to receive(:read).with('/proc/meminfo').and_return(meminfo)
allow(File).to receive(:read).with('/proc/loadavg').and_return(loadavg)
end

describe '#memory_free_bytes' do
it 'returns (Inactive + MemFree) in bytes' do
expect(VCAP::Stats.memory_free_bytes).to eq((4_609_024 + 10_810_368) * 1024)
end
end

describe '#memory_used_bytes' do
it 'returns (MemTotal - Inactive - MemFree) in bytes' do
expect(VCAP::Stats.memory_used_bytes).to eq((16_793_990 - 4_609_024 - 10_810_368) * 1024)
end
end

describe '#cpu_load_average' do
it 'returns the one-minute load as a float' do
expect(VCAP::Stats.cpu_load_average).to eq(1.37)
end
end
end

describe 'system metrics on non-Linux' do
before do
allow(VCAP::Stats).to receive(:linux?).and_return(false)
end

it 'returns 0 for memory_used_bytes' do
expect(VCAP::Stats.memory_used_bytes).to eq(0)
end

it 'returns 0 for memory_free_bytes' do
expect(VCAP::Stats.memory_free_bytes).to eq(0)
end

it 'returns 0 for cpu_load_average' do
expect(VCAP::Stats.cpu_load_average).to eq(0)
end
end
end
Loading