Skip to content

Commit

Permalink
Cherry-pick #21113 to 7.x: libbeat/cmd/instance: report cgroup stats (#…
Browse files Browse the repository at this point in the history
…21334)

* libbeat/cmd/instance: report cgroup stats (#21113)

* libbeat/cmd/instance: report cgroup stats

(cherry picked from commit b4c7a93)

* Fix panic in cgroups monitoring

Gosigar's cgroups GetStatsForProcesses can return a nil Stats pointer
and no error when the ["blkio", "cpu", "cpuacct", "memory"] subsystems
are on the root cgroup.

Related #21113

Co-authored-by: Adrian Serrano <[email protected]>
  • Loading branch information
axw and adriansr authored Sep 30, 2020
1 parent a5613d2 commit 8f4d194
Showing 1 changed file with 88 additions and 2 deletions.
90 changes: 88 additions & 2 deletions libbeat/cmd/instance/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/elastic/beats/v7/libbeat/metric/system/cpu"
"github.com/elastic/beats/v7/libbeat/metric/system/process"
"github.com/elastic/beats/v7/libbeat/monitoring"
"github.com/elastic/gosigar/cgroup"
)

var (
Expand Down Expand Up @@ -65,10 +66,15 @@ func setupMetrics(name string) error {
}

func setupPlatformSpecificMetrics() {
switch runtime.GOOS {
case "linux":
monitoring.NewFunc(beatMetrics, "cgroup", reportBeatCgroups, monitoring.Report)
case "windows":
setupWindowsHandlesMetrics()
}

if runtime.GOOS != "windows" {
monitoring.NewFunc(systemMetrics, "load", reportSystemLoadAverage, monitoring.Report)
} else {
setupWindowsHandlesMetrics()
}

setupLinuxBSDFDMetrics()
Expand Down Expand Up @@ -254,3 +260,83 @@ func reportRuntime(_ monitoring.Mode, V monitoring.Visitor) {

monitoring.ReportInt(V, "goroutines", int64(runtime.NumGoroutine()))
}

func reportBeatCgroups(_ monitoring.Mode, V monitoring.Visitor) {
V.OnRegistryStart()
defer V.OnRegistryFinished()

pid, err := process.GetSelfPid()
if err != nil {
logp.Err("error getting PID for self process: %v", err)
return
}

cgroups, err := cgroup.NewReader("", true)
if err != nil {
if err == cgroup.ErrCgroupsMissing {
logp.Warn("cgroup data collection disabled: %v", err)
} else {
logp.Err("cgroup data collection disabled: %v", err)
}
return
}
selfStats, err := cgroups.GetStatsForProcess(pid)
if err != nil {
logp.Err("error getting group status: %v", err)
return
}
// GetStatsForProcess returns a nil selfStats and no error when there's no stats
if selfStats == nil {
return
}

if cpu := selfStats.CPU; cpu != nil {
monitoring.ReportNamespace(V, "cpu", func() {
if cpu.ID != "" {
monitoring.ReportString(V, "id", cpu.ID)
}
monitoring.ReportNamespace(V, "cfs", func() {
monitoring.ReportNamespace(V, "period", func() {
monitoring.ReportInt(V, "us", int64(cpu.CFS.PeriodMicros))
})
monitoring.ReportNamespace(V, "quota", func() {
monitoring.ReportInt(V, "us", int64(cpu.CFS.QuotaMicros))
})
})
monitoring.ReportNamespace(V, "stats", func() {
monitoring.ReportInt(V, "periods", int64(cpu.Stats.Periods))
monitoring.ReportNamespace(V, "throttled", func() {
monitoring.ReportInt(V, "periods", int64(cpu.Stats.ThrottledPeriods))
monitoring.ReportInt(V, "ns", int64(cpu.Stats.ThrottledTimeNanos))
})
})
})
}

if cpuacct := selfStats.CPUAccounting; cpuacct != nil {
monitoring.ReportNamespace(V, "cpuacct", func() {
if cpuacct.ID != "" {
monitoring.ReportString(V, "id", cpuacct.ID)
}
monitoring.ReportNamespace(V, "total", func() {
monitoring.ReportInt(V, "ns", int64(cpuacct.TotalNanos))
})
})
}

if memory := selfStats.Memory; memory != nil {
monitoring.ReportNamespace(V, "memory", func() {
if memory.ID != "" {
monitoring.ReportString(V, "id", memory.ID)
}
monitoring.ReportNamespace(V, "mem", func() {
monitoring.ReportNamespace(V, "limit", func() {
monitoring.ReportInt(V, "bytes", int64(memory.Mem.Limit))
})
monitoring.ReportNamespace(V, "usage", func() {
monitoring.ReportInt(V, "bytes", int64(memory.Mem.Usage))
})
})
})
}
}

0 comments on commit 8f4d194

Please sign in to comment.