ebpf_exporter
71 строка · 1.4 Кб
1package cgroup
2
3import (
4"io/fs"
5"log"
6"path/filepath"
7)
8
9type walkerMonitor struct {
10path string
11mapping map[int]string
12}
13
14func newWalkerMonitor(path string) (*walkerMonitor, error) {
15mapping, err := walk(path)
16if err != nil {
17return nil, err
18}
19
20return &walkerMonitor{path: path, mapping: mapping}, nil
21}
22
23func (m *walkerMonitor) Resolve(id int) string {
24// Try to resolve in cache first
25if existing, ok := m.mapping[id]; ok {
26return existing
27}
28
29// Refresh mapping to see if we a new cgroup appeared since last time
30if mapping, err := walk(m.path); err != nil {
31log.Printf("Error refreshing mapping: %v", err)
32} else {
33for id, name := range mapping {
34m.mapping[id] = name
35}
36}
37
38// If no new cgroup appeared, cache negative resolution to prevent constant refreshes
39if _, ok := m.mapping[id]; !ok {
40m.mapping[id] = ""
41}
42
43// Return whatever we have now (either newly resolved or cached negative value)
44return m.mapping[id]
45}
46
47func walk(dir string) (map[int]string, error) {
48mapping := map[int]string{}
49
50err := filepath.WalkDir(dir, func(path string, entry fs.DirEntry, err error) error {
51if err != nil {
52return err
53}
54
55if !entry.IsDir() {
56return nil
57}
58
59inode, err := inode(path)
60if err != nil {
61log.Printf("Error resolving inode for %q: %v", path, err)
62return nil
63}
64
65mapping[inode] = path
66
67return nil
68})
69
70return mapping, err
71}
72