-
Notifications
You must be signed in to change notification settings - Fork 0
/
digitalocean_collector.go
187 lines (165 loc) · 4.94 KB
/
digitalocean_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
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package digitaloceanexporter
import (
"time"
"strconv"
"github.com/prometheus/client_golang/prometheus"
)
// A DigitalOceanSource is an interface which can retrieve information about a
// resources in a DigitalOcean account. It is implemented by
// *digitaloceanexporter.DigitalOceanService.
type DigitalOceanSource interface {
Droplets() map[DropletCounter]int
FloatingIPs() map[FlipCounter]int
LoadBalancers() map[LoadBalancerCounter]int
Tags() map[TagCounter]int
Volumes() map[VolumeCounter]int
QueryDuration() time.Duration
}
// A DigitalOceanCollector is a Prometheus collector for metrics regarding
// DigitalOcean.
type DigitalOceanCollector struct {
Droplets *prometheus.Desc
FloatingIPs *prometheus.Desc
LoadBalancers *prometheus.Desc
Tags *prometheus.Desc
Volumes *prometheus.Desc
QueryDuration *prometheus.Desc
dos DigitalOceanSource
}
// Verify that DigitalOceanCollector implements the prometheus.Collector interface.
var _ prometheus.Collector = &DigitalOceanCollector{}
// NewDigitalOceanCollector creates a new DigitalOceanCollector which collects
// metrics about resources in a DigitalOcean account.
func NewDigitalOceanCollector(dos DigitalOceanSource) *DigitalOceanCollector {
return &DigitalOceanCollector{
Droplets: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "droplets", "count"),
"Number of Droplets by region, size, and status.",
[]string{"region", "size", "status", "price_hourly", "price_monthly", "tags"},
nil,
),
FloatingIPs: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "floating_ips", "count"),
"Number of Floating IPs by region and status.",
[]string{"region", "status"},
nil,
),
LoadBalancers: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "load_balancers", "count"),
"Number of Load Balancers by region and status.",
[]string{"region", "status"},
nil,
),
Tags: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "tags", "count"),
"Count of tagged resources by name and resource type.",
[]string{"name", "resource_type"},
nil,
),
Volumes: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "volumes", "count"),
"Number of Volumes by region, size in GiB, and status.",
[]string{"region", "size", "status"},
nil,
),
QueryDuration: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "query_duration", "seconds"),
"Time elapsed while querying the DigitalOcean API in seconds.",
[]string{},
nil,
),
dos: dos,
}
}
// collect begins a metrics collection task for all metrics related to
// resources in a DigitalOcean account.
func (c *DigitalOceanCollector) collect(ch chan<- prometheus.Metric) {
c.collectDropletCounts(ch)
c.collectFipsCounts(ch)
c.collectLoadBalancerCounts(ch)
c.collectTagCounts(ch)
c.collectVolumeCounts(ch)
c.collectQueryDuration(ch)
}
func (c *DigitalOceanCollector) collectDropletCounts(ch chan<- prometheus.Metric) {
for d, count := range c.dos.Droplets() {
ch <- prometheus.MustNewConstMetric(
c.Droplets,
prometheus.GaugeValue,
float64(count),
d.region,
d.size,
d.status,
strconv.FormatFloat(d.price_hourly, 'f', 6, 64),
strconv.FormatFloat(d.price_monthly, 'f', 2, 64),
d.tags,
)
}
}
func (c *DigitalOceanCollector) collectFipsCounts(ch chan<- prometheus.Metric) {
for fip, count := range c.dos.FloatingIPs() {
ch <- prometheus.MustNewConstMetric(
c.FloatingIPs,
prometheus.GaugeValue,
float64(count),
fip.region,
fip.status,
)
}
}
func (c *DigitalOceanCollector) collectLoadBalancerCounts(ch chan<- prometheus.Metric) {
for lb, count := range c.dos.LoadBalancers() {
ch <- prometheus.MustNewConstMetric(
c.LoadBalancers,
prometheus.GaugeValue,
float64(count),
lb.region,
lb.status,
)
}
}
func (c *DigitalOceanCollector) collectTagCounts(ch chan<- prometheus.Metric) {
for t, count := range c.dos.Tags() {
ch <- prometheus.MustNewConstMetric(
c.Tags,
prometheus.GaugeValue,
float64(count),
t.name,
t.resourceType,
)
}
}
func (c *DigitalOceanCollector) collectVolumeCounts(ch chan<- prometheus.Metric) {
for v, count := range c.dos.Volumes() {
ch <- prometheus.MustNewConstMetric(
c.Volumes,
prometheus.GaugeValue,
float64(count),
v.region,
v.size,
v.status,
)
}
}
func (c *DigitalOceanCollector) collectQueryDuration(ch chan<- prometheus.Metric) {
ch <- prometheus.MustNewConstMetric(
c.QueryDuration,
prometheus.GaugeValue,
c.dos.QueryDuration().Seconds(),
)
}
// Describe sends the descriptors of each metric over to the provided channel.
// The corresponding metric values are sent separately.
func (c *DigitalOceanCollector) Describe(ch chan<- *prometheus.Desc) {
ds := []*prometheus.Desc{
c.Droplets,
}
for _, d := range ds {
ch <- d
}
}
// Collect sends the metric values for each metric pertaining to the DigitalOcean
// resources to the provided prometheus Metric channel.
func (c *DigitalOceanCollector) Collect(ch chan<- prometheus.Metric) {
c.collect(ch)
}