Merge pull request #719 from rjnagal/summary
Add cgroup info and links to the process list on root page.
This commit is contained in:
commit
6abaa07e63
@ -181,5 +181,6 @@ type ProcessInfo struct {
|
||||
VirtualSize uint64 `json:"virtual_size"`
|
||||
Status string `json:"status"`
|
||||
RunningTime string `json:"running_time"`
|
||||
CgroupPath string `json:"cgroup_path"`
|
||||
Cmd string `json:"cmd"`
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -41,6 +42,8 @@ var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second,
|
||||
var maxHousekeepingInterval = flag.Duration("max_housekeeping_interval", 60*time.Second, "Largest interval to allow between container housekeepings")
|
||||
var allowDynamicHousekeeping = flag.Bool("allow_dynamic_housekeeping", true, "Whether to allow the housekeeping interval to be dynamic")
|
||||
|
||||
var cgroupPathRegExp = regexp.MustCompile(".*:devices:(.*?),.*")
|
||||
|
||||
// Decay value used for load average smoothing. Interval length of 10 seconds is used.
|
||||
var loadDecay = math.Exp(float64(-1 * (*HousekeepingInterval).Seconds() / 10))
|
||||
|
||||
@ -116,6 +119,19 @@ func (c *containerData) DerivedStats() (v2.DerivedStats, error) {
|
||||
return c.summaryReader.DerivedStats()
|
||||
}
|
||||
|
||||
func (c *containerData) getCgroupPath(cgroups string) (string, error) {
|
||||
if cgroups == "-" {
|
||||
return "/", nil
|
||||
}
|
||||
matches := cgroupPathRegExp.FindSubmatch([]byte(cgroups))
|
||||
if len(matches) != 2 {
|
||||
glog.V(3).Infof("failed to get devices cgroup path from %q", cgroups)
|
||||
// return root in case of failures - devices hierarchy might not be enabled.
|
||||
return "/", nil
|
||||
}
|
||||
return string(matches[1]), nil
|
||||
}
|
||||
|
||||
func (c *containerData) GetProcessList() ([]v2.ProcessInfo, error) {
|
||||
// report all processes for root.
|
||||
isRoot := c.info.Name == "/"
|
||||
@ -130,9 +146,9 @@ func (c *containerData) GetProcessList() ([]v2.ProcessInfo, error) {
|
||||
}
|
||||
}
|
||||
// TODO(rjnagal): Take format as an option?
|
||||
format := "user,pid,ppid,stime,pcpu,pmem,rss,vsz,stat,time,comm"
|
||||
format := "user,pid,ppid,stime,pcpu,pmem,rss,vsz,stat,time,comm,cgroup"
|
||||
args := []string{"-e", "-o", format}
|
||||
expectedFields := 11
|
||||
expectedFields := 12
|
||||
out, err := exec.Command("ps", args...).Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute ps command: %v", err)
|
||||
@ -171,6 +187,14 @@ func (c *containerData) GetProcessList() ([]v2.ProcessInfo, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid virtual size %q: %v", fields[7], err)
|
||||
}
|
||||
var cgroupPath string
|
||||
if isRoot {
|
||||
cgroupPath, err = c.getCgroupPath(fields[11])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse cgroup path from %q: %v", fields[10], err)
|
||||
}
|
||||
}
|
||||
|
||||
if isRoot || pidMap[pid] == true {
|
||||
processes = append(processes, v2.ProcessInfo{
|
||||
User: fields[0],
|
||||
@ -183,7 +207,8 @@ func (c *containerData) GetProcessList() ([]v2.ProcessInfo, error) {
|
||||
VirtualSize: vs,
|
||||
Status: fields[8],
|
||||
RunningTime: fields[9],
|
||||
Cmd: strings.Join(fields[10:], " "),
|
||||
Cmd: fields[10],
|
||||
CgroupPath: cgroupPath,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ const containersHtmlTemplate = `
|
||||
{{end}}
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
startPage({{.ContainerName}}, {{.CpuAvailable}}, {{.MemoryAvailable}}, {{.Root}});
|
||||
startPage({{.ContainerName}}, {{.CpuAvailable}}, {{.MemoryAvailable}}, {{.Root}}, {{.IsRoot}});
|
||||
drawImages({{.DockerImages}});
|
||||
</script>
|
||||
</body>
|
||||
|
@ -462,12 +462,16 @@ function drawImages(images) {
|
||||
drawTable(titles, titleTypes, data, "docker-images", 30);
|
||||
}
|
||||
|
||||
function drawProcesses(processInfo) {
|
||||
function drawProcesses(isRoot, rootDir, processInfo) {
|
||||
if (processInfo.length == 0) {
|
||||
return;
|
||||
}
|
||||
var titles = ["User", "PID", "PPID", "Start Time", "CPU %", "MEM %", "RSS", "Virtual Size", "Status", "Running Time", "Command"];
|
||||
var titleTypes = ['string', 'number', 'number', 'string', 'number', 'number', 'number', 'number', 'string', 'string', 'string'];
|
||||
if (isRoot) {
|
||||
titles.push("Cgroup");
|
||||
titleTypes.push('string');
|
||||
}
|
||||
var data = []
|
||||
for (var i = 0; i < processInfo.length; i++) {
|
||||
var elements = [];
|
||||
@ -482,6 +486,12 @@ function drawProcesses(processInfo) {
|
||||
elements.push(processInfo[i].status);
|
||||
elements.push(processInfo[i].running_time);
|
||||
elements.push(processInfo[i].cmd);
|
||||
if (isRoot) {
|
||||
var cgroup = processInfo[i].cgroup_path
|
||||
// Use the raw cgroup link as it works for all containers.
|
||||
var cgroupLink = '<a href="' + rootDir + 'containers/' + cgroup +'">' + cgroup.substr(0,30) + ' </a>';
|
||||
elements.push({v:cgroup, f:cgroupLink});
|
||||
}
|
||||
data.push(elements);
|
||||
}
|
||||
drawTable(titles, titleTypes, data, "processes-top", 25);
|
||||
@ -600,7 +610,7 @@ function drawCharts(machineInfo, containerInfo) {
|
||||
}
|
||||
|
||||
// Executed when the page finishes loading.
|
||||
function startPage(containerName, hasCpu, hasMemory, rootDir) {
|
||||
function startPage(containerName, hasCpu, hasMemory, rootDir, isRoot) {
|
||||
// Don't fetch data if we don't have any resource.
|
||||
if (!hasCpu && !hasMemory) {
|
||||
return;
|
||||
@ -612,11 +622,11 @@ function startPage(containerName, hasCpu, hasMemory, rootDir) {
|
||||
|
||||
// Draw process information at start and refresh every 60s.
|
||||
getProcessInfo(rootDir, containerName, function(processInfo) {
|
||||
drawProcesses(processInfo)
|
||||
drawProcesses(isRoot, rootDir, processInfo)
|
||||
});
|
||||
setInterval(function() {
|
||||
getProcessInfo(rootDir, containerName, function(processInfo) {
|
||||
drawProcesses(processInfo)
|
||||
drawProcesses(isRoot, rootDir, processInfo)
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user