Skip to content

Commit

Permalink
Add template option for Cgroups (ncabatoff#199)
Browse files Browse the repository at this point in the history
Add template tag for Cgroups.  If the cgroup is not available, we simply return an empty array as this
can commonly happen on older kernels using the v1 cgroups (found at `/proc/self/cgroups` instead of `/proc/self/cgroup`).

Co-authored-by: Nathan Monfils <[email protected]>
Co-authored-by: Nathan Monfils <[email protected]>
  • Loading branch information
3 people authored Oct 28, 2021
1 parent 934d2ed commit 146e0df
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 2 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ Template variables available:
will only contain a single process.
- `{{.StartTime}}` contains the start time of the process. This can be useful
in conjunction with PID because PIDs get reused over time.
- `{{.Cgroups}}` contains (if supported) the cgroups of the process
(`/proc/self/cgroup`). This is particularly useful for identifying to which container
a process belongs.

Using `PID` or `StartTime` is discouraged: this is almost never what you want,
and is likely to result in high cardinality metrics which Prometheus will have
Expand Down
1 change: 1 addition & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type (
ProcAttributes struct {
Name string
Cmdline []string
Cgroups []string
Username string
PID int
StartTime time.Time
Expand Down
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type (
}

templateParams struct {
Cgroups []string
Comm string
ExeBase string
ExeFull string
Expand Down Expand Up @@ -116,6 +117,7 @@ func (m *matchNamer) MatchAndName(nacl common.ProcAttributes) (bool, string) {
var buf bytes.Buffer
m.template.Execute(&buf, &templateParams{
Comm: nacl.Name,
Cgroups: nacl.Cgroups,
ExeBase: exebase,
ExeFull: exefull,
Matches: matches,
Expand Down
1 change: 1 addition & 0 deletions fixtures/14804/cgroup
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0::/system.slice/docker-8dde0b0d6e919baef8d635cd9399b22639ed1e400eaec1b1cb94ff3b216cf3c3.scope
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/prometheus/client_golang v1.11.0
github.com/prometheus/common v0.26.0
github.com/prometheus/procfs v0.6.0
github.com/prometheus/procfs v0.7.1
github.com/rogpeppe/go-internal v1.8.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/yaml.v2 v2.4.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULU
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.1 h1:TlEtJq5GvGqMykEwWzbZWjjztF86swFhsPix1i0bkgA=
github.com/prometheus/procfs v0.7.1/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down
2 changes: 1 addition & 1 deletion proc/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (n namer) MatchAndName(nacl common.ProcAttributes) (bool, string) {

func newProcIDStatic(pid, ppid int, startTime uint64, name string, cmdline []string) (ID, Static) {
return ID{pid, startTime},
Static{name, cmdline, ppid, time.Unix(int64(startTime), 0).UTC(), 1000}
Static{name, cmdline, []string{}, ppid, time.Unix(int64(startTime), 0).UTC(), 1000}
}

func newProc(pid int, name string, m Metrics) IDInfo {
Expand Down
28 changes: 28 additions & 0 deletions proc/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type (
Static struct {
Name string
Cmdline []string
Cgroups []string
ParentPid int
StartTime time.Time
EffectiveUID int
Expand Down Expand Up @@ -135,6 +136,7 @@ type (
stat *procfs.ProcStat
status *procfs.ProcStatus
cmdline []string
cgroups []procfs.Cgroup
io *procfs.ProcIO
fs *FS
wchan *string
Expand Down Expand Up @@ -299,6 +301,18 @@ func (p *proccache) getStatus() (procfs.ProcStatus, error) {
return *p.status, nil
}

func (p *proccache) getCgroups() ([]procfs.Cgroup, error) {
if p.cgroups == nil {
cgroups, err := p.Proc.Cgroups()
if err != nil {
return nil, err
}
p.cgroups = cgroups
}

return p.cgroups, nil
}

// GetProcID implements Proc.
func (p *proccache) GetProcID() (ID, error) {
if p.procid == nil {
Expand Down Expand Up @@ -367,6 +381,19 @@ func (p *proccache) GetStatic() (Static, error) {
return Static{}, err
}

// /proc/<pid>/cgroup(s) is normally world-readable.
// However cgroups aren't always supported -> return an empty array in that
// case.
cgroups, err := p.getCgroups()
var cgroupsStr []string
if err != nil {
cgroupsStr = []string{}
} else {
for _, c := range cgroups {
cgroupsStr = append(cgroupsStr, c.Path)
}
}

effectiveUID, err := strconv.ParseInt(status.UIDs[1], 10, 64)
if err != nil {
return Static{}, err
Expand All @@ -375,6 +402,7 @@ func (p *proccache) GetStatic() (Static, error) {
return Static{
Name: stat.Comm,
Cmdline: cmdline,
Cgroups: cgroupsStr,
ParentPid: stat.PPID,
StartTime: startTime,
EffectiveUID: int(effectiveUID),
Expand Down
1 change: 1 addition & 0 deletions proc/read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func TestReadFixture(t *testing.T) {
wantstatic := Static{
Name: "process-exporte",
Cmdline: []string{"./process-exporter", "-procnames", "bash"},
Cgroups: []string{"/system.slice/docker-8dde0b0d6e919baef8d635cd9399b22639ed1e400eaec1b1cb94ff3b216cf3c3.scope"},
ParentPid: 10884,
StartTime: stime,
EffectiveUID: 1000,
Expand Down
1 change: 1 addition & 0 deletions proc/tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ func (t *Tracker) Update(iter Iter) (CollectErrors, []Update, error) {
nacl := common.ProcAttributes{
Name: idinfo.Name,
Cmdline: idinfo.Cmdline,
Cgroups: idinfo.Cgroups,
Username: t.lookupUid(idinfo.EffectiveUID),
PID: idinfo.Pid,
StartTime: idinfo.StartTime,
Expand Down

0 comments on commit 146e0df

Please sign in to comment.