Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/cmd/internal/flowmode/resources_collector.go
4094 views
1
package flowmode
2
3
import (
4
"os"
5
"time"
6
7
"github.com/go-kit/log"
8
"github.com/go-kit/log/level"
9
"github.com/prometheus/client_golang/prometheus"
10
"github.com/shirou/gopsutil/v3/net"
11
"github.com/shirou/gopsutil/v3/process"
12
)
13
14
// resourcesCollector is a prometheus.Collector which exposes process-level
15
// statistics. It is similar to the process collector in
16
// github.com/prometheus/client_golang but includes support for more platforms.
17
type resourcesCollector struct {
18
log log.Logger
19
20
processStartTime *prometheus.Desc
21
cpuTotal *prometheus.Desc
22
rssMemory *prometheus.Desc
23
virtMemory *prometheus.Desc
24
rxBytes *prometheus.Desc
25
txBytes *prometheus.Desc
26
}
27
28
var _ prometheus.Collector = (*resourcesCollector)(nil)
29
30
// newResourcesCollector creates a new resourcesCollector.
31
func newResourcesCollector(l log.Logger) *resourcesCollector {
32
rc := &resourcesCollector{
33
log: l,
34
35
processStartTime: prometheus.NewDesc(
36
"agent_resources_process_start_time_seconds",
37
"Start time of the process since Unix epoch in seconds.",
38
nil, nil,
39
),
40
41
cpuTotal: prometheus.NewDesc(
42
"agent_resources_process_cpu_seconds_total",
43
"Total user and system CPU time spent in seconds.",
44
nil, nil,
45
),
46
47
rssMemory: prometheus.NewDesc(
48
"agent_resources_process_resident_memory_bytes",
49
"Current resident memory size in bytes.",
50
nil, nil,
51
),
52
53
virtMemory: prometheus.NewDesc(
54
"agent_resources_process_virtual_memory_bytes",
55
"Current virtual memory size in bytes.",
56
nil, nil,
57
),
58
59
rxBytes: prometheus.NewDesc(
60
"agent_resources_machine_rx_bytes_total",
61
"Total bytes, host-wide, received across all network interfaces.",
62
nil, nil,
63
),
64
65
txBytes: prometheus.NewDesc(
66
"agent_resources_machine_tx_bytes_total",
67
"Total bytes, host-wide, sent across all given network interface.",
68
nil, nil,
69
),
70
}
71
72
return rc
73
}
74
75
func (rc *resourcesCollector) Describe(ch chan<- *prometheus.Desc) {
76
ch <- rc.processStartTime
77
ch <- rc.cpuTotal
78
ch <- rc.rssMemory
79
ch <- rc.virtMemory
80
ch <- rc.rxBytes
81
ch <- rc.txBytes
82
}
83
84
func (rc *resourcesCollector) Collect(ch chan<- prometheus.Metric) {
85
proc, err := process.NewProcess(int32(os.Getpid()))
86
if err != nil {
87
level.Error(rc.log).Log("msg", "failed to get process", "err", err)
88
return
89
}
90
91
if t, err := proc.CreateTime(); err != nil {
92
rc.reportError(rc.processStartTime, err)
93
} else {
94
dur := time.Duration(t) * time.Millisecond
95
96
ch <- prometheus.MustNewConstMetric(
97
rc.processStartTime,
98
prometheus.GaugeValue,
99
dur.Seconds(),
100
)
101
}
102
103
if ts, err := proc.Times(); err != nil {
104
rc.reportError(rc.cpuTotal, err)
105
} else {
106
ch <- prometheus.MustNewConstMetric(
107
rc.cpuTotal,
108
prometheus.CounterValue,
109
ts.User+ts.System,
110
)
111
}
112
113
if mi, err := proc.MemoryInfo(); err != nil {
114
rc.reportError(rc.virtMemory, err)
115
rc.reportError(rc.rssMemory, err)
116
} else {
117
ch <- prometheus.MustNewConstMetric(
118
rc.virtMemory,
119
prometheus.GaugeValue,
120
float64(mi.VMS),
121
)
122
123
ch <- prometheus.MustNewConstMetric(
124
rc.rssMemory,
125
prometheus.GaugeValue,
126
float64(mi.RSS),
127
)
128
}
129
130
if counters, err := net.IOCounters(true); err != nil {
131
rc.reportError(rc.rxBytes, err)
132
rc.reportError(rc.txBytes, err)
133
} else {
134
var rxBytes, txByes uint64
135
136
for _, counter := range counters {
137
rxBytes += counter.BytesRecv
138
txByes += counter.BytesSent
139
}
140
141
ch <- prometheus.MustNewConstMetric(
142
rc.rxBytes,
143
prometheus.CounterValue,
144
float64(rxBytes),
145
)
146
147
ch <- prometheus.MustNewConstMetric(
148
rc.txBytes,
149
prometheus.CounterValue,
150
float64(txByes),
151
)
152
}
153
}
154
155
func (rc *resourcesCollector) reportError(d *prometheus.Desc, err error) {
156
level.Error(rc.log).Log("msg", "failed to collect resources metric", "name", d.String(), "err", err)
157
}
158
159