Module: Datadog::Core::Environment::Cgroup

Defined in:
lib/datadog/core/environment/cgroup.rb

Overview

Reads information from Linux cgroups. This information is used to extract information about the current Linux container identity.

Defined Under Namespace

Classes: Entry

Class Method Summary collapse

Class Method Details

.entriesArray<Entry>

Parses the /proc/self/cgroup file,

Returns:

  • (Array<Entry>)

    one entry for each valid cgroup line



25
26
27
28
29
30
31
32
33
34
# File 'lib/datadog/core/environment/cgroup.rb', line 25

def entries
  filepath = '/proc/self/cgroup'
  return [] unless File.exist?(filepath)

  ret = []
  File.foreach(filepath) do |entry_line|
    ret << parse(entry_line) unless entry_line.empty?
  end
  ret
end

.inode_for(controllers, path) ⇒ Object

We can find the container inode by running a file stat on the cgroup filesystem path. Example:

For the entry `0:cpu:/docker/abc123`,
we read `stat -c '%i' /sys/fs/cgroup/cpu/docker/abc123`


63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/datadog/core/environment/cgroup.rb', line 63

def inode_for(controllers, path)
  return if controllers.nil? || path.nil?

  # In cgroup v1, when multiple controllers are co-mounted, the controllers
  # becomes part of the directory name (with commas preserved).
  # Example entry:
  #   For the line "10:cpu,cpuacct:/docker/abc123", the path is
  #   "/sys/fs/cgroup/cpu,cpuacct/docker/abc123"
  inode_path = File.join('/sys/fs/cgroup', controllers, path)

  File.stat(inode_path).ino if File.exist?(inode_path)
end

.parse(entry_line) ⇒ Entry

Parses a single cgroup entry from /proc/<pid>/cgroup.

Files can have cgroup v1 and v2 entries mixed. Their format is the same.

Each entry has 3 colon-separated fields:

hierarchy-ID:controllers:path

Examples:

10:memory:/docker/1234567890abcdef (cgroup v1)
0::/docker/1234567890abcdef (cgroup v2)


48
49
50
51
52
53
54
55
56
57
# File 'lib/datadog/core/environment/cgroup.rb', line 48

def parse(entry_line)
  hierarchy, controllers, path = entry_line.split(':', 3)

  Entry.new(
    hierarchy,
    controllers,
    path,
    inode_for(controllers, path)
  )
end