node_exporter源码解析

背景

最近想要实现一个关于OS exporter,发现和node exporter类似,所以打算学习一下node exporter源码。这里以centos8作为操作系统。所以相关代码都是Linux相关。

CPU指标获取

在具体了解代码之前,在linux中如果想要查看CPU相关指标都有那些工具?耳熟能详的都有以下工具:

  1. top
  2. 各种stat
    1. vmstat
    2. iostat
    3. pidstat
    4. mpstat

当然还有BPF等工具也可以查看到CPU相关指标,比如使用率;这些工具读取的地方主要就是以下路径:

  1. /proc
  2. /sys

所以,node_exporter也不例外:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//collector/paths.go


var (
// The path of the proc filesystem.
procPath = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String()
sysPath = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String()
rootfsPath = kingpin.Flag("path.rootfs", "rootfs mountpoint.").Default("/").String()
udevDataPath = kingpin.Flag("path.udev.data", "udev data path.").Default("/run/udev/data").String()
)

func procFilePath(name string) string {
return filepath.Join(*procPath, name)
}

func sysFilePath(name string) string {
return filepath.Join(*sysPath, name)
}

func rootfsFilePath(name string) string {
return filepath.Join(*rootfsPath, name)
}

func udevDataFilePath(name string) string {
return filepath.Join(*udevDataPath, name)
}

func rootfsStripPrefix(path string) string {
if *rootfsPath == "/" {
return path
}
stripped := strings.TrimPrefix(path, *rootfsPath)
if stripped == "" {
return "/"
}
return stripped
}

CPU loadavg获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Read loadavg from /proc.
func getLoad() (loads []float64, err error) {
data, err := os.ReadFile(procFilePath("loadavg"))
if err != nil {
return nil, err
}
loads, err = parseLoad(string(data))
if err != nil {
return nil, err
}
return loads, nil
}

// Parse /proc loadavg and return 1m, 5m and 15m.
func parseLoad(data string) (loads []float64, err error) {
loads = make([]float64, 3)
parts := strings.Fields(data)
if len(parts) < 3 {
return nil, fmt.Errorf("unexpected content in %s", procFilePath("loadavg"))
}
for i, load := range parts[0:3] {
loads[i], err = strconv.ParseFloat(load, 64)
if err != nil {
return nil, fmt.Errorf("could not parse load '%s': %w", load, err)
}
}
return loads, nil
}

node_exporter源码解析
http://example.com/2024/02/15/node-exporter源码解析/
Author
John Doe
Posted on
February 15, 2024
Licensed under