1
1
package main
2
2
3
3
import (
4
+ "bytes"
4
5
"strings"
5
6
6
7
as "github.com/aerospike/aerospike-client-go"
90
91
counter ("client_write_error" , "client write error" ),
91
92
counter ("client_write_success" , "client write success" ),
92
93
counter ("client_write_timeout" , "client write timeout" ),
93
- counter ("defrag_reads" , "defrag reads" ),
94
- counter ("defrag_writes" , "defrag writes" ),
95
94
counter ("evicted_objects" , "evicted objects" ),
96
95
counter ("expired_objects" , "expired objects" ),
97
96
counter ("fail_generation" , "fail generation" ),
@@ -166,7 +165,6 @@ var (
166
165
counter ("xdr_write_success" , "xdr write success" ),
167
166
counter ("xdr_write_timeout" , "xdr write timeout" ),
168
167
gauge ("available_bin_names" , "available bin names" ),
169
- // broken gauge("defrag_q", "defrag queue"),
170
168
gauge ("device_available_pct" , "device available pct" ),
171
169
gauge ("device_compression_ratio" , "device compression ratio" ),
172
170
gauge ("device_free_pct" , "device free pct" ),
@@ -216,7 +214,6 @@ var (
216
214
gauge ("prole_objects" , "prole objects" ),
217
215
gauge ("prole_tombstones" , "prole tombstones" ),
218
216
gauge ("replication-factor" , "replication factor" ),
219
- // broken gauge("shadow_write_q", "shadow write queue"),
220
217
gauge ("stop_writes" , "stop writes" ),
221
218
gauge ("stop-writes-pct" , "stop writes pct" ),
222
219
gauge ("tombstones" , "tombstones" ),
@@ -225,10 +222,16 @@ var (
225
222
gauge ("dead_partitions" , "dead partitions" ),
226
223
gauge ("unavailable_partitions" , "unavailable partitions" ),
227
224
gauge ("rack-id" , "rack id" ),
228
- // gauge("write_q", "write queue"),
229
225
// device-level stats don't appear to work
230
226
// and this plugin thinks "storage-engine.device[0].write_q" is malformed.
231
227
}
228
+ NamespaceStorageMetrics = []metric {
229
+ counter ("defrag_reads" , "defrag reads" ),
230
+ counter ("defrag_writes" , "defrag writes" ),
231
+ gauge ("shadow_write_q" , "shadow write queue" ),
232
+ gauge ("defrag_q" , "defrag queue" ),
233
+ gauge ("write_q" , "write queue" ),
234
+ }
232
235
)
233
236
234
237
type nsCollector cmetrics
@@ -246,6 +249,18 @@ func newNSCollector() nsCollector {
246
249
),
247
250
}
248
251
}
252
+ for _ , m := range NamespaceStorageMetrics {
253
+ ns [m .aeroName ] = cmetric {
254
+ typ : m .typ ,
255
+ desc : prometheus .NewDesc (
256
+ promkey (systemNamespace , m .aeroName ),
257
+ m .desc ,
258
+ []string {"namespace" , "mount" },
259
+ nil ,
260
+ ),
261
+ }
262
+ }
263
+
249
264
return ns
250
265
}
251
266
@@ -255,21 +270,85 @@ func (nc nsCollector) describe(ch chan<- *prometheus.Desc) {
255
270
}
256
271
}
257
272
273
+ func (nc nsCollector ) parseStorage (s string , d string ) (string , error ) {
274
+ // the function remove the storage prefix metrics for each device:
275
+ // d is storage-engine.device[ix]
276
+ // s is all storage metrics that has been scraped
277
+ // storage-engine.device[ix].age -> age
278
+ // https://www.aerospike.com/docs/reference/metrics/#storage-engine.device[ix].age
279
+ buf := bytes.Buffer {}
280
+ for _ , l := range strings .Split (s , ";" ) {
281
+ for _ , v := range strings .Split (l , ":" ) {
282
+ kv := strings .SplitN (v , "=" , 2 )
283
+ if len (kv ) > 1 {
284
+ if strings .HasPrefix (kv [0 ], d ) {
285
+ //todo: optimize
286
+ kv [0 ] = strings .Replace (kv [0 ]+ "." , d , "" , 1 )
287
+ kv [0 ] = strings .Replace (kv [0 ], "." , "" , - 1 )
288
+ }
289
+ buf .WriteString (kv [0 ] + "=" + kv [1 ] + ";" )
290
+ }
291
+ }
292
+ }
293
+ r := buf .String ()
294
+ return r , nil
295
+ }
296
+
297
+ func (nc nsCollector ) splitInfo (s string ) (string , string , map [string ]string ) {
298
+ nsStorageMounts := map [string ]string {}
299
+
300
+ bufStandardMetrics := bytes.Buffer {}
301
+ bufStorageMetrics := bytes.Buffer {}
302
+
303
+ for _ , l := range strings .Split (s , ";" ) {
304
+ for _ , v := range strings .Split (l , ":" ) {
305
+ kv := strings .SplitN (v , "=" , 2 )
306
+ if strings .HasPrefix (kv [0 ], "storage-engine" ) {
307
+ bufStorageMetrics .WriteString (v + ";" )
308
+ if strings .HasSuffix (kv [0 ], "]" ) {
309
+ nsStorageMounts [kv [1 ]] = kv [0 ]
310
+ }
311
+ } else {
312
+ bufStandardMetrics .WriteString (v + ";" )
313
+ }
314
+ }
315
+ }
316
+ nsStandardMetrics := bufStandardMetrics .String ()
317
+ nsStorageMetrics := bufStorageMetrics .String ()
318
+ return nsStorageMetrics , nsStandardMetrics , nsStorageMounts
319
+ }
320
+
258
321
func (nc nsCollector ) collect (conn * as.Connection ) ([]prometheus.Metric , error ) {
259
322
info , err := as .RequestInfo (conn , "namespaces" )
260
323
if err != nil {
261
324
return nil , err
262
325
}
263
326
var metrics []prometheus.Metric
264
327
for _ , ns := range strings .Split (info ["namespaces" ], ";" ) {
265
- nsinfo , err := as .RequestInfo (conn , "namespace/" + ns )
328
+ nsInfo , err := as .RequestInfo (conn , "namespace/" + ns )
266
329
if err != nil {
267
330
return nil , err
268
331
}
332
+
333
+ nsInfoStorage , nsInfoStandard , nsInfoStorageDevices := nc .splitInfo (nsInfo ["namespace/" + ns ])
334
+
269
335
metrics = append (
270
336
metrics ,
271
- infoCollect (cmetrics (nc ), nsinfo [ "namespace/" + ns ] , ns )... ,
337
+ infoCollect (cmetrics (nc ), nsInfoStandard , ns )... ,
272
338
)
339
+
340
+ for mountName , metricName := range nsInfoStorageDevices {
341
+ nsInfoStorage , err = nc .parseStorage (nsInfoStorage , metricName )
342
+
343
+ if err != nil {
344
+ return nil , err
345
+ }
346
+
347
+ metrics = append (
348
+ metrics ,
349
+ infoCollect (cmetrics (nc ), nsInfoStorage , ns , mountName )... ,
350
+ )
351
+ }
273
352
}
274
353
return metrics , nil
275
354
}
0 commit comments