Module: PSI

Defined in:
lib/psi.rb,
lib/psi/event.rb,
lib/psi/monitor.rb,
lib/psi/reading.rb,
lib/psi/sampler.rb,
lib/psi/trigger.rb,
lib/psi/version.rb

Overview

Reads Linux Pressure Stall Information (PSI).

Defined Under Namespace

Classes: Delta, Error, Event, Metrics, Monitor, Reading, Sampler, Trigger, TriggerError, UnsupportedError

Constant Summary collapse

RESOURCES =

Resource names exposed by Linux PSI.

%i[cpu memory io irq].freeze
VERSION =

Current gem version.

"1.0.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.procfs_rootObject



25
26
27
# File 'lib/psi.rb', line 25

def procfs_root
  @procfs_root ||= "/proc"
end

Class Method Details

.current_cgroupString

Resolves this process's unified cgroup v2 directory.

Returns:

  • (String)


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

def current_cgroup
  entry = File.foreach(File.join(procfs_root, "self/cgroup")).find { |line| line.start_with?("0::") }
  raise UnsupportedError, "cgroup v2 is not mounted" unless entry

  File.join("/sys/fs/cgroup", entry.split("::", 2).last.strip.delete_prefix("/"))
rescue Errno::ENOENT => e
  raise UnsupportedError, e.message
end

.path_for(resource, cgroup: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Builds the backing file path for a resource.



71
72
73
74
75
76
# File 'lib/psi.rb', line 71

def path_for(resource, cgroup: nil)
  resource = validate_resource(resource)
  return File.join(cgroup, "#{resource}.pressure") if cgroup

  File.join(procfs_root, "pressure", resource.to_s)
end

.read(resource, cgroup: nil) ⇒ Reading

Reads one system-wide or cgroup pressure resource.

Parameters:

  • resource (Symbol, String)
  • cgroup (String, nil) (defaults to: nil)

    cgroup v2 directory, or nil for procfs

Returns:



43
44
45
46
47
48
# File 'lib/psi.rb', line 43

def read(resource, cgroup: nil)
  resource = validate_resource(resource)
  Reading.parse(resource, File.read(path_for(resource, cgroup: cgroup)))
rescue Errno::ENOENT, Errno::EOPNOTSUPP => e
  raise UnsupportedError, e.message
end

.read_all(cgroup: nil) ⇒ Hash{Symbol => Reading}

Reads every pressure resource available at the target location.

Parameters:

  • cgroup (String, nil) (defaults to: nil)

    cgroup v2 directory, or nil for procfs

Returns:



53
54
55
56
# File 'lib/psi.rb', line 53

def read_all(cgroup: nil)
  available = cgroup ? RESOURCES.select { |resource| File.file?(path_for(resource, cgroup: cgroup)) } : resources
  available.to_h { |resource| [resource, read(resource, cgroup: cgroup)] }
end

.resourcesArray<Symbol>

Returns resources available under the configured procfs root.

Returns:

  • (Array<Symbol>)


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

def resources
  RESOURCES.select { |resource| File.file?(path_for(resource)) }
end

.supported?Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/psi.rb', line 29

def supported?
  File.directory?(File.join(procfs_root, "pressure"))
end