Skip to content

Commit f652e66

Browse files
Michael CaptainMichael Captain
Michael Captain
authored and
Michael Captain
committed
Add the code for version 0.1.0 of the Prometheus FlashBlade exporter
1 parent 485abc6 commit f652e66

16 files changed

+918
-0
lines changed

Dockerfile

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
ARG GO_VERSION=1.12
2+
3+
FROM golang:${GO_VERSION}-alpine AS builder
4+
5+
RUN mkdir /user && \
6+
echo 'fbexporter:x:1000:1000:fbexporter:/:' > /user/passwd && \
7+
echo 'fbexporter:x:1000:' > /user/group
8+
9+
RUN apk add --no-cache ca-certificates
10+
ENV CGO_ENABLED=0
11+
WORKDIR /src
12+
COPY ./ ./
13+
14+
RUN go build -ldflags '-w -extldflags "-static"'
15+
16+
FROM scratch AS final
17+
18+
COPY --from=builder /user/group /user/passwd /etc/
19+
COPY --from=builder /src/prometheus-flashblade-exporter /usr/bin/prometheus-flashblade-exporter
20+
21+
EXPOSE 9130
22+
23+
USER fbexporter:fbexporter
24+
25+
# Run the compiled binary.
26+
ENTRYPOINT ["/usr/bin/prometheus-flashblade-exporter"]
27+

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
all: build
2+
build:
3+
CGO_ENABLED=0 go build -ldflags '-w -extldflags "-static"'
4+
docker:
5+
docker build

README.md

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Pure FlashBlade Exporter for Prometheus
2+
3+
The exporter uses FlashBlade API version 1.2.
4+
5+
## Building
6+
7+
```
8+
make deps
9+
make build
10+
```
11+
12+
Or simply:
13+
14+
```
15+
make
16+
```
17+
18+
## Usage
19+
20+
The exporter requires the name of the FlashBlade as a command-line argument:
21+
22+
`flashblade_exporter <flashblade>`
23+
24+
The exporter accepts the following command line flags:
25+
26+
| Flag | Description | Default |
27+
| ---------- | ------------------------------------------------------------------------ | ------- |
28+
| --port | Port on which the exporter will bind to in order to serve up the metrics | 9130 |
29+
| --insecure | Disable SSL verification | false |
30+
31+
32+
## Metrics
33+
34+
* Filesystem usage (unique, virtual, snapshot and total)
35+
* Bandwidth, IOPS and latency for both read and write
36+
37+
```
38+
# HELP flashblade_alert_num_critical_alerts Number of open critical severity alerts
39+
# TYPE flashblade_alert_num_critical_alerts gauge
40+
# HELP flashblade_alert_num_info_alerts Number of open info severity alerts
41+
# TYPE flashblade_alert_num_info_alerts gauge
42+
# HELP flashblade_alert_num_warning_alerts Number of open warning severity alerts
43+
# TYPE flashblade_alert_num_warning_alerts gauge
44+
# HELP flashblade_blade_num_healthy_blades Number of blades in healthy status
45+
# TYPE flashblade_blade_num_healthy_blades gauge
46+
# HELP flashblade_blade_num_unhealthy_blades Number of blades in a non-healthy status
47+
# TYPE flashblade_blade_num_unhealthy_blades gauge
48+
# HELP flashblade_collector_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which flashblade_collector was built.
49+
# TYPE flashblade_collector_build_info gauge
50+
# HELP flashblade_fs_data_reduction Reduction of data
51+
# TYPE flashblade_fs_data_reduction gauge
52+
# HELP flashblade_fs_snapshot_usage_bytes Physical usage by snapshots, non-unique
53+
# TYPE flashblade_fs_snapshot_usage_bytes gauge
54+
# HELP flashblade_fs_total_usage_bytes Total physical usage (including snapshots) in bytes
55+
# TYPE flashblade_fs_total_usage_bytes gauge
56+
# HELP flashblade_fs_unique_usage_bytes Physical usage in bytes
57+
# TYPE flashblade_fs_unique_usage_bytes gauge
58+
# HELP flashblade_fs_virtual_usage_bytes Usage in bytes
59+
# TYPE flashblade_fs_virtual_usage_bytes gauge
60+
# HELP flashblade_perf_bytes_per_op Average operation size (read bytes+write bytes/(read ops+write ops))
61+
# TYPE flashblade_perf_bytes_per_op gauge
62+
# HELP flashblade_perf_bytes_per_read Average read size in bytes per read operation
63+
# TYPE flashblade_perf_bytes_per_read gauge
64+
# HELP flashblade_perf_bytes_per_write Average write size in bytes per write operation
65+
# TYPE flashblade_perf_bytes_per_write gauge
66+
# HELP flashblade_perf_input_per_sec Bytes written per second
67+
# TYPE flashblade_perf_input_per_sec gauge
68+
# HELP flashblade_perf_others_per_sec Other operations processed per second
69+
# TYPE flashblade_perf_others_per_sec gauge
70+
# HELP flashblade_perf_output_per_sec Bytes read per second
71+
# TYPE flashblade_perf_output_per_sec gauge
72+
# HELP flashblade_perf_reads_per_sec Read requests processed per second
73+
# TYPE flashblade_perf_reads_per_sec gauge
74+
# HELP flashblade_perf_usec_per_other_op Average time, measured in microseconds, that the array takes to process other operations
75+
# TYPE flashblade_perf_usec_per_other_op gauge
76+
# HELP flashblade_perf_usec_per_read_op Average time, measured in microseconds, that the array takes to process a read request
77+
# TYPE flashblade_perf_usec_per_read_op gauge
78+
# HELP flashblade_perf_usec_per_write_op Average time, measured in microseconds, that the array takes to process a write request
79+
# TYPE flashblade_perf_usec_per_write_op gauge
80+
# HELP flashblade_perf_writes_per_sec Write requests processed per second
81+
# TYPE flashblade_perf_writes_per_sec gauge
82+
```
83+
84+
## TODO
85+
86+
[ ] Add overall capacity metrics
87+
[ ] Add optional per-IP metrics

collector/alerts.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package collector
2+
3+
import (
4+
"github.com/manahl/prometheus-flashblade-exporter/fb"
5+
"github.com/prometheus/client_golang/prometheus"
6+
"github.com/prometheus/common/log"
7+
)
8+
9+
type AlertsCollector struct {
10+
fbClient *fb.FlashbladeClient
11+
AlertTotal *prometheus.Desc
12+
}
13+
14+
func NewAlertsCollector(fbClient *fb.FlashbladeClient) *AlertsCollector {
15+
const subsystem = "alert"
16+
17+
return &AlertsCollector{
18+
fbClient: fbClient,
19+
AlertTotal: prometheus.NewDesc(
20+
prometheus.BuildFQName(namespace, subsystem, "alert_total"),
21+
"Number of open alerts",
22+
[]string{"severity"},
23+
prometheus.Labels{"host": fbClient.Host},
24+
),
25+
}
26+
}
27+
28+
func (c AlertsCollector) Collect(ch chan<- prometheus.Metric) {
29+
if err := c.collect(ch); err != nil {
30+
log.Error("Failed collecting alerts metrics", err)
31+
}
32+
}
33+
34+
func countAlertsBySeverity(alerts fb.AlertsResponse) map[string]int {
35+
alertSeverityMap := make(map[string]int)
36+
37+
for _, alert := range alerts.Items {
38+
alertSeverityMap[alert.Severity]++
39+
}
40+
41+
return alertSeverityMap
42+
}
43+
44+
func (c AlertsCollector) collect(ch chan<- prometheus.Metric) error {
45+
alerts, err := c.fbClient.OpenAlerts()
46+
if err != nil {
47+
return err
48+
}
49+
50+
alertSeverityMap := countAlertsBySeverity(alerts)
51+
52+
for sev, count := range alertSeverityMap {
53+
ch <- prometheus.MustNewConstMetric(
54+
c.AlertTotal,
55+
prometheus.GaugeValue,
56+
float64(count),
57+
sev)
58+
}
59+
60+
return nil
61+
}

collector/array_performance.go

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package collector
2+
3+
import (
4+
"github.com/manahl/prometheus-flashblade-exporter/fb"
5+
"github.com/prometheus/client_golang/prometheus"
6+
"github.com/prometheus/common/log"
7+
)
8+
9+
type ArrayPerformanceCollector struct {
10+
fbClient *fb.FlashbladeClient
11+
BytesPerOp *prometheus.Desc
12+
BytesPerRead *prometheus.Desc
13+
BytesPerWrite *prometheus.Desc
14+
OthersPerSec *prometheus.Desc
15+
OutputPerSec *prometheus.Desc
16+
ReadsPerSec *prometheus.Desc
17+
UsecPerOtherOp *prometheus.Desc
18+
UsecPerReadOp *prometheus.Desc
19+
UsecPerWriteOp *prometheus.Desc
20+
InputPerSec *prometheus.Desc
21+
WritesPerSec *prometheus.Desc
22+
}
23+
24+
func NewArrayPerformanceCollector(fbClient *fb.FlashbladeClient) *ArrayPerformanceCollector {
25+
const subsystem = "perf"
26+
27+
return &ArrayPerformanceCollector{
28+
fbClient: fbClient,
29+
BytesPerOp: prometheus.NewDesc(
30+
prometheus.BuildFQName(namespace, subsystem, "bytes_per_op"),
31+
"Average operation size (read bytes+write bytes/(read ops+write ops))",
32+
nil,
33+
prometheus.Labels{"host": fbClient.Host},
34+
),
35+
BytesPerRead: prometheus.NewDesc(
36+
prometheus.BuildFQName(namespace, subsystem, "bytes_per_read"),
37+
"Average read size in bytes per read operation",
38+
nil,
39+
prometheus.Labels{"host": fbClient.Host},
40+
),
41+
BytesPerWrite: prometheus.NewDesc(
42+
prometheus.BuildFQName(namespace, subsystem, "bytes_per_write"),
43+
"Average write size in bytes per write operation",
44+
nil,
45+
prometheus.Labels{"host": fbClient.Host},
46+
),
47+
OthersPerSec: prometheus.NewDesc(
48+
prometheus.BuildFQName(namespace, subsystem, "others_per_sec"),
49+
"Other operations processed per second",
50+
nil,
51+
prometheus.Labels{"host": fbClient.Host},
52+
),
53+
OutputPerSec: prometheus.NewDesc(
54+
prometheus.BuildFQName(namespace, subsystem, "output_per_sec"),
55+
"Bytes read per second",
56+
nil,
57+
prometheus.Labels{"host": fbClient.Host},
58+
),
59+
ReadsPerSec: prometheus.NewDesc(
60+
prometheus.BuildFQName(namespace, subsystem, "reads_per_sec"),
61+
"Read requests processed per second",
62+
nil,
63+
prometheus.Labels{"host": fbClient.Host},
64+
),
65+
UsecPerOtherOp: prometheus.NewDesc(
66+
prometheus.BuildFQName(namespace, subsystem, "usec_per_other_op"),
67+
"Average time, measured in microseconds, that the array takes to process other operations",
68+
nil,
69+
prometheus.Labels{"host": fbClient.Host},
70+
),
71+
UsecPerReadOp: prometheus.NewDesc(
72+
prometheus.BuildFQName(namespace, subsystem, "usec_per_read_op"),
73+
"Average time, measured in microseconds, that the array takes to process a read request",
74+
nil,
75+
prometheus.Labels{"host": fbClient.Host},
76+
),
77+
UsecPerWriteOp: prometheus.NewDesc(
78+
prometheus.BuildFQName(namespace, subsystem, "usec_per_write_op"),
79+
"Average time, measured in microseconds, that the array takes to process a write request",
80+
nil,
81+
prometheus.Labels{"host": fbClient.Host},
82+
),
83+
InputPerSec: prometheus.NewDesc(
84+
prometheus.BuildFQName(namespace, subsystem, "input_per_sec"),
85+
"Bytes written per second",
86+
nil,
87+
prometheus.Labels{"host": fbClient.Host},
88+
),
89+
WritesPerSec: prometheus.NewDesc(
90+
prometheus.BuildFQName(namespace, subsystem, "writes_per_sec"),
91+
"Write requests processed per second",
92+
nil,
93+
prometheus.Labels{"host": fbClient.Host},
94+
),
95+
}
96+
}
97+
98+
func (c ArrayPerformanceCollector) Collect(ch chan<- prometheus.Metric) {
99+
if err := c.collect(ch); err != nil {
100+
log.Error("Failed collecting array performance metrics", err)
101+
}
102+
}
103+
104+
func (c ArrayPerformanceCollector) collect(ch chan<- prometheus.Metric) error {
105+
stats, err := c.fbClient.ArrayPerformance()
106+
if err != nil {
107+
return err
108+
}
109+
110+
ch <- prometheus.MustNewConstMetric(
111+
c.BytesPerOp,
112+
prometheus.GaugeValue,
113+
float64(stats.Items[0].BytesPerOp))
114+
115+
ch <- prometheus.MustNewConstMetric(
116+
c.BytesPerRead,
117+
prometheus.GaugeValue,
118+
float64(stats.Items[0].BytesPerRead))
119+
120+
ch <- prometheus.MustNewConstMetric(
121+
c.BytesPerWrite,
122+
prometheus.GaugeValue,
123+
float64(stats.Items[0].BytesPerWrite))
124+
125+
ch <- prometheus.MustNewConstMetric(
126+
c.OthersPerSec,
127+
prometheus.GaugeValue,
128+
float64(stats.Items[0].OthersPerSec))
129+
130+
ch <- prometheus.MustNewConstMetric(
131+
c.OutputPerSec,
132+
prometheus.GaugeValue,
133+
float64(stats.Items[0].OutputPerSec))
134+
135+
ch <- prometheus.MustNewConstMetric(
136+
c.ReadsPerSec,
137+
prometheus.GaugeValue,
138+
float64(stats.Items[0].ReadsPerSec))
139+
140+
ch <- prometheus.MustNewConstMetric(
141+
c.UsecPerOtherOp,
142+
prometheus.GaugeValue,
143+
float64(stats.Items[0].UsecPerOtherOp))
144+
145+
ch <- prometheus.MustNewConstMetric(
146+
c.UsecPerReadOp,
147+
prometheus.GaugeValue,
148+
float64(stats.Items[0].UsecPerReadOp))
149+
150+
ch <- prometheus.MustNewConstMetric(
151+
c.UsecPerWriteOp,
152+
prometheus.GaugeValue,
153+
float64(stats.Items[0].UsecPerWriteOp))
154+
155+
ch <- prometheus.MustNewConstMetric(
156+
c.InputPerSec,
157+
prometheus.GaugeValue,
158+
float64(stats.Items[0].InputPerSec))
159+
160+
ch <- prometheus.MustNewConstMetric(
161+
c.WritesPerSec,
162+
prometheus.GaugeValue,
163+
float64(stats.Items[0].WritesPerSec))
164+
165+
return nil
166+
}

0 commit comments

Comments
 (0)