Class: OsCtl::Lib::LoadAvgReader

Inherits:
Object
  • Object
show all
Defined in:
lib/libosctl/loadavg_reader.rb

Overview

Reads and parses per-container load averages from LXCFS

Defined Under Namespace

Classes: LoadAvg

Constant Summary collapse

SYSTEM_LXCFS =
'/var/lib/lxcfs'
FILE =
'proc/.loadavgs'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.read_for(containers) ⇒ Hash<String, LoadAvg>

Read loadavgs for given containers and return them in a hash indexed by ctid

Parameters:

  • containers (Array<Hash>)

    list of containers as received from osctld

Returns:



20
21
22
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/libosctl/loadavg_reader.rb', line 20

def self.read_for(containers)
  reader = new
  lavgs = {}

  # First read from the system lxcfs instance
  # TODO: remove this in the future
  if Dir.exist?(File.join(SYSTEM_LXCFS, 'proc'))
    index = Hash[ containers.map { |ct| ["#{ct[:pool]}:#{ct[:id]}", true] } ]

    reader.read_lxcfs(SYSTEM_LXCFS) do |lavg|
      lavgs[ lavg.ident ] = lavg

      index.delete(lavg.ident)
      index.empty? ? :stop : nil
    end
  end

  lxcfs_workers = {}

  containers.each do |ct|
    mountpoint = ct[:lxcfs_mountpoint]
    next if mountpoint.nil?

    k = "#{ct[:pool]}:#{ct[:id]}"

    lxcfs_workers[mountpoint] ||= {}
    lxcfs_workers[mountpoint][k] = true
  end

  lxcfs_workers.each do |mountpoint, cts|
    reader.read_lxcfs(mountpoint) do |lavg|
      lavgs[ lavg.ident ] = lavg if cts.has_key?(lavg.ident)
    end
  end

  ret = {}

  containers.each do |ct|
    k = "#{ct[:pool]}:#{ct[:id]}"

    ret[k] = lavgs[k] if lavgs.has_key?(k)
  end

  ret
end

Instance Method Details

#parse(line) ⇒ Object (protected)



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/libosctl/loadavg_reader.rb', line 83

def parse(line)
  # <cgroup> <avg1> <avg5> <avg15> <runnable>/<total> <last_pid>
  cols = line.strip.split
  return if cols.size != 6

  pool, ctid = parse_ct(cols[0])
  return if pool.nil?

  runnable, total = cols[4].split('/').map(&:to_i)

  LoadAvg.new(
    pool,
    ctid,
    {1 => cols[1].to_f, 5 => cols[2].to_f, 15 => cols[3].to_f},
    runnable,
    total,
    cols[5].to_i
  )
end

#parse_ct(cgroup) ⇒ Object (protected)



103
104
105
106
107
108
109
110
111
# File 'lib/libosctl/loadavg_reader.rb', line 103

def parse_ct(cgroup)
  return if /^\/osctl\/pool\.([^\/]+)/ !~ cgroup
  pool = $1

  return if /ct\.([^\/]+)\/user\-owned\// !~ cgroup
  ct = $1

  [pool, ct]
end

#read_lxcfs(mountpoint) {|lavg| ... } ⇒ Object

Read load averages from LXCFS

Parameters:

  • mountpoint (String)

Yield Parameters:

Yield Returns:

  • (:stop, any)


70
71
72
73
74
75
76
77
78
79
80
# File 'lib/libosctl/loadavg_reader.rb', line 70

def read_lxcfs(mountpoint)
  File.open(File.join(mountpoint, FILE), 'r') do |f|
    f.each_line do |line|
      lavg = parse(line)
      next if lavg.nil?
      break if yield(lavg) == :stop
    end
  end

rescue Errno::ENOENT
end