Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gather file descriptors as process metric #961

Merged
merged 2 commits into from
Feb 17, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions client/app/scripts/utils/string-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ const formatters = {
return formatters.metric(obj.value, obj.suffix);
},

integer(value) {
if (value < 1100 && value >= 0) {
return Number(value).toFixed(0);
}
return formatLargeValue(value);
},

number(value) {
if (value < 1100 && value >= 0) {
return Number(value).toFixed(2);
Expand Down
16 changes: 9 additions & 7 deletions probe/process/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import (

// We use these keys in node metadata
const (
PID = "pid"
Name = "name"
PPID = "ppid"
Cmdline = "cmdline"
Threads = "threads"
CPUUsage = "process_cpu_usage_percent"
MemoryUsage = "process_memory_usage_bytes"
PID = "pid"
Name = "name"
PPID = "ppid"
Cmdline = "cmdline"
Threads = "threads"
CPUUsage = "process_cpu_usage_percent"
MemoryUsage = "process_memory_usage_bytes"
FileDescriptors = "file_descriptors"
)

// Reporter generates Reports containing the Process topology.
Expand Down Expand Up @@ -84,6 +85,7 @@ func (r *Reporter) processTopology() (report.Topology, error) {
}

node = node.WithMetric(MemoryUsage, report.MakeMetric().Add(now, float64(p.RSSBytes)))
node = node.WithMetric(FileDescriptors, report.MakeMetric().Add(now, float64(p.FileDescriptors)))

t.AddNode(nodeID, node)
})
Expand Down
13 changes: 7 additions & 6 deletions probe/process/walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import "sync"

// Process represents a single process.
type Process struct {
PID, PPID int
Name string
Cmdline string
Threads int
Jiffies uint64
RSSBytes uint64
PID, PPID int
Name string
Cmdline string
Threads int
Jiffies uint64
RSSBytes uint64
FileDescriptors int

This comment was marked as abuse.

}

// Walker is something that walks the /proc directory
Expand Down
25 changes: 18 additions & 7 deletions probe/process/walker_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func readStats(path string) (ppid, threads int, jiffies, rss uint64, err error)
return
}

func readFileDescriptors(path string) (int, error) {
names, err := fs.ReadDirNames(path)
return len(names), err
}

// Walk walks the supplied directory (expecting it to look like /proc)
// and marshalls the files into instances of Process, which it then
// passes one-by-one to the supplied function. Walk is only made public
Expand All @@ -83,6 +88,11 @@ func (w *walker) Walk(f func(Process, Process)) error {
continue
}

fileDescriptors, err := readFileDescriptors(path.Join(w.procRoot, filename, "fd"))

This comment was marked as abuse.

if err != nil {
continue
}

cmdline, name := "", "(unknown)"
if cmdlineBuf, err := cachedReadFile(path.Join(w.procRoot, filename, "cmdline")); err == nil {
// like proc, treat name as the first element of command line
Expand All @@ -96,13 +106,14 @@ func (w *walker) Walk(f func(Process, Process)) error {
}

f(Process{
PID: pid,
PPID: ppid,
Name: name,
Cmdline: cmdline,
Threads: threads,
Jiffies: jiffies,
RSSBytes: rss,
PID: pid,
PPID: ppid,
Name: name,
Cmdline: cmdline,
Threads: threads,
Jiffies: jiffies,
RSSBytes: rss,
FileDescriptors: fileDescriptors,
}, Process{})
}

Expand Down
12 changes: 8 additions & 4 deletions probe/process/walker_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var mockFS = fs.Dir("",
FName: "stat",
FContents: "3 na R 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0",
},
fs.Dir("fd", fs.File{FName: "0"}, fs.File{FName: "1"}, fs.File{FName: "2"}),
),
fs.Dir("2",
fs.File{
Expand All @@ -31,6 +32,7 @@ var mockFS = fs.Dir("",
FName: "stat",
FContents: "2 na R 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0",
},
fs.Dir("fd", fs.File{FName: "1"}, fs.File{FName: "2"}),
),
fs.Dir("4",
fs.File{
Expand All @@ -41,6 +43,7 @@ var mockFS = fs.Dir("",
FName: "stat",
FContents: "4 na R 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0",
},
fs.Dir("fd", fs.File{FName: "0"}),
),
fs.Dir("notapid"),
fs.Dir("1",
Expand All @@ -52,6 +55,7 @@ var mockFS = fs.Dir("",
FName: "stat",
FContents: "1 na R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0",
},
fs.Dir("fd"),
),
),
)
Expand All @@ -61,10 +65,10 @@ func TestWalker(t *testing.T) {
defer fs_hook.Restore()

want := map[int]process.Process{
3: {PID: 3, PPID: 2, Name: "curl", Cmdline: "curl google.com", Threads: 1},
2: {PID: 2, PPID: 1, Name: "bash", Cmdline: "bash", Threads: 1},
4: {PID: 4, PPID: 3, Name: "apache", Cmdline: "apache", Threads: 1},
1: {PID: 1, PPID: 0, Name: "init", Cmdline: "init", Threads: 1},
3: {PID: 3, PPID: 2, Name: "curl", Cmdline: "curl google.com", Threads: 1, FileDescriptors: 3},
2: {PID: 2, PPID: 1, Name: "bash", Cmdline: "bash", Threads: 1, FileDescriptors: 2},
4: {PID: 4, PPID: 3, Name: "apache", Cmdline: "apache", Threads: 1, FileDescriptors: 1},
1: {PID: 1, PPID: 0, Name: "init", Cmdline: "init", Threads: 1, FileDescriptors: 0},
}

have := map[int]process.Process{}
Expand Down
1 change: 1 addition & 0 deletions render/detailed/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var labels = map[string]string{
process.CPUUsage: "CPU",
process.Cmdline: "Command",
process.MemoryUsage: "Memory",
process.FileDescriptors: "Open Files",
process.PID: "PID",
process.PPID: "Parent PID",
process.Threads: "# Threads",
Expand Down
2 changes: 2 additions & 0 deletions render/detailed/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import (
const (
defaultFormat = ""
filesizeFormat = "filesize"
integerFormat = "integer"
percentFormat = "percent"
)

var (
processNodeMetrics = []MetricRow{
{ID: process.CPUUsage, Format: percentFormat},
{ID: process.MemoryUsage, Format: filesizeFormat},
{ID: process.FileDescriptors, Format: integerFormat},
}
containerNodeMetrics = []MetricRow{
{ID: docker.CPUTotalUsage, Format: percentFormat},
Expand Down