forked from eduardoflorendo/do-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollector.go
98 lines (84 loc) · 2.56 KB
/
collector.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
package process
import (
"strconv"
"github.com/digitalocean/do-agent/internal/flags"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/procfs"
)
type processCollector struct {
collectFn func(chan<- prometheus.Metric)
cpuTotal *prometheus.Desc
openFDs *prometheus.Desc
rss *prometheus.Desc
startTime *prometheus.Desc
}
// NewProcessCollector returns a collector which exports the current state of
// process metrics including CPU, memory and file descriptor usage as well as
// the process start time.
func NewProcessCollector() prometheus.Collector {
c := &processCollector{
cpuTotal: prometheus.NewDesc(
"sonar_process_cpu_seconds_total",
"Process user and system CPU utilization.",
[]string{"process", "pid"}, nil,
),
openFDs: prometheus.NewDesc(
"sonar_process_open_fds",
"Number of open file descriptors.",
[]string{"process", "pid"}, nil,
),
rss: prometheus.NewDesc(
"sonar_process_resident_memory_bytes",
"Resident memory size in bytes.",
[]string{"process", "pid"}, nil,
),
startTime: prometheus.NewDesc(
"sonar_process_start_time_seconds",
"Start time of the process since unix epoch in seconds.",
[]string{"process", "pid"}, nil,
),
}
if _, err := procfs.NewStat(); err == nil {
c.collectFn = c.processCollect
} else {
// nop
c.collectFn = func(ch chan<- prometheus.Metric) {}
}
return c
}
// Describe returns all descriptions of the collector.
func (c *processCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.cpuTotal
ch <- c.openFDs
ch <- c.rss
ch <- c.startTime
}
// Collect returns the current state of all metrics of the collector.
func (c *processCollector) Collect(ch chan<- prometheus.Metric) {
c.collectFn(ch)
}
func (c *processCollector) processCollect(ch chan<- prometheus.Metric) {
fs, err := procfs.NewFS(flags.ProcfsPath)
if err != nil {
return
}
procs, err := fs.AllProcs()
if err != nil {
return
}
for _, proc := range procs {
stat, err := proc.NewStat()
if err != nil {
return
}
name := stat.Comm
pid := strconv.Itoa(stat.PID)
starttime := float64(stat.Starttime)
ch <- prometheus.MustNewConstMetric(c.cpuTotal, prometheus.CounterValue, stat.CPUTime(), name, pid)
ch <- prometheus.MustNewConstMetric(c.rss, prometheus.GaugeValue, float64(stat.ResidentMemory()), name, pid)
ch <- prometheus.MustNewConstMetric(c.startTime, prometheus.GaugeValue, starttime, name, pid)
if fds, err := proc.FileDescriptorsLen(); err == nil {
ch <- prometheus.MustNewConstMetric(c.openFDs, prometheus.GaugeValue, float64(fds), name, pid)
}
}
}