Class: PSI::Reading

Inherits:
Object
  • Object
show all
Defined in:
lib/psi/reading.rb

Overview

A snapshot read from one PSI resource.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource:, some:, full:, read_at:, metrics: nil) ⇒ Reading

Returns a new instance of Reading.



62
63
64
65
66
67
68
# File 'lib/psi/reading.rb', line 62

def initialize(resource:, some:, full:, read_at:, metrics: nil)
  @resource = resource
  @some = some
  @full = full
  @read_at = read_at
  @metrics = (metrics || { some: some, full: full }.compact).freeze
end

Instance Attribute Details

#fullObject (readonly)

Returns the value of attribute full.



36
37
38
# File 'lib/psi/reading.rb', line 36

def full
  @full
end

#metricsObject (readonly)

Returns the value of attribute metrics.



36
37
38
# File 'lib/psi/reading.rb', line 36

def metrics
  @metrics
end

#read_atObject (readonly)

Returns the value of attribute read_at.



36
37
38
# File 'lib/psi/reading.rb', line 36

def read_at
  @read_at
end

#resourceObject (readonly)

Returns the value of attribute resource.



36
37
38
# File 'lib/psi/reading.rb', line 36

def resource
  @resource
end

#someObject (readonly)

Returns the value of attribute some.



36
37
38
# File 'lib/psi/reading.rb', line 36

def some
  @some
end

Class Method Details

.parse(resource, text, read_at: Time.now) ⇒ Reading

Parses the contents of a Linux pressure file.

Parameters:

  • resource (Symbol)
  • text (String)
  • read_at (Time) (defaults to: Time.now)

Returns:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/psi/reading.rb', line 43

def self.parse(resource, text, read_at: Time.now)
  metrics = text.each_line.filter_map do |line|
    kind, *fields = line.split
    next unless kind

    values = fields.filter_map { |field| field.split("=", 2) if field.include?("=") }.to_h
    next unless %w[some full].include?(kind) || values.key?("total")

    averages = values.filter_map do |key, value|
      [Integer(key.delete_prefix("avg")), Float(value)] if key.match?(/\Aavg\d+\z/)
    end.to_h
    [kind.to_sym, Metrics.new(averages: averages, total: Integer(values.fetch("total")))]
  end.to_h

  new(resource: resource, some: metrics[:some], full: metrics[:full], read_at: read_at, metrics: metrics)
rescue ArgumentError, KeyError => e
  raise Error, "invalid PSI data: #{e.message}"
end