Skip to content

Commit 8e63f6e

Browse files
Merge pull request #1 from MCBrandenburg/moremetrics
Moremetrics
2 parents bd88ebb + 045d9d7 commit 8e63f6e

File tree

16 files changed

+655
-40
lines changed

16 files changed

+655
-40
lines changed

.github/workflows/go.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ jobs:
55
name: Build
66
runs-on: ubuntu-latest
77
steps:
8-
- name: Set up Go 1.13
8+
- name: Set up Go 1.18
99
uses: actions/setup-go@v1
1010
with:
11-
go-version: 1.13
11+
go-version: 1.18
1212
id: go
1313

1414
- name: Check out code into the Go module directory

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# build stage
2-
FROM golang:1.13.2-alpine AS go-build-env
2+
FROM golang:1.18-alpine AS go-build-env
33

44
RUN apk add --no-cache --update make git alpine-sdk gcc build-base
55

go.mod

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
11
module github.com/mjavier2k/solidfire-exporter
22

3-
go 1.15
3+
go 1.18
44

55
require (
66
github.com/K-Phoen/grabana v0.16.3
77
github.com/amoghe/distillog v0.0.0-20180726233512-ae382b35b717
8+
github.com/prometheus/client_golang v1.10.0
9+
github.com/spf13/pflag v1.0.5
10+
github.com/spf13/viper v1.7.1
11+
github.com/stretchr/testify v1.7.0
12+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
13+
gopkg.in/h2non/gock.v1 v1.0.16
14+
)
15+
16+
require (
17+
github.com/beorn7/perks v1.0.1 // indirect
18+
github.com/cespare/xxhash/v2 v2.1.1 // indirect
19+
github.com/davecgh/go-spew v1.1.1 // indirect
820
github.com/fsnotify/fsnotify v1.4.9 // indirect
921
github.com/golang/protobuf v1.5.2 // indirect
22+
github.com/gosimple/slug v1.9.0 // indirect
1023
github.com/grafana-tools/sdk v0.0.0-20210521150820-354cd37a4b4e // indirect
24+
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
25+
github.com/hashicorp/hcl v1.0.0 // indirect
1126
github.com/magiconair/properties v1.8.5 // indirect
27+
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
1228
github.com/mitchellh/mapstructure v1.4.1 // indirect
1329
github.com/pelletier/go-toml v1.9.1 // indirect
14-
github.com/prometheus/client_golang v1.10.0
30+
github.com/pkg/errors v0.9.1 // indirect
31+
github.com/pmezard/go-difflib v1.0.0 // indirect
32+
github.com/prometheus/client_model v0.2.0 // indirect
1533
github.com/prometheus/common v0.25.0 // indirect
34+
github.com/prometheus/procfs v0.6.0 // indirect
35+
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect
1636
github.com/spf13/afero v1.6.0 // indirect
1737
github.com/spf13/cast v1.3.1 // indirect
1838
github.com/spf13/jwalterweatherman v1.1.0 // indirect
19-
github.com/spf13/pflag v1.0.5
20-
github.com/spf13/viper v1.7.1
2139
github.com/stretchr/objx v0.3.0 // indirect
22-
github.com/stretchr/testify v1.7.0
23-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
40+
github.com/subosito/gotenv v1.2.0 // indirect
2441
golang.org/x/sys v0.0.0-20210521203332-0cec03c779c1 // indirect
2542
golang.org/x/text v0.3.6 // indirect
26-
gopkg.in/h2non/gock.v1 v1.0.16
43+
google.golang.org/protobuf v1.26.0 // indirect
2744
gopkg.in/ini.v1 v1.62.0 // indirect
45+
gopkg.in/yaml.v2 v2.4.0 // indirect
2846
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
2947
)

go.sum

Lines changed: 1 addition & 28 deletions
Large diffs are not rendered by default.

pkg/prom/collector.go

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,28 @@ func (c *SolidfireCollector) Describe(ch chan<- *prometheus.Desc) {
166166
ch <- MetricDescriptions.DriveCapacityBytes
167167

168168
ch <- MetricDescriptions.NodeISCSISessions
169+
170+
ch <- MetricDescriptions.VolumeCount
171+
ch <- MetricDescriptions.AccountCount
172+
ch <- MetricDescriptions.ClusterAdminCount
173+
ch <- MetricDescriptions.InitiatorCount
174+
ch <- MetricDescriptions.VolumeAccessGroupCount
169175
}
170176

171-
func (c *SolidfireCollector) collectVolumeMeta(ctx context.Context) error {
177+
func (c *SolidfireCollector) collectVolumeMeta(ctx context.Context, ch chan<- prometheus.Metric) error {
172178
volumes, err := c.client.ListVolumes(ctx)
173179
if err != nil {
174180
return err
175181
}
176182
mu.Lock()
177183
defer mu.Unlock()
184+
185+
ch <- prometheus.MustNewConstMetric(
186+
MetricDescriptions.VolumeCount,
187+
prometheus.CounterValue,
188+
float64(len(volumes.Result.Volumes)),
189+
)
190+
178191
for _, vol := range volumes.Result.Volumes {
179192
c.volumeNamesByID[vol.VolumeID] = vol.Name
180193
}
@@ -218,6 +231,7 @@ func (c *SolidfireCollector) collectNodeMeta(ctx context.Context, ch chan<- prom
218231
}
219232
return nil
220233
}
234+
221235
func (c *SolidfireCollector) collectVolumeStats(ctx context.Context, ch chan<- prometheus.Metric) error {
222236
volumeStats, err := c.client.ListVolumeStats(ctx)
223237
if err != nil {
@@ -1251,6 +1265,65 @@ func (c *SolidfireCollector) collectISCSISessions(ctx context.Context, ch chan<-
12511265
return nil
12521266
}
12531267

1268+
func (c *SolidfireCollector) collectAccounts(ctx context.Context, ch chan<- prometheus.Metric) error {
1269+
accounts, err := c.client.ListAccounts(ctx)
1270+
if err != nil {
1271+
return err
1272+
}
1273+
mu.Lock()
1274+
defer mu.Unlock()
1275+
ch <- prometheus.MustNewConstMetric(
1276+
MetricDescriptions.AccountCount,
1277+
prometheus.CounterValue,
1278+
float64(len(accounts.Result.Accounts)),
1279+
)
1280+
return nil
1281+
}
1282+
1283+
func (c *SolidfireCollector) collectClusterAdmins(ctx context.Context, ch chan<- prometheus.Metric) error {
1284+
clusterAdmins, err := c.client.ListClusterAdmins(ctx)
1285+
if err != nil {
1286+
return err
1287+
}
1288+
mu.Lock()
1289+
defer mu.Unlock()
1290+
ch <- prometheus.MustNewConstMetric(
1291+
MetricDescriptions.ClusterAdminCount,
1292+
prometheus.CounterValue,
1293+
float64(len(clusterAdmins.Result.ClusterAdmins)),
1294+
)
1295+
return nil
1296+
}
1297+
1298+
func (c *SolidfireCollector) collectInitiators(ctx context.Context, ch chan<- prometheus.Metric) error {
1299+
initiators, err := c.client.ListInitiators(ctx)
1300+
if err != nil {
1301+
return err
1302+
}
1303+
mu.Lock()
1304+
defer mu.Unlock()
1305+
ch <- prometheus.MustNewConstMetric(
1306+
MetricDescriptions.InitiatorCount,
1307+
prometheus.CounterValue,
1308+
float64(len(initiators.Result.Initiators)),
1309+
)
1310+
return nil
1311+
}
1312+
func (c *SolidfireCollector) collectVolumeAccessGroups(ctx context.Context, ch chan<- prometheus.Metric) error {
1313+
volumeAccessGroups, err := c.client.ListVolumeAccessGroups(ctx)
1314+
if err != nil {
1315+
return err
1316+
}
1317+
mu.Lock()
1318+
defer mu.Unlock()
1319+
ch <- prometheus.MustNewConstMetric(
1320+
MetricDescriptions.VolumeAccessGroupCount,
1321+
prometheus.CounterValue,
1322+
float64(len(volumeAccessGroups.Result.VolumeAccessGroups)),
1323+
)
1324+
return nil
1325+
}
1326+
12541327
func (c *SolidfireCollector) Collect(ch chan<- prometheus.Metric) {
12551328
var up float64 = 0
12561329
defer func() { ch <- prometheus.MustNewConstMetric(MetricDescriptions.upDesc, prometheus.GaugeValue, up) }()
@@ -1259,7 +1332,7 @@ func (c *SolidfireCollector) Collect(ch chan<- prometheus.Metric) {
12591332

12601333
metadataGroup, ctx := errgroup.WithContext(parentCtx)
12611334
metadataGroup.Go(func() error {
1262-
return c.collectVolumeMeta(ctx)
1335+
return c.collectVolumeMeta(ctx, ch)
12631336
})
12641337
metadataGroup.Go(func() error {
12651338
return c.collectNodeMeta(ctx, ch)
@@ -1296,6 +1369,18 @@ func (c *SolidfireCollector) Collect(ch chan<- prometheus.Metric) {
12961369
metricsGroup.Go(func() error {
12971370
return c.collectISCSISessions(ctx, ch)
12981371
})
1372+
metricsGroup.Go(func() error {
1373+
return c.collectAccounts(ctx, ch)
1374+
})
1375+
metricsGroup.Go(func() error {
1376+
return c.collectClusterAdmins(ctx, ch)
1377+
})
1378+
metricsGroup.Go(func() error {
1379+
return c.collectInitiators(ctx, ch)
1380+
})
1381+
metricsGroup.Go(func() error {
1382+
return c.collectVolumeAccessGroups(ctx, ch)
1383+
})
12991384
if err := metricsGroup.Wait(); err != nil {
13001385
log.Errorln(err)
13011386
return

pkg/prom/collector_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,5 +231,33 @@ func newMockedClient(t *testing.T, mockErrs mockErrors) *testutils.MockSolidfire
231231
require.NoError(t, json.Unmarshal(bytes, &listVolumeStatsResponse))
232232
mockSfClient.On(string(call), mock.Anything).Return(listVolumeStatsResponse, mockErrs[call])
233233

234+
listAccountsResponse := solidfire.ListAccountsResponse{}
235+
call = solidfire.RPCListAccounts
236+
bytes, err = ioutil.ReadFile(testutils.ResolveFixturePath(fixtureBasePath, call))
237+
require.NoError(t, err)
238+
require.NoError(t, json.Unmarshal(bytes, &listAccountsResponse))
239+
mockSfClient.On(string(call), mock.Anything).Return(listAccountsResponse, mockErrs[call])
240+
241+
listClusterAdminsResponse := solidfire.ListClusterAdminsResponse{}
242+
call = solidfire.RPCListClusterAdmins
243+
bytes, err = ioutil.ReadFile(testutils.ResolveFixturePath(fixtureBasePath, call))
244+
require.NoError(t, err)
245+
require.NoError(t, json.Unmarshal(bytes, &listClusterAdminsResponse))
246+
mockSfClient.On(string(call), mock.Anything).Return(listClusterAdminsResponse, mockErrs[call])
247+
248+
listInitiatorsResponse := solidfire.ListInitiatorsResponse{}
249+
call = solidfire.RPCListInitiators
250+
bytes, err = ioutil.ReadFile(testutils.ResolveFixturePath(fixtureBasePath, call))
251+
require.NoError(t, err)
252+
require.NoError(t, json.Unmarshal(bytes, &listInitiatorsResponse))
253+
mockSfClient.On(string(call), mock.Anything).Return(listInitiatorsResponse, mockErrs[call])
254+
255+
listVolumeAccessGroupsResponse := solidfire.ListVolumeAccessGroupsResponse{}
256+
call = solidfire.RPCListVolumeAccessGroups
257+
bytes, err = ioutil.ReadFile(testutils.ResolveFixturePath(fixtureBasePath, call))
258+
require.NoError(t, err)
259+
require.NoError(t, json.Unmarshal(bytes, &listVolumeAccessGroupsResponse))
260+
mockSfClient.On(string(call), mock.Anything).Return(listVolumeAccessGroupsResponse, mockErrs[call])
261+
234262
return mockSfClient
235263
}

pkg/prom/metrics.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ type Descriptions struct {
141141

142142
NodeISCSISessions *prometheus.Desc
143143
//NodeISCSIVolumes *prometheus.Desc
144+
145+
InitiatorCount *prometheus.Desc
146+
AccountCount *prometheus.Desc
147+
ClusterAdminCount *prometheus.Desc
148+
VolumeCount *prometheus.Desc
149+
VolumeAccessGroupCount *prometheus.Desc
150+
VolumeAccessGroupLun *prometheus.Desc
144151
}
145152

146153
func NewMetricDescriptions(namespace string) *Descriptions {
@@ -926,5 +933,40 @@ func NewMetricDescriptions(namespace string) *Descriptions {
926933
nil,
927934
)
928935

936+
d.VolumeCount = prometheus.NewDesc(
937+
prometheus.BuildFQName(namespace, "", "cluster_volume_count"),
938+
"The total number of volumes in cluster",
939+
nil,
940+
nil,
941+
)
942+
943+
d.AccountCount = prometheus.NewDesc(
944+
prometheus.BuildFQName(namespace, "", "cluster_account_count"),
945+
"The total number of accounts in cluster",
946+
nil,
947+
nil,
948+
)
949+
950+
d.ClusterAdminCount = prometheus.NewDesc(
951+
prometheus.BuildFQName(namespace, "", "cluster_admin_account"),
952+
"The total number of admin accounts in the cluster",
953+
nil,
954+
nil,
955+
)
956+
957+
d.InitiatorCount = prometheus.NewDesc(
958+
prometheus.BuildFQName(namespace, "", "cluster_initiator_count"),
959+
"The total number of initiators in cluster",
960+
nil,
961+
nil,
962+
)
963+
964+
d.VolumeAccessGroupCount = prometheus.NewDesc(
965+
prometheus.BuildFQName(namespace, "", "cluster_volume_access_group_count"),
966+
"The total number of volume access groups in cluster",
967+
nil,
968+
nil,
969+
)
970+
929971
return &d
930972
}

pkg/solidfire/solidfire.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ const (
2929
RPCListVolumeQoSHistograms RPC = "ListVolumeQoSHistograms"
3030
RPCListVolumes RPC = "ListVolumes"
3131
RPCListVolumeStats RPC = "ListVolumeStats"
32+
RPCListAccounts RPC = "ListAccounts"
33+
RPCListClusterAdmins RPC = "ListClusterAdmins"
34+
RPCListInitiators RPC = "ListInitiators"
35+
RPCListVolumeAccessGroups RPC = "ListVolumeAccessGroups"
3236
)
3337

3438
func NewSolidfireClient() (*Client, error) {
@@ -324,3 +328,91 @@ func (s *Client) ListISCSISessions(ctx context.Context) (ListISCSISessionsRespon
324328
}
325329
return r, nil
326330
}
331+
332+
func (s *Client) ListClusterAdmins(ctx context.Context) (ListClusterAdminsResponse, error) {
333+
payload := &RPCBody{
334+
Method: RPCListClusterAdmins,
335+
Params: ListClusterAdminsParams{},
336+
ID: 1,
337+
}
338+
339+
payloadBytes, err := json.Marshal(&payload)
340+
r := ListClusterAdminsResponse{}
341+
bodyBytes, err := s.doRpcCall(ctx, payloadBytes)
342+
343+
if err != nil {
344+
return r, err
345+
}
346+
err = json.Unmarshal(bodyBytes, &r)
347+
348+
if err != nil {
349+
return r, err
350+
}
351+
return r, nil
352+
}
353+
354+
func (s *Client) ListAccounts(ctx context.Context) (ListAccountsResponse, error) {
355+
payload := &RPCBody{
356+
Method: RPCListAccounts,
357+
Params: ListAccountsParams{},
358+
ID: 1,
359+
}
360+
361+
payloadBytes, err := json.Marshal(&payload)
362+
r := ListAccountsResponse{}
363+
bodyBytes, err := s.doRpcCall(ctx, payloadBytes)
364+
365+
if err != nil {
366+
return r, err
367+
}
368+
err = json.Unmarshal(bodyBytes, &r)
369+
370+
if err != nil {
371+
return r, err
372+
}
373+
return r, nil
374+
}
375+
376+
func (s *Client) ListInitiators(ctx context.Context) (ListInitiatorsResponse, error) {
377+
payload := &RPCBody{
378+
Method: RPCListInitiators,
379+
Params: ListInitiatorsParams{},
380+
ID: 1,
381+
}
382+
383+
payloadBytes, err := json.Marshal(&payload)
384+
r := ListInitiatorsResponse{}
385+
bodyBytes, err := s.doRpcCall(ctx, payloadBytes)
386+
387+
if err != nil {
388+
return r, err
389+
}
390+
err = json.Unmarshal(bodyBytes, &r)
391+
392+
if err != nil {
393+
return r, err
394+
}
395+
return r, nil
396+
}
397+
398+
func (s *Client) ListVolumeAccessGroups(ctx context.Context) (ListVolumeAccessGroupsResponse, error) {
399+
payload := &RPCBody{
400+
Method: RPCListVolumeAccessGroups,
401+
Params: ListVolumeAccessGroupsParams{},
402+
ID: 1,
403+
}
404+
405+
payloadBytes, err := json.Marshal(&payload)
406+
r := ListVolumeAccessGroupsResponse{}
407+
bodyBytes, err := s.doRpcCall(ctx, payloadBytes)
408+
409+
if err != nil {
410+
return r, err
411+
}
412+
err = json.Unmarshal(bodyBytes, &r)
413+
414+
if err != nil {
415+
return r, err
416+
}
417+
return r, nil
418+
}

0 commit comments

Comments
 (0)