Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

Commit ef82cb8

Browse files
authoredDec 29, 2019
Merge pull request #36 from ag0n1k/DMP-3004-queues
Added ability to track storage-engine metrics
2 parents 46ba280 + ec56f34 commit ef82cb8

File tree

1 file changed

+86
-7
lines changed

1 file changed

+86
-7
lines changed
 

‎namespaces.go

+86-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"bytes"
45
"strings"
56

67
as "github.com/aerospike/aerospike-client-go"
@@ -90,8 +91,6 @@ var (
9091
counter("client_write_error", "client write error"),
9192
counter("client_write_success", "client write success"),
9293
counter("client_write_timeout", "client write timeout"),
93-
counter("defrag_reads", "defrag reads"),
94-
counter("defrag_writes", "defrag writes"),
9594
counter("evicted_objects", "evicted objects"),
9695
counter("expired_objects", "expired objects"),
9796
counter("fail_generation", "fail generation"),
@@ -166,7 +165,6 @@ var (
166165
counter("xdr_write_success", "xdr write success"),
167166
counter("xdr_write_timeout", "xdr write timeout"),
168167
gauge("available_bin_names", "available bin names"),
169-
// broken gauge("defrag_q", "defrag queue"),
170168
gauge("device_available_pct", "device available pct"),
171169
gauge("device_compression_ratio", "device compression ratio"),
172170
gauge("device_free_pct", "device free pct"),
@@ -216,7 +214,6 @@ var (
216214
gauge("prole_objects", "prole objects"),
217215
gauge("prole_tombstones", "prole tombstones"),
218216
gauge("replication-factor", "replication factor"),
219-
// broken gauge("shadow_write_q", "shadow write queue"),
220217
gauge("stop_writes", "stop writes"),
221218
gauge("stop-writes-pct", "stop writes pct"),
222219
gauge("tombstones", "tombstones"),
@@ -225,10 +222,16 @@ var (
225222
gauge("dead_partitions", "dead partitions"),
226223
gauge("unavailable_partitions", "unavailable partitions"),
227224
gauge("rack-id", "rack id"),
228-
// gauge("write_q", "write queue"),
229225
// device-level stats don't appear to work
230226
// and this plugin thinks "storage-engine.device[0].write_q" is malformed.
231227
}
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+
}
232235
)
233236

234237
type nsCollector cmetrics
@@ -246,6 +249,18 @@ func newNSCollector() nsCollector {
246249
),
247250
}
248251
}
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+
249264
return ns
250265
}
251266

@@ -255,21 +270,85 @@ func (nc nsCollector) describe(ch chan<- *prometheus.Desc) {
255270
}
256271
}
257272

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+
258321
func (nc nsCollector) collect(conn *as.Connection) ([]prometheus.Metric, error) {
259322
info, err := as.RequestInfo(conn, "namespaces")
260323
if err != nil {
261324
return nil, err
262325
}
263326
var metrics []prometheus.Metric
264327
for _, ns := range strings.Split(info["namespaces"], ";") {
265-
nsinfo, err := as.RequestInfo(conn, "namespace/"+ns)
328+
nsInfo, err := as.RequestInfo(conn, "namespace/"+ns)
266329
if err != nil {
267330
return nil, err
268331
}
332+
333+
nsInfoStorage, nsInfoStandard, nsInfoStorageDevices := nc.splitInfo(nsInfo["namespace/"+ns])
334+
269335
metrics = append(
270336
metrics,
271-
infoCollect(cmetrics(nc), nsinfo["namespace/"+ns], ns)...,
337+
infoCollect(cmetrics(nc), nsInfoStandard, ns)...,
272338
)
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+
}
273352
}
274353
return metrics, nil
275354
}

0 commit comments

Comments
 (0)