diff options
Diffstat (limited to '')
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/cockroachdb/collect.go | 160 |
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..1636a14d6 --- /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 { + for _, m := range scraped.FindByName(name) { + if isMetricFloat(name) { + mx[name] += m.Value * precision + } else { + mx[name] += m.Value + } + } + } + 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:]...) +} |