| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package couchbase |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "net/url" |
| 8 | |
| 9 | "github.com/netdata/netdata/go/plugins/pkg/web" |
| 10 | "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi" |
| 11 | ) |
| 12 | |
| 13 | const ( |
| 14 | urlPathBucketsStats = "/pools/default/buckets" |
| 15 | |
| 16 | precision = 1000 |
| 17 | ) |
| 18 | |
| 19 | func (c *Collector) collect() (map[string]int64, error) { |
| 20 | ms, err := c.scrapeCouchbase() |
| 21 | if err != nil { |
| 22 | return nil, fmt.Errorf("error on scraping couchbase: %v", err) |
| 23 | } |
| 24 | if ms.empty() { |
| 25 | return nil, nil |
| 26 | } |
| 27 | |
| 28 | collected := make(map[string]int64) |
| 29 | c.collectBasicStats(collected, ms) |
| 30 | |
| 31 | return collected, nil |
| 32 | } |
| 33 | |
| 34 | func (c *Collector) collectBasicStats(collected map[string]int64, ms *cbMetrics) { |
| 35 | for _, b := range ms.BucketsBasicStats { |
| 36 | |
| 37 | if !c.collectedBuckets[b.Name] { |
| 38 | c.collectedBuckets[b.Name] = true |
| 39 | c.addBucketToCharts(b.Name) |
| 40 | } |
| 41 | |
| 42 | bs := b.BasicStats |
| 43 | collected[indexDimID(b.Name, "quota_percent_used")] = int64(bs.QuotaPercentUsed * precision) |
| 44 | collected[indexDimID(b.Name, "ops_per_sec")] = int64(bs.OpsPerSec * precision) |
| 45 | collected[indexDimID(b.Name, "disk_fetches")] = int64(bs.DiskFetches) |
| 46 | collected[indexDimID(b.Name, "item_count")] = int64(bs.ItemCount) |
| 47 | collected[indexDimID(b.Name, "disk_used")] = int64(bs.DiskUsed) |
| 48 | collected[indexDimID(b.Name, "data_used")] = int64(bs.DataUsed) |
| 49 | collected[indexDimID(b.Name, "mem_used")] = int64(bs.MemUsed) |
| 50 | collected[indexDimID(b.Name, "vb_active_num_non_resident")] = int64(bs.VbActiveNumNonResident) |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | func (c *Collector) addBucketToCharts(bucket string) { |
| 55 | c.addDimToChart(bucketQuotaPercentUsedChart.ID, &collectorapi.Dim{ |
| 56 | ID: indexDimID(bucket, "quota_percent_used"), |
| 57 | Name: bucket, |
| 58 | Div: precision, |
| 59 | }) |
| 60 | |
| 61 | c.addDimToChart(bucketOpsPerSecChart.ID, &collectorapi.Dim{ |
| 62 | ID: indexDimID(bucket, "ops_per_sec"), |
| 63 | Name: bucket, |
| 64 | Div: precision, |
| 65 | }) |
| 66 | |
| 67 | c.addDimToChart(bucketDiskFetchesChart.ID, &collectorapi.Dim{ |
| 68 | ID: indexDimID(bucket, "disk_fetches"), |
| 69 | Name: bucket, |
| 70 | }) |
| 71 | |
| 72 | c.addDimToChart(bucketItemCountChart.ID, &collectorapi.Dim{ |
| 73 | ID: indexDimID(bucket, "item_count"), |
| 74 | Name: bucket, |
| 75 | }) |
| 76 | |
| 77 | c.addDimToChart(bucketDiskUsedChart.ID, &collectorapi.Dim{ |
| 78 | ID: indexDimID(bucket, "disk_used"), |
| 79 | Name: bucket, |
| 80 | }) |
| 81 | |
| 82 | c.addDimToChart(bucketDataUsedChart.ID, &collectorapi.Dim{ |
| 83 | ID: indexDimID(bucket, "data_used"), |
| 84 | Name: bucket, |
| 85 | }) |
| 86 | |
| 87 | c.addDimToChart(bucketMemUsedChart.ID, &collectorapi.Dim{ |
| 88 | ID: indexDimID(bucket, "mem_used"), |
| 89 | Name: bucket, |
| 90 | }) |
| 91 | |
| 92 | c.addDimToChart(bucketVBActiveNumNonResidentChart.ID, &collectorapi.Dim{ |
| 93 | ID: indexDimID(bucket, "vb_active_num_non_resident"), |
| 94 | Name: bucket, |
| 95 | }) |
| 96 | } |
| 97 | |
| 98 | func (c *Collector) addDimToChart(chartID string, dim *collectorapi.Dim) { |
| 99 | chart := c.Charts().Get(chartID) |
| 100 | if chart == nil { |
| 101 | c.Warningf("error on adding '%s' dimension: can not find '%s' chart", dim.ID, chartID) |
| 102 | return |
| 103 | } |
| 104 | if err := chart.AddDim(dim); err != nil { |
| 105 | c.Warning(err) |
| 106 | return |
| 107 | } |
| 108 | chart.MarkNotCreated() |
| 109 | } |
| 110 | |
| 111 | func (c *Collector) scrapeCouchbase() (*cbMetrics, error) { |
| 112 | req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathBucketsStats) |
| 113 | if err != nil { |
| 114 | return nil, err |
| 115 | } |
| 116 | req.URL.RawQuery = url.Values{"skipMap": []string{"true"}}.Encode() |
| 117 | |
| 118 | ms := &cbMetrics{} |
| 119 | if err := web.DoHTTP(c.httpClient).RequestJSON(req, &ms.BucketsBasicStats); err != nil { |
| 120 | return nil, err |
| 121 | } |
| 122 | |
| 123 | return ms, nil |
| 124 | } |
| 125 | |
| 126 | func indexDimID(name, metric string) string { |
| 127 | return fmt.Sprintf("bucket_%s_%s", name, metric) |
| 128 | } |