summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/modules/cockroachdb/collect.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/go/collectors/go.d.plugin/modules/cockroachdb/collect.go160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/cockroachdb/collect.go b/src/go/collectors/go.d.plugin/modules/cockroachdb/collect.go
new file mode 100644
index 000000000..0cdc2d1d8
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cockroachdb/collect.go
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cockroachdb
+
+import (
+ "errors"
+
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/stm"
+)
+
+func validCockroachDBMetrics(scraped prometheus.Series) bool {
+ return scraped.FindByName("sql_restart_savepoint_count_internal").Len() > 0
+}
+
+func (c *CockroachDB) collect() (map[string]int64, error) {
+ scraped, err := c.prom.ScrapeSeries()
+ if err != nil {
+ return nil, err
+ }
+
+ if !validCockroachDBMetrics(scraped) {
+ return nil, errors.New("returned metrics aren't CockroachDB metrics")
+ }
+
+ mx := collectScraped(scraped, metrics)
+ calcUsableCapacity(mx)
+ calcUnusableCapacity(mx)
+ calcTotalCapacityUsedPercentage(mx)
+ calcUsableCapacityUsedPercentage(mx)
+ calcRocksDBCacheHitRate(mx)
+ calcActiveReplicas(mx)
+ calcCPUUsagePercent(mx)
+
+ return stm.ToMap(mx), nil
+}
+
+const precision = 1000
+
+func collectScraped(scraped prometheus.Series, metricList []string) map[string]float64 {
+ mx := make(map[string]float64)
+ for _, name := range metricList {
+ if ms := scraped.FindByName(name); ms.Len() == 1 {
+ if isMetricFloat(name) {
+ mx[name] = ms.Max() * precision
+ } else {
+ mx[name] = ms.Max()
+ }
+ }
+ }
+ return mx
+}
+
+func calcUsableCapacity(mx map[string]float64) {
+ if !hasAll(mx, metricCapacityAvailable, metricCapacityUsed) {
+ return
+ }
+ available := mx[metricCapacityAvailable]
+ used := mx[metricCapacityUsed]
+
+ mx[metricCapacityUsable] = available + used
+}
+
+func calcUnusableCapacity(mx map[string]float64) {
+ if !hasAll(mx, metricCapacity, metricCapacityAvailable, metricCapacityUsed) {
+ return
+ }
+ total := mx[metricCapacity]
+ available := mx[metricCapacityAvailable]
+ used := mx[metricCapacityUsed]
+
+ mx[metricCapacityUnusable] = total - (available + used)
+}
+
+func calcTotalCapacityUsedPercentage(mx map[string]float64) {
+ if !hasAll(mx, metricCapacity, metricCapacityUnusable, metricCapacityUsed) {
+ return
+ }
+ total := mx[metricCapacity]
+ unusable := mx[metricCapacityUnusable]
+ used := mx[metricCapacityUsed]
+
+ if mx[metricCapacity] == 0 {
+ mx[metricCapacityUsedPercentage] = 0
+ } else {
+ mx[metricCapacityUsedPercentage] = (unusable + used) / total * 100 * precision
+ }
+}
+
+func calcUsableCapacityUsedPercentage(mx map[string]float64) {
+ if !hasAll(mx, metricCapacityUsable, metricCapacityUsed) {
+ return
+ }
+ usable := mx[metricCapacityUsable]
+ used := mx[metricCapacityUsed]
+
+ if usable == 0 {
+ mx[metricCapacityUsableUsedPercentage] = 0
+ } else {
+ mx[metricCapacityUsableUsedPercentage] = used / usable * 100 * precision
+ }
+}
+
+func calcRocksDBCacheHitRate(mx map[string]float64) {
+ if !hasAll(mx, metricRocksDBBlockCacheHits, metricRocksDBBlockCacheMisses) {
+ return
+ }
+ hits := mx[metricRocksDBBlockCacheHits]
+ misses := mx[metricRocksDBBlockCacheMisses]
+
+ if sum := hits + misses; sum == 0 {
+ mx[metricRocksDBBlockCacheHitRate] = 0
+ } else {
+ mx[metricRocksDBBlockCacheHitRate] = hits / sum * 100 * precision
+ }
+}
+
+func calcActiveReplicas(mx map[string]float64) {
+ if !hasAll(mx, metricReplicasQuiescent) {
+ return
+ }
+ total := mx[metricReplicas]
+ quiescent := mx[metricReplicasQuiescent]
+
+ mx[metricReplicasActive] = total - quiescent
+}
+
+func calcCPUUsagePercent(mx map[string]float64) {
+ if hasAll(mx, metricSysCPUUserPercent) {
+ mx[metricSysCPUUserPercent] *= 100
+ }
+ if hasAll(mx, metricSysCPUSysPercent) {
+ mx[metricSysCPUSysPercent] *= 100
+ }
+ if hasAll(mx, metricSysCPUCombinedPercentNormalized) {
+ mx[metricSysCPUCombinedPercentNormalized] *= 100
+ }
+}
+
+func isMetricFloat(name string) bool {
+ // only Float metrics (see NewGaugeFloat64 in the cockroach repo):
+ // - GcPausePercent, CPUUserPercent, CPUCombinedPercentNorm, AverageQueriesPerSecond, AverageWritesPerSecond
+ switch name {
+ case metricSysCPUUserPercent,
+ metricSysCPUSysPercent,
+ metricSysCPUCombinedPercentNormalized,
+ metricRebalancingQueriesPerSecond,
+ metricRebalancingWritesPerSecond:
+ return true
+ }
+ return false
+}
+
+func hasAll(mx map[string]float64, key string, rest ...string) bool {
+ _, ok := mx[key]
+ if len(rest) == 0 {
+ return ok
+ }
+ return ok && hasAll(mx, rest[0], rest[1:]...)
+}