class Processor
Computes interval CPU utilization from cumulative process metrics.
Nested
Definitions
Snapshot = Struct.new(:start_time, :processor_time, :timestamp)
- private
Signature
- private
def initialize(capture: General.method(:capture))
Initialize a process metrics sampler.
Signature
-
parameter
captureInterface(:call) The process snapshot capture callable.
Implementation
def initialize(capture: General.method(:capture))
@capture = capture
@snapshots = {}
end
def sample(process_ids)
Sample CPU utilization for the given processes. The first observation of each process establishes a baseline and does not produce a sample.
Signature
-
parameter
process_idsInteger | Array(Integer) The process IDs to sample.
-
returns
Hash(Integer, Processor::Sample) The valid interval samples keyed by process ID.
Implementation
def sample(process_ids)
processes = @capture.call(pid: process_ids, memory: false)
timestamp = now
return {} unless finite?(timestamp)
samples = {}
snapshots = {}
processes.each do |process_id, process|
start_time = process.start_time
processor_time = process.processor_time
next unless finite?(start_time) && finite?(processor_time)
current = Snapshot.new(start_time, processor_time, timestamp)
snapshots[process_id] = current
if previous = @snapshots[process_id]
next unless previous.start_time == current.start_time
duration = current.timestamp - previous.timestamp
processor_time = current.processor_time - previous.processor_time
next unless finite?(duration) && duration > 0.0
next unless finite?(processor_time) && processor_time >= 0.0
utilization = processor_time / duration
next unless finite?(utilization)
samples[process_id] = Sample.new(process_id, duration, processor_time, utilization).freeze
end
end
@snapshots = snapshots
return samples
end
def now
Get the current monotonic time.
Implementation
def now
Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
def finite?(value)
Whether the value is a finite number.
Implementation
def finite?(value)
value.is_a?(Numeric) && value.finite?
end