| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package k8s_kubeproxy |
| 4 | |
| 5 | import ( |
| 6 | "math" |
| 7 | "strings" |
| 8 | |
| 9 | "github.com/netdata/netdata/go/plugins/pkg/prometheus" |
| 10 | "github.com/netdata/netdata/go/plugins/pkg/stm" |
| 11 | "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi" |
| 12 | mtx "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/oldmetrix" |
| 13 | ) |
| 14 | |
| 15 | func (c *Collector) collect() (map[string]int64, error) { |
| 16 | raw, err := c.prom.ScrapeSeries() |
| 17 | |
| 18 | if err != nil { |
| 19 | return nil, err |
| 20 | } |
| 21 | |
| 22 | mx := newMetrics() |
| 23 | |
| 24 | c.collectSyncProxyRules(raw, mx) |
| 25 | c.collectRESTClientHTTPRequests(raw, mx) |
| 26 | c.collectHTTPRequestDuration(raw, mx) |
| 27 | |
| 28 | return stm.ToMap(mx), nil |
| 29 | } |
| 30 | |
| 31 | func (c *Collector) collectSyncProxyRules(raw prometheus.Series, mx *metrics) { |
| 32 | m := raw.FindByName("kubeproxy_sync_proxy_rules_latency_microseconds_count") |
| 33 | mx.SyncProxyRules.Count.Set(m.Max()) |
| 34 | c.collectSyncProxyRulesLatency(raw, mx) |
| 35 | } |
| 36 | |
| 37 | func (c *Collector) collectSyncProxyRulesLatency(raw prometheus.Series, mx *metrics) { |
| 38 | metricName := "kubeproxy_sync_proxy_rules_latency_microseconds_bucket" |
| 39 | latency := &mx.SyncProxyRules.Latency |
| 40 | |
| 41 | for _, metric := range raw.FindByName(metricName) { |
| 42 | value := metric.Value |
| 43 | bucket := strings.TrimSuffix(metric.Labels.Get("le"), ".0") |
| 44 | switch bucket { |
| 45 | case "1000": |
| 46 | latency.LE1000.Set(value) |
| 47 | case "2000": |
| 48 | latency.LE2000.Set(value) |
| 49 | case "4000": |
| 50 | latency.LE4000.Set(value) |
| 51 | case "8000": |
| 52 | latency.LE8000.Set(value) |
| 53 | case "16000": |
| 54 | latency.LE16000.Set(value) |
| 55 | case "32000": |
| 56 | latency.LE32000.Set(value) |
| 57 | case "64000": |
| 58 | latency.LE64000.Set(value) |
| 59 | case "128000": |
| 60 | latency.LE128000.Set(value) |
| 61 | case "256000": |
| 62 | latency.LE256000.Set(value) |
| 63 | case "512000": |
| 64 | latency.LE512000.Set(value) |
| 65 | case "1.024e+06": |
| 66 | latency.LE1024000.Set(value) |
| 67 | case "2.048e+06": |
| 68 | latency.LE2048000.Set(value) |
| 69 | case "4.096e+06": |
| 70 | latency.LE4096000.Set(value) |
| 71 | case "8.192e+06": |
| 72 | latency.LE8192000.Set(value) |
| 73 | case "1.6384e+07": |
| 74 | latency.LE16384000.Set(value) |
| 75 | case "+Inf": |
| 76 | latency.Inf.Set(value) |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | latency.Inf.Sub(latency.LE16384000.Value()) |
| 81 | latency.LE16384000.Sub(latency.LE8192000.Value()) |
| 82 | latency.LE8192000.Sub(latency.LE4096000.Value()) |
| 83 | latency.LE4096000.Sub(latency.LE2048000.Value()) |
| 84 | latency.LE2048000.Sub(latency.LE1024000.Value()) |
| 85 | latency.LE1024000.Sub(latency.LE512000.Value()) |
| 86 | latency.LE512000.Sub(latency.LE256000.Value()) |
| 87 | latency.LE256000.Sub(latency.LE128000.Value()) |
| 88 | latency.LE128000.Sub(latency.LE64000.Value()) |
| 89 | latency.LE64000.Sub(latency.LE32000.Value()) |
| 90 | latency.LE32000.Sub(latency.LE16000.Value()) |
| 91 | latency.LE16000.Sub(latency.LE8000.Value()) |
| 92 | latency.LE8000.Sub(latency.LE4000.Value()) |
| 93 | latency.LE4000.Sub(latency.LE2000.Value()) |
| 94 | latency.LE2000.Sub(latency.LE1000.Value()) |
| 95 | } |
| 96 | |
| 97 | func (c *Collector) collectRESTClientHTTPRequests(raw prometheus.Series, mx *metrics) { |
| 98 | metricName := "rest_client_requests_total" |
| 99 | chart := c.charts.Get("rest_client_requests_by_code") |
| 100 | |
| 101 | for _, metric := range raw.FindByName(metricName) { |
| 102 | code := metric.Labels.Get("code") |
| 103 | if code == "" { |
| 104 | continue |
| 105 | } |
| 106 | dimID := "rest_client_requests_" + code |
| 107 | if !chart.HasDim(dimID) { |
| 108 | _ = chart.AddDim(&Dim{ID: dimID, Name: code, Algo: collectorapi.Incremental}) |
| 109 | chart.MarkNotCreated() |
| 110 | } |
| 111 | mx.RESTClient.Requests.ByStatusCode[code] = mtx.Gauge(metric.Value) |
| 112 | } |
| 113 | |
| 114 | chart = c.charts.Get("rest_client_requests_by_method") |
| 115 | |
| 116 | for _, metric := range raw.FindByName(metricName) { |
| 117 | method := metric.Labels.Get("method") |
| 118 | if method == "" { |
| 119 | continue |
| 120 | } |
| 121 | dimID := "rest_client_requests_" + method |
| 122 | if !chart.HasDim(dimID) { |
| 123 | _ = chart.AddDim(&Dim{ID: dimID, Name: method, Algo: collectorapi.Incremental}) |
| 124 | chart.MarkNotCreated() |
| 125 | } |
| 126 | mx.RESTClient.Requests.ByMethod[method] = mtx.Gauge(metric.Value) |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | func (c *Collector) collectHTTPRequestDuration(raw prometheus.Series, mx *metrics) { |
| 131 | // Summary |
| 132 | for _, metric := range raw.FindByName("http_request_duration_microseconds") { |
| 133 | if math.IsNaN(metric.Value) { |
| 134 | continue |
| 135 | } |
| 136 | quantile := metric.Labels.Get("quantile") |
| 137 | switch quantile { |
| 138 | case "0.5": |
| 139 | mx.HTTP.Request.Duration.Quantile05.Set(metric.Value) |
| 140 | case "0.9": |
| 141 | mx.HTTP.Request.Duration.Quantile09.Set(metric.Value) |
| 142 | case "0.99": |
| 143 | mx.HTTP.Request.Duration.Quantile099.Set(metric.Value) |
| 144 | } |
| 145 | } |
| 146 | } |