Skip to content

Commit 146e0df

Browse files
Nathan Monfilsazertyfun
Nathan Monfils
andauthored
Add template option for Cgroups (ncabatoff#199)
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]>
1 parent 934d2ed commit 146e0df

File tree

10 files changed

+41
-2
lines changed

10 files changed

+41
-2
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ Template variables available:
107107
will only contain a single process.
108108
- `{{.StartTime}}` contains the start time of the process. This can be useful
109109
in conjunction with PID because PIDs get reused over time.
110+
- `{{.Cgroups}}` contains (if supported) the cgroups of the process
111+
(`/proc/self/cgroup`). This is particularly useful for identifying to which container
112+
a process belongs.
110113

111114
Using `PID` or `StartTime` is discouraged: this is almost never what you want,
112115
and is likely to result in high cardinality metrics which Prometheus will have

common.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type (
99
ProcAttributes struct {
1010
Name string
1111
Cmdline []string
12+
Cgroups []string
1213
Username string
1314
PID int
1415
StartTime time.Time

config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type (
5050
}
5151

5252
templateParams struct {
53+
Cgroups []string
5354
Comm string
5455
ExeBase string
5556
ExeFull string
@@ -116,6 +117,7 @@ func (m *matchNamer) MatchAndName(nacl common.ProcAttributes) (bool, string) {
116117
var buf bytes.Buffer
117118
m.template.Execute(&buf, &templateParams{
118119
Comm: nacl.Name,
120+
Cgroups: nacl.Cgroups,
119121
ExeBase: exebase,
120122
ExeFull: exefull,
121123
Matches: matches,

fixtures/14804/cgroup

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0::/system.slice/docker-8dde0b0d6e919baef8d635cd9399b22639ed1e400eaec1b1cb94ff3b216cf3c3.scope

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
1313
github.com/prometheus/client_golang v1.11.0
1414
github.com/prometheus/common v0.26.0
15-
github.com/prometheus/procfs v0.6.0
15+
github.com/prometheus/procfs v0.7.1
1616
github.com/rogpeppe/go-internal v1.8.0 // indirect
1717
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
1818
gopkg.in/yaml.v2 v2.4.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULU
259259
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
260260
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
261261
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
262+
github.com/prometheus/procfs v0.7.1 h1:TlEtJq5GvGqMykEwWzbZWjjztF86swFhsPix1i0bkgA=
263+
github.com/prometheus/procfs v0.7.1/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
262264
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
263265
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
264266
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=

proc/base_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func (n namer) MatchAndName(nacl common.ProcAttributes) (bool, string) {
6767

6868
func newProcIDStatic(pid, ppid int, startTime uint64, name string, cmdline []string) (ID, Static) {
6969
return ID{pid, startTime},
70-
Static{name, cmdline, ppid, time.Unix(int64(startTime), 0).UTC(), 1000}
70+
Static{name, cmdline, []string{}, ppid, time.Unix(int64(startTime), 0).UTC(), 1000}
7171
}
7272

7373
func newProc(pid int, name string, m Metrics) IDInfo {

proc/read.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type (
3030
Static struct {
3131
Name string
3232
Cmdline []string
33+
Cgroups []string
3334
ParentPid int
3435
StartTime time.Time
3536
EffectiveUID int
@@ -135,6 +136,7 @@ type (
135136
stat *procfs.ProcStat
136137
status *procfs.ProcStatus
137138
cmdline []string
139+
cgroups []procfs.Cgroup
138140
io *procfs.ProcIO
139141
fs *FS
140142
wchan *string
@@ -299,6 +301,18 @@ func (p *proccache) getStatus() (procfs.ProcStatus, error) {
299301
return *p.status, nil
300302
}
301303

304+
func (p *proccache) getCgroups() ([]procfs.Cgroup, error) {
305+
if p.cgroups == nil {
306+
cgroups, err := p.Proc.Cgroups()
307+
if err != nil {
308+
return nil, err
309+
}
310+
p.cgroups = cgroups
311+
}
312+
313+
return p.cgroups, nil
314+
}
315+
302316
// GetProcID implements Proc.
303317
func (p *proccache) GetProcID() (ID, error) {
304318
if p.procid == nil {
@@ -367,6 +381,19 @@ func (p *proccache) GetStatic() (Static, error) {
367381
return Static{}, err
368382
}
369383

384+
// /proc/<pid>/cgroup(s) is normally world-readable.
385+
// However cgroups aren't always supported -> return an empty array in that
386+
// case.
387+
cgroups, err := p.getCgroups()
388+
var cgroupsStr []string
389+
if err != nil {
390+
cgroupsStr = []string{}
391+
} else {
392+
for _, c := range cgroups {
393+
cgroupsStr = append(cgroupsStr, c.Path)
394+
}
395+
}
396+
370397
effectiveUID, err := strconv.ParseInt(status.UIDs[1], 10, 64)
371398
if err != nil {
372399
return Static{}, err
@@ -375,6 +402,7 @@ func (p *proccache) GetStatic() (Static, error) {
375402
return Static{
376403
Name: stat.Comm,
377404
Cmdline: cmdline,
405+
Cgroups: cgroupsStr,
378406
ParentPid: stat.PPID,
379407
StartTime: startTime,
380408
EffectiveUID: int(effectiveUID),

proc/read_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func TestReadFixture(t *testing.T) {
6363
wantstatic := Static{
6464
Name: "process-exporte",
6565
Cmdline: []string{"./process-exporter", "-procnames", "bash"},
66+
Cgroups: []string{"/system.slice/docker-8dde0b0d6e919baef8d635cd9399b22639ed1e400eaec1b1cb94ff3b216cf3c3.scope"},
6667
ParentPid: 10884,
6768
StartTime: stime,
6869
EffectiveUID: 1000,

proc/tracker.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ func (t *Tracker) Update(iter Iter) (CollectErrors, []Update, error) {
419419
nacl := common.ProcAttributes{
420420
Name: idinfo.Name,
421421
Cmdline: idinfo.Cmdline,
422+
Cgroups: idinfo.Cgroups,
422423
Username: t.lookupUid(idinfo.EffectiveUID),
423424
PID: idinfo.Pid,
424425
StartTime: idinfo.StartTime,

0 commit comments

Comments
 (0)