forked from coroot/coroot-node-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
125 lines (106 loc) · 3.06 KB
/
main.go
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"bytes"
"github.com/coroot/coroot-node-agent/common"
"github.com/coroot/coroot-node-agent/containers"
"github.com/coroot/coroot-node-agent/flags"
"github.com/coroot/coroot-node-agent/node"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"golang.org/x/mod/semver"
"golang.org/x/sys/unix"
"k8s.io/klog/v2"
"net/http"
_ "net/http/pprof"
"os"
"path"
"runtime"
"strings"
)
var (
version = "unknown"
)
const minSupportedKernelVersion = "4.16"
func uname() (string, string, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
f, err := os.Open("/proc/1/ns/uts")
if err != nil {
return "", "", err
}
defer f.Close()
self, err := os.Open("/proc/self/ns/uts")
if err != nil {
return "", "", err
}
defer self.Close()
defer func() {
unix.Setns(int(self.Fd()), unix.CLONE_NEWUTS)
}()
err = unix.Setns(int(f.Fd()), unix.CLONE_NEWUTS)
if err != nil {
return "", "", err
}
var utsname unix.Utsname
if err := unix.Uname(&utsname); err != nil {
return "", "", err
}
hostname := string(bytes.Split(utsname.Nodename[:], []byte{0})[0])
kernelVersion := string(bytes.Split(utsname.Release[:], []byte{0})[0])
return hostname, kernelVersion, nil
}
func machineID() string {
for _, p := range []string{"sys/devices/virtual/dmi/id/product_uuid", "etc/machine-id", "var/lib/dbus/machine-id"} {
payload, err := os.ReadFile(path.Join("/proc/1/root", p))
if err != nil {
klog.Warningln("failed to read machine-id:", err)
continue
}
id := strings.TrimSpace(strings.Replace(string(payload), "-", "", -1))
klog.Infoln("machine-id: ", id)
return id
}
return ""
}
func main() {
klog.Infoln("agent version:", version)
hostname, kv, err := uname()
if err != nil {
klog.Exitln("failed to get uname:", err)
}
klog.Infoln("hostname:", hostname)
klog.Infoln("kernel version:", kv)
ver := common.KernelMajorMinor(kv)
if ver == "" {
klog.Exitln("invalid kernel version:", kv)
}
if semver.Compare("v"+ver, "v"+minSupportedKernelVersion) == -1 {
klog.Exitf("the minimum Linux kernel version required is %s or later", minSupportedKernelVersion)
}
registry := prometheus.NewRegistry()
registerer := prometheus.WrapRegistererWith(prometheus.Labels{"machine_id": machineID()}, registry)
registerer.MustRegister(info("node_agent_info", version))
if err := registerer.Register(node.NewCollector(hostname, kv)); err != nil {
klog.Exitln(err)
}
cs, err := containers.NewRegistry(registerer, kv)
if err != nil {
klog.Exitln(err)
}
defer cs.Close()
http.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{ErrorLog: logger{}, Registry: registerer}))
klog.Infoln("listening on:", *flags.ListenAddress)
klog.Errorln(http.ListenAndServe(*flags.ListenAddress, nil))
}
func info(name, version string) prometheus.Collector {
g := prometheus.NewGauge(prometheus.GaugeOpts{
Name: name,
ConstLabels: prometheus.Labels{"version": version},
})
g.Set(1)
return g
}
type logger struct{}
func (l logger) Println(v ...interface{}) {
klog.Errorln(v...)
}