summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy
diff options
context:
space:
mode:
Diffstat (limited to '')
l---------src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/README.md1
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/charts.go108
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/collect.go146
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/config_schema.json177
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/init.go26
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/integrations/kubeproxy.md186
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy.go111
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy_test.go146
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metadata.yaml227
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metrics.go54
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.json20
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.yaml17
-rw-r--r--src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/metrics.txt190
13 files changed, 1409 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/README.md b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/README.md
new file mode 120000
index 000000000..020405250
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/README.md
@@ -0,0 +1 @@
+integrations/kubeproxy.md \ No newline at end of file
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/charts.go b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/charts.go
new file mode 100644
index 000000000..b00097b3f
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/charts.go
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package k8s_kubeproxy
+
+import "github.com/netdata/netdata/go/go.d.plugin/agent/module"
+
+type (
+ // Charts is an alias for module.Charts
+ Charts = module.Charts
+ // Dims is an alias for module.Dims
+ Dims = module.Dims
+ // Dim is an alias for module.Dim
+ Dim = module.Dim
+)
+
+var charts = Charts{
+ {
+ ID: "kubeproxy_sync_proxy_rules",
+ Title: "Sync Proxy Rules",
+ Units: "events/s",
+ Fam: "sync proxy rules",
+ Ctx: "k8s_kubeproxy.kubeproxy_sync_proxy_rules",
+ Dims: Dims{
+ {ID: "sync_proxy_rules_count", Name: "sync proxy rules", Algo: module.Incremental},
+ },
+ },
+ {
+ ID: "kubeproxy_sync_proxy_rules_latency",
+ Title: "Sync Proxy Rules Latency",
+ Units: "observes/s",
+ Fam: "sync proxy rules",
+ Ctx: "k8s_kubeproxy.kubeproxy_sync_proxy_rules_latency_microseconds",
+ Type: module.Stacked,
+ Dims: Dims{
+ {ID: "sync_proxy_rules_bucket_1000", Name: "0.001 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_2000", Name: "0.002 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_4000", Name: "0.004 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_8000", Name: "0.008 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_16000", Name: "0.016 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_32000", Name: "0.032 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_64000", Name: "0.064 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_128000", Name: "0.128 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_256000", Name: "0.256 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_512000", Name: "0.512 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_1024000", Name: "1.024 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_2048000", Name: "2.048 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_4096000", Name: "4.096 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_8192000", Name: "8.192 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_16384000", Name: "16.384 sec", Algo: module.Incremental},
+ {ID: "sync_proxy_rules_bucket_+Inf", Name: "+Inf", Algo: module.Incremental},
+ },
+ },
+ {
+ ID: "kubeproxy_sync_proxy_rules_latency_percentage",
+ Title: "Sync Proxy Rules Latency Percentage",
+ Units: "%",
+ Fam: "sync proxy rules",
+ Ctx: "k8s_kubeproxy.kubeproxy_sync_proxy_rules_latency",
+ Type: module.Stacked,
+ Dims: Dims{
+ {ID: "sync_proxy_rules_bucket_1000", Name: "0.001 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_2000", Name: "0.002 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_4000", Name: "0.004 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_8000", Name: "0.008 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_16000", Name: "0.016 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_32000", Name: "0.032 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_64000", Name: "0.064 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_128000", Name: "0.128 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_256000", Name: "0.256 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_512000", Name: "0.512 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_1024000", Name: "1.024 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_2048000", Name: "2.048 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_4096000", Name: "4.096 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_8192000", Name: "8.192 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_16384000", Name: "16.384 sec", Algo: module.PercentOfIncremental},
+ {ID: "sync_proxy_rules_bucket_+Inf", Name: "+Inf", Algo: module.PercentOfIncremental},
+ },
+ },
+ {
+ ID: "rest_client_requests_by_code",
+ Title: "HTTP Requests By Status Code",
+ Units: "requests/s",
+ Fam: "rest client",
+ Ctx: "k8s_kubeproxy.rest_client_requests_by_code",
+ Type: module.Stacked,
+ },
+ {
+ ID: "rest_client_requests_by_method",
+ Title: "HTTP Requests By Status Method",
+ Units: "requests/s",
+ Fam: "rest client",
+ Ctx: "k8s_kubeproxy.rest_client_requests_by_method",
+ Type: module.Stacked,
+ },
+ {
+ ID: "http_request_duration",
+ Title: "HTTP Requests Duration",
+ Units: "microseconds",
+ Fam: "http",
+ Ctx: "k8s_kubeproxy.http_request_duration",
+ Type: module.Stacked,
+ Dims: Dims{
+ {ID: "http_request_duration_05", Name: "0.5"},
+ {ID: "http_request_duration_09", Name: "0.9"},
+ {ID: "http_request_duration_099", Name: "0.99"},
+ },
+ },
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/collect.go b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/collect.go
new file mode 100644
index 000000000..625713f10
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/collect.go
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package k8s_kubeproxy
+
+import (
+ "math"
+
+ mtx "github.com/netdata/netdata/go/go.d.plugin/pkg/metrics"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/stm"
+
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
+)
+
+func (kp *KubeProxy) collect() (map[string]int64, error) {
+ raw, err := kp.prom.ScrapeSeries()
+
+ if err != nil {
+ return nil, err
+ }
+
+ mx := newMetrics()
+
+ kp.collectSyncProxyRules(raw, mx)
+ kp.collectRESTClientHTTPRequests(raw, mx)
+ kp.collectHTTPRequestDuration(raw, mx)
+
+ return stm.ToMap(mx), nil
+}
+
+func (kp *KubeProxy) collectSyncProxyRules(raw prometheus.Series, mx *metrics) {
+ m := raw.FindByName("kubeproxy_sync_proxy_rules_latency_microseconds_count")
+ mx.SyncProxyRules.Count.Set(m.Max())
+ kp.collectSyncProxyRulesLatency(raw, mx)
+}
+
+func (kp *KubeProxy) collectSyncProxyRulesLatency(raw prometheus.Series, mx *metrics) {
+ metricName := "kubeproxy_sync_proxy_rules_latency_microseconds_bucket"
+ latency := &mx.SyncProxyRules.Latency
+
+ for _, metric := range raw.FindByName(metricName) {
+ bucket := metric.Labels.Get("le")
+ value := metric.Value
+ switch bucket {
+ case "1000":
+ latency.LE1000.Set(value)
+ case "2000":
+ latency.LE2000.Set(value)
+ case "4000":
+ latency.LE4000.Set(value)
+ case "8000":
+ latency.LE8000.Set(value)
+ case "16000":
+ latency.LE16000.Set(value)
+ case "32000":
+ latency.LE32000.Set(value)
+ case "64000":
+ latency.LE64000.Set(value)
+ case "128000":
+ latency.LE128000.Set(value)
+ case "256000":
+ latency.LE256000.Set(value)
+ case "512000":
+ latency.LE512000.Set(value)
+ case "1.024e+06":
+ latency.LE1024000.Set(value)
+ case "2.048e+06":
+ latency.LE2048000.Set(value)
+ case "4.096e+06":
+ latency.LE4096000.Set(value)
+ case "8.192e+06":
+ latency.LE8192000.Set(value)
+ case "1.6384e+07":
+ latency.LE16384000.Set(value)
+ case "+Inf":
+ latency.Inf.Set(value)
+ }
+ }
+
+ latency.Inf.Sub(latency.LE16384000.Value())
+ latency.LE16384000.Sub(latency.LE8192000.Value())
+ latency.LE8192000.Sub(latency.LE4096000.Value())
+ latency.LE4096000.Sub(latency.LE2048000.Value())
+ latency.LE2048000.Sub(latency.LE1024000.Value())
+ latency.LE1024000.Sub(latency.LE512000.Value())
+ latency.LE512000.Sub(latency.LE256000.Value())
+ latency.LE256000.Sub(latency.LE128000.Value())
+ latency.LE128000.Sub(latency.LE64000.Value())
+ latency.LE64000.Sub(latency.LE32000.Value())
+ latency.LE32000.Sub(latency.LE16000.Value())
+ latency.LE16000.Sub(latency.LE8000.Value())
+ latency.LE8000.Sub(latency.LE4000.Value())
+ latency.LE4000.Sub(latency.LE2000.Value())
+ latency.LE2000.Sub(latency.LE1000.Value())
+}
+
+func (kp *KubeProxy) collectRESTClientHTTPRequests(raw prometheus.Series, mx *metrics) {
+ metricName := "rest_client_requests_total"
+ chart := kp.charts.Get("rest_client_requests_by_code")
+
+ for _, metric := range raw.FindByName(metricName) {
+ code := metric.Labels.Get("code")
+ if code == "" {
+ continue
+ }
+ dimID := "rest_client_requests_" + code
+ if !chart.HasDim(dimID) {
+ _ = chart.AddDim(&Dim{ID: dimID, Name: code, Algo: module.Incremental})
+ chart.MarkNotCreated()
+ }
+ mx.RESTClient.Requests.ByStatusCode[code] = mtx.Gauge(metric.Value)
+ }
+
+ chart = kp.charts.Get("rest_client_requests_by_method")
+
+ for _, metric := range raw.FindByName(metricName) {
+ method := metric.Labels.Get("method")
+ if method == "" {
+ continue
+ }
+ dimID := "rest_client_requests_" + method
+ if !chart.HasDim(dimID) {
+ _ = chart.AddDim(&Dim{ID: dimID, Name: method, Algo: module.Incremental})
+ chart.MarkNotCreated()
+ }
+ mx.RESTClient.Requests.ByMethod[method] = mtx.Gauge(metric.Value)
+ }
+}
+
+func (kp *KubeProxy) collectHTTPRequestDuration(raw prometheus.Series, mx *metrics) {
+ // Summary
+ for _, metric := range raw.FindByName("http_request_duration_microseconds") {
+ if math.IsNaN(metric.Value) {
+ continue
+ }
+ quantile := metric.Labels.Get("quantile")
+ switch quantile {
+ case "0.5":
+ mx.HTTP.Request.Duration.Quantile05.Set(metric.Value)
+ case "0.9":
+ mx.HTTP.Request.Duration.Quantile09.Set(metric.Value)
+ case "0.99":
+ mx.HTTP.Request.Duration.Quantile099.Set(metric.Value)
+ }
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/config_schema.json b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/config_schema.json
new file mode 100644
index 000000000..9e68e80c4
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/config_schema.json
@@ -0,0 +1,177 @@
+{
+ "jsonSchema": {
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Kubeproxy collector configuration.",
+ "type": "object",
+ "properties": {
+ "update_every": {
+ "title": "Update every",
+ "description": "Data collection interval, measured in seconds.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ },
+ "url": {
+ "title": "URL",
+ "description": "The URL of the Kubeproxy metrics endpoint.",
+ "type": "string",
+ "default": "http://127.0.0.1:10249/metrics",
+ "format": "uri"
+ },
+ "timeout": {
+ "title": "Timeout",
+ "description": "The timeout in seconds for the HTTP request.",
+ "type": "number",
+ "minimum": 0.5,
+ "default": 1
+ },
+ "not_follow_redirects": {
+ "title": "Not follow redirects",
+ "description": "If set, the client will not follow HTTP redirects automatically.",
+ "type": "boolean"
+ },
+ "username": {
+ "title": "Username",
+ "description": "The username for basic authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "password": {
+ "title": "Password",
+ "description": "The password for basic authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "proxy_url": {
+ "title": "Proxy URL",
+ "description": "The URL of the proxy server.",
+ "type": "string"
+ },
+ "proxy_username": {
+ "title": "Proxy username",
+ "description": "The username for proxy authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "proxy_password": {
+ "title": "Proxy password",
+ "description": "The password for proxy authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "headers": {
+ "title": "Headers",
+ "description": "Additional HTTP headers to include in the request.",
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "tls_skip_verify": {
+ "title": "Skip TLS verification",
+ "description": "If set, TLS certificate verification will be skipped.",
+ "type": "boolean"
+ },
+ "tls_ca": {
+ "title": "TLS CA",
+ "description": "The path to the CA certificate file for TLS verification.",
+ "type": "string",
+ "pattern": "^$|^/"
+ },
+ "tls_cert": {
+ "title": "TLS certificate",
+ "description": "The path to the client certificate file for TLS authentication.",
+ "type": "string",
+ "pattern": "^$|^/"
+ },
+ "tls_key": {
+ "title": "TLS key",
+ "description": "The path to the client key file for TLS authentication.",
+ "type": "string",
+ "pattern": "^$|^/"
+ },
+ "body": {
+ "title": "Body",
+ "type": "string"
+ },
+ "method": {
+ "title": "Method",
+ "type": "string"
+ }
+ },
+ "required": [
+ "url"
+ ],
+ "additionalProperties": false,
+ "patternProperties": {
+ "^name$": {}
+ }
+ },
+ "uiSchema": {
+ "ui:flavour": "tabs",
+ "ui:options": {
+ "tabs": [
+ {
+ "title": "Base",
+ "fields": [
+ "update_every",
+ "url",
+ "timeout",
+ "not_follow_redirects"
+ ]
+ },
+ {
+ "title": "Auth",
+ "fields": [
+ "username",
+ "password"
+ ]
+ },
+ {
+ "title": "TLS",
+ "fields": [
+ "tls_skip_verify",
+ "tls_ca",
+ "tls_cert",
+ "tls_key"
+ ]
+ },
+ {
+ "title": "Proxy",
+ "fields": [
+ "proxy_url",
+ "proxy_username",
+ "proxy_password"
+ ]
+ },
+ {
+ "title": "Headers",
+ "fields": [
+ "headers"
+ ]
+ }
+ ]
+ },
+ "uiOptions": {
+ "fullPage": true
+ },
+ "body": {
+ "ui:widget": "hidden"
+ },
+ "method": {
+ "ui:widget": "hidden"
+ },
+ "timeout": {
+ "ui:help": "Accepts decimals for precise control (e.g., type 1.5 for 1.5 seconds)."
+ },
+ "password": {
+ "ui:widget": "password"
+ },
+ "proxy_password": {
+ "ui:widget": "password"
+ }
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/init.go b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/init.go
new file mode 100644
index 000000000..29386210d
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/init.go
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package k8s_kubeproxy
+
+import (
+ "errors"
+
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
+)
+
+func (kp *KubeProxy) validateConfig() error {
+ if kp.URL == "" {
+ return errors.New("url not set")
+ }
+ return nil
+}
+
+func (kp *KubeProxy) initPrometheusClient() (prometheus.Prometheus, error) {
+ httpClient, err := web.NewHTTPClient(kp.Client)
+ if err != nil {
+ return nil, err
+ }
+
+ return prometheus.New(httpClient, kp.Request), nil
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/integrations/kubeproxy.md b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/integrations/kubeproxy.md
new file mode 100644
index 000000000..beea0c080
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/integrations/kubeproxy.md
@@ -0,0 +1,186 @@
+<!--startmeta
+custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/README.md"
+meta_yaml: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metadata.yaml"
+sidebar_label: "Kubeproxy"
+learn_status: "Published"
+learn_rel_path: "Collecting Metrics/Kubernetes"
+most_popular: True
+message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE COLLECTOR'S metadata.yaml FILE"
+endmeta-->
+
+# Kubeproxy
+
+
+<img src="https://netdata.cloud/img/kubernetes.svg" width="150"/>
+
+
+Plugin: go.d.plugin
+Module: k8s_kubeproxy
+
+<img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" />
+
+## Overview
+
+This collector monitors Kubeproxy instances.
+
+
+
+
+This collector is supported on all platforms.
+
+This collector supports collecting metrics from multiple instances of this integration, including remote instances.
+
+
+### Default Behavior
+
+#### Auto-Detection
+
+This integration doesn't support auto-detection.
+
+#### Limits
+
+The default configuration for this integration does not impose any limits on data collection.
+
+#### Performance Impact
+
+The default configuration for this integration is not expected to impose a significant performance impact on the system.
+
+
+## Metrics
+
+Metrics grouped by *scope*.
+
+The scope defines the instance that the metric belongs to. An instance is uniquely identified by a set of labels.
+
+
+
+### Per Kubeproxy instance
+
+These metrics refer to the entire monitored application.
+
+This scope has no labels.
+
+Metrics:
+
+| Metric | Dimensions | Unit |
+|:------|:----------|:----|
+| k8s_kubeproxy.kubeproxy_sync_proxy_rules | sync_proxy_rules | events/s |
+| k8s_kubeproxy.kubeproxy_sync_proxy_rules_latency_microsecond | 0.001, 0.002, 0.004, 0.008, 0.016, 0.032, 0.064, 0.128, 0.256, 0.512, 1.024, 2.048, 4.096, 8.192, 16.384, +Inf | observes/s |
+| k8s_kubeproxy.kubeproxy_sync_proxy_rules_latency | 0.001, 0.002, 0.004, 0.008, 0.016, 0.032, 0.064, 0.128, 0.256, 0.512, 1.024, 2.048, 4.096, 8.192, 16.384, +Inf | percentage |
+| k8s_kubeproxy.rest_client_requests_by_code | a dimension per HTTP status code | requests/s |
+| k8s_kubeproxy.rest_client_requests_by_method | a dimension per HTTP method | requests/s |
+| k8s_kubeproxy.http_request_duration | 0.5, 0.9, 0.99 | microseconds |
+
+
+
+## Alerts
+
+There are no alerts configured by default for this integration.
+
+
+## Setup
+
+### Prerequisites
+
+No action required.
+
+### Configuration
+
+#### File
+
+The configuration file name for this integration is `go.d/k8s_kubeproxy.conf`.
+
+
+You can edit the configuration file using the `edit-config` script from the
+Netdata [config directory](/docs/netdata-agent/configuration/README.md#the-netdata-config-directory).
+
+```bash
+cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
+sudo ./edit-config go.d/k8s_kubeproxy.conf
+```
+#### Options
+
+The following options can be defined globally: update_every, autodetection_retry.
+
+
+<details open><summary>Config options</summary>
+
+| Name | Description | Default | Required |
+|:----|:-----------|:-------|:--------:|
+| update_every | Data collection frequency. | 1 | no |
+| autodetection_retry | Recheck interval in seconds. Zero means no recheck will be scheduled. | 0 | no |
+| url | Server URL. | http://127.0.0.1:10249/metrics | yes |
+| timeout | HTTP request timeout. | 1 | no |
+| username | Username for basic HTTP authentication. | | no |
+| password | Password for basic HTTP authentication. | | no |
+| proxy_url | Proxy URL. | | no |
+| proxy_username | Username for proxy basic HTTP authentication. | | no |
+| proxy_password | Password for proxy basic HTTP authentication. | | no |
+| method | HTTP request method. | GET | no |
+| body | HTTP request body. | | no |
+| headers | HTTP request headers. | | no |
+| not_follow_redirects | Redirect handling policy. Controls whether the client follows redirects. | no | no |
+| tls_skip_verify | Server certificate chain and hostname validation policy. Controls whether the client performs this check. | no | no |
+| tls_ca | Certification authority that the client uses when verifying the server's certificates. | | no |
+| tls_cert | Client TLS certificate. | | no |
+| tls_key | Client TLS key. | | no |
+
+</details>
+
+#### Examples
+
+##### Basic
+
+A basic example configuration.
+
+```yaml
+jobs:
+ - name: local
+ url: http://127.0.0.1:10249/metrics
+
+```
+##### HTTPS with self-signed certificate
+
+Do not validate server certificate chain and hostname.
+
+
+<details open><summary>Config</summary>
+
+```yaml
+jobs:
+ - name: local
+ url: https://127.0.0.1:10249/metrics
+ tls_skip_verify: yes
+
+```
+</details>
+
+
+
+## Troubleshooting
+
+### Debug Mode
+
+To troubleshoot issues with the `k8s_kubeproxy` collector, run the `go.d.plugin` with the debug option enabled. The output
+should give you clues as to why the collector isn't working.
+
+- Navigate to the `plugins.d` directory, usually at `/usr/libexec/netdata/plugins.d/`. If that's not the case on
+ your system, open `netdata.conf` and look for the `plugins` setting under `[directories]`.
+
+ ```bash
+ cd /usr/libexec/netdata/plugins.d/
+ ```
+
+- Switch to the `netdata` user.
+
+ ```bash
+ sudo -u netdata -s
+ ```
+
+- Run the `go.d.plugin` to debug the collector:
+
+ ```bash
+ ./go.d.plugin -d -m k8s_kubeproxy
+ ```
+
+
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy.go b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy.go
new file mode 100644
index 000000000..3af89c12f
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy.go
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package k8s_kubeproxy
+
+import (
+ _ "embed"
+ "errors"
+ "time"
+
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
+)
+
+//go:embed "config_schema.json"
+var configSchema string
+
+func init() {
+ module.Register("k8s_kubeproxy", module.Creator{
+ JobConfigSchema: configSchema,
+ Defaults: module.Defaults{
+ // NETDATA_CHART_PRIO_CGROUPS_CONTAINERS 40000
+ Priority: 50000,
+ },
+ Create: func() module.Module { return New() },
+ Config: func() any { return &Config{} },
+ })
+}
+
+func New() *KubeProxy {
+ return &KubeProxy{
+ Config: Config{
+ HTTP: web.HTTP{
+ Request: web.Request{
+ URL: "http://127.0.0.1:10249/metrics",
+ },
+ Client: web.Client{
+ Timeout: web.Duration(time.Second),
+ },
+ },
+ },
+ charts: charts.Copy(),
+ }
+}
+
+type Config struct {
+ UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
+ web.HTTP `yaml:",inline" json:""`
+}
+
+type KubeProxy struct {
+ module.Base
+ Config `yaml:",inline" json:""`
+
+ charts *Charts
+
+ prom prometheus.Prometheus
+}
+
+func (kp *KubeProxy) Configuration() any {
+ return kp.Config
+}
+
+func (kp *KubeProxy) Init() error {
+ if err := kp.validateConfig(); err != nil {
+ kp.Errorf("config validation: %v", err)
+ return err
+ }
+
+ prom, err := kp.initPrometheusClient()
+ if err != nil {
+ kp.Error(err)
+ return err
+ }
+ kp.prom = prom
+
+ return nil
+}
+
+func (kp *KubeProxy) Check() error {
+ mx, err := kp.collect()
+ if err != nil {
+ kp.Error(err)
+ return err
+ }
+ if len(mx) == 0 {
+ return errors.New("no metrics collected")
+ }
+ return nil
+}
+
+func (kp *KubeProxy) Charts() *Charts {
+ return kp.charts
+}
+
+func (kp *KubeProxy) Collect() map[string]int64 {
+ mx, err := kp.collect()
+
+ if err != nil {
+ kp.Error(err)
+ return nil
+ }
+
+ return mx
+}
+
+func (kp *KubeProxy) Cleanup() {
+ if kp.prom != nil && kp.prom.HTTPClient() != nil {
+ kp.prom.HTTPClient().CloseIdleConnections()
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy_test.go b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy_test.go
new file mode 100644
index 000000000..27a6c9174
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/kubeproxy_test.go
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package k8s_kubeproxy
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "os"
+ "testing"
+
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+var (
+ dataConfigJSON, _ = os.ReadFile("testdata/config.json")
+ dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
+
+ dataMetrics, _ = os.ReadFile("testdata/metrics.txt")
+)
+
+func Test_testDataIsValid(t *testing.T) {
+ for name, data := range map[string][]byte{
+ "dataConfigJSON": dataConfigJSON,
+ "dataConfigYAML": dataConfigYAML,
+ "dataMetrics": dataMetrics,
+ } {
+ require.NotNil(t, data, name)
+ }
+}
+
+func TestKubeProxy_ConfigurationSerialize(t *testing.T) {
+ module.TestConfigurationSerialize(t, &KubeProxy{}, dataConfigJSON, dataConfigYAML)
+}
+
+func TestKubeProxy_Charts(t *testing.T) {
+ assert.NotNil(t, New().Charts())
+}
+
+func TestKubeProxy_Cleanup(t *testing.T) {
+ New().Cleanup()
+}
+
+func TestKubeProxy_Init(t *testing.T) {
+ assert.NoError(t, New().Init())
+}
+
+func TestKubeProxy_InitNG(t *testing.T) {
+ job := New()
+ job.URL = ""
+ assert.Error(t, job.Init())
+}
+
+func TestKubeProxy_Check(t *testing.T) {
+ ts := httptest.NewServer(
+ http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ _, _ = w.Write(dataMetrics)
+ }))
+ defer ts.Close()
+
+ job := New()
+ job.URL = ts.URL + "/metrics"
+ require.NoError(t, job.Init())
+ assert.NoError(t, job.Check())
+}
+
+func TestKubeProxy_CheckNG(t *testing.T) {
+ job := New()
+ job.URL = "http://127.0.0.1:38001/metrics"
+ require.NoError(t, job.Init())
+ assert.Error(t, job.Check())
+}
+
+func TestKubeProxy_Collect(t *testing.T) {
+ ts := httptest.NewServer(
+ http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ _, _ = w.Write(dataMetrics)
+ }))
+ defer ts.Close()
+
+ job := New()
+ job.URL = ts.URL + "/metrics"
+ require.NoError(t, job.Init())
+ require.NoError(t, job.Check())
+
+ expected := map[string]int64{
+ "sync_proxy_rules_count": 2669,
+ "sync_proxy_rules_bucket_1000": 1,
+ "sync_proxy_rules_bucket_2000": 0,
+ "sync_proxy_rules_bucket_4000": 0,
+ "sync_proxy_rules_bucket_8000": 0,
+ "sync_proxy_rules_bucket_16000": 23,
+ "sync_proxy_rules_bucket_32000": 2510,
+ "sync_proxy_rules_bucket_64000": 126,
+ "sync_proxy_rules_bucket_128000": 8,
+ "sync_proxy_rules_bucket_256000": 0,
+ "sync_proxy_rules_bucket_512000": 1,
+ "sync_proxy_rules_bucket_1024000": 0,
+ "sync_proxy_rules_bucket_4096000": 0,
+ "sync_proxy_rules_bucket_8192000": 0,
+ "sync_proxy_rules_bucket_2048000": 0,
+ "sync_proxy_rules_bucket_16384000": 0,
+ "sync_proxy_rules_bucket_+Inf": 0,
+ "rest_client_requests_201": 1,
+ "rest_client_requests_200": 362,
+ "rest_client_requests_GET": 362,
+ "rest_client_requests_POST": 1,
+ "http_request_duration_05": 1515,
+ "http_request_duration_09": 3939,
+ "http_request_duration_099": 9464,
+ }
+
+ assert.Equal(t, expected, job.Collect())
+}
+
+func TestKubeProxy_InvalidData(t *testing.T) {
+ ts := httptest.NewServer(
+ http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ _, _ = w.Write([]byte("hello and goodbye"))
+ }))
+ defer ts.Close()
+
+ job := New()
+ job.URL = ts.URL + "/metrics"
+ require.NoError(t, job.Init())
+ assert.Error(t, job.Check())
+}
+
+func TestKubeProxy_404(t *testing.T) {
+ ts := httptest.NewServer(
+ http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusNotFound)
+ }))
+ defer ts.Close()
+
+ job := New()
+ job.URL = ts.URL + "/metrics"
+ require.NoError(t, job.Init())
+ assert.Error(t, job.Check())
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metadata.yaml b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metadata.yaml
new file mode 100644
index 000000000..0f8d0d72a
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metadata.yaml
@@ -0,0 +1,227 @@
+plugin_name: go.d.plugin
+modules:
+ - meta:
+ id: collector-go.d.plugin-k8s_kubeproxy
+ plugin_name: go.d.plugin
+ module_name: k8s_kubeproxy
+ monitored_instance:
+ name: Kubeproxy
+ link: https://kubernetes.io/docs/concepts/overview/components/#kube-proxy
+ icon_filename: kubernetes.svg
+ categories:
+ - data-collection.kubernetes
+ keywords:
+ - kubeproxy
+ - kubernetes
+ - k8s
+ related_resources:
+ integrations:
+ list:
+ - plugin_name: apps.plugin
+ module_name: apps
+ info_provided_to_referring_integrations:
+ description: ""
+ most_popular: true
+ overview:
+ data_collection:
+ metrics_description: |
+ This collector monitors Kubeproxy instances.
+ method_description: ""
+ supported_platforms:
+ include: []
+ exclude: []
+ multi_instance: true
+ additional_permissions:
+ description: ""
+ default_behavior:
+ auto_detection:
+ description: ""
+ limits:
+ description: ""
+ performance_impact:
+ description: ""
+ setup:
+ prerequisites:
+ list: []
+ configuration:
+ file:
+ name: go.d/k8s_kubeproxy.conf
+ options:
+ description: |
+ The following options can be defined globally: update_every, autodetection_retry.
+ folding:
+ title: Config options
+ enabled: true
+ list:
+ - name: update_every
+ description: Data collection frequency.
+ default_value: 1
+ required: false
+ - name: autodetection_retry
+ description: Recheck interval in seconds. Zero means no recheck will be scheduled.
+ default_value: 0
+ required: false
+ - name: url
+ description: Server URL.
+ default_value: http://127.0.0.1:10249/metrics
+ required: true
+ - name: timeout
+ description: HTTP request timeout.
+ default_value: 1
+ required: false
+ - name: username
+ description: Username for basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: password
+ description: Password for basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: proxy_url
+ description: Proxy URL.
+ default_value: ""
+ required: false
+ - name: proxy_username
+ description: Username for proxy basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: proxy_password
+ description: Password for proxy basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: method
+ description: HTTP request method.
+ default_value: GET
+ required: false
+ - name: body
+ description: HTTP request body.
+ default_value: ""
+ required: false
+ - name: headers
+ description: HTTP request headers.
+ default_value: ""
+ required: false
+ - name: not_follow_redirects
+ description: Redirect handling policy. Controls whether the client follows redirects.
+ default_value: no
+ required: false
+ - name: tls_skip_verify
+ description: Server certificate chain and hostname validation policy. Controls whether the client performs this check.
+ default_value: no
+ required: false
+ - name: tls_ca
+ description: Certification authority that the client uses when verifying the server's certificates.
+ default_value: ""
+ required: false
+ - name: tls_cert
+ description: Client TLS certificate.
+ default_value: ""
+ required: false
+ - name: tls_key
+ description: Client TLS key.
+ default_value: ""
+ required: false
+ examples:
+ folding:
+ title: Config
+ enabled: true
+ list:
+ - name: Basic
+ folding:
+ enabled: false
+ description: A basic example configuration.
+ config: |
+ jobs:
+ - name: local
+ url: http://127.0.0.1:10249/metrics
+ - name: HTTPS with self-signed certificate
+ description: |
+ Do not validate server certificate chain and hostname.
+ config: |
+ jobs:
+ - name: local
+ url: https://127.0.0.1:10249/metrics
+ tls_skip_verify: yes
+ troubleshooting:
+ problems:
+ list: []
+ alerts: []
+ metrics:
+ folding:
+ title: Metrics
+ enabled: false
+ description: ""
+ availability: []
+ scopes:
+ - name: global
+ description: These metrics refer to the entire monitored application.
+ labels: []
+ metrics:
+ - name: k8s_kubeproxy.kubeproxy_sync_proxy_rules
+ description: Sync Proxy Rules
+ unit: events/s
+ chart_type: line
+ dimensions:
+ - name: sync_proxy_rules
+ - name: k8s_kubeproxy.kubeproxy_sync_proxy_rules_latency_microsecond
+ description: Sync Proxy Rules Latency
+ unit: observes/s
+ chart_type: stacked
+ dimensions:
+ - name: "0.001"
+ - name: "0.002"
+ - name: "0.004"
+ - name: "0.008"
+ - name: "0.016"
+ - name: "0.032"
+ - name: "0.064"
+ - name: "0.128"
+ - name: "0.256"
+ - name: "0.512"
+ - name: "1.024"
+ - name: "2.048"
+ - name: "4.096"
+ - name: "8.192"
+ - name: "16.384"
+ - name: +Inf
+ - name: k8s_kubeproxy.kubeproxy_sync_proxy_rules_latency
+ description: Sync Proxy Rules Latency Percentage
+ unit: percentage
+ chart_type: stacked
+ dimensions:
+ - name: "0.001"
+ - name: "0.002"
+ - name: "0.004"
+ - name: "0.008"
+ - name: "0.016"
+ - name: "0.032"
+ - name: "0.064"
+ - name: "0.128"
+ - name: "0.256"
+ - name: "0.512"
+ - name: "1.024"
+ - name: "2.048"
+ - name: "4.096"
+ - name: "8.192"
+ - name: "16.384"
+ - name: +Inf
+ - name: k8s_kubeproxy.rest_client_requests_by_code
+ description: HTTP Requests By Status Code
+ unit: requests/s
+ chart_type: stacked
+ dimensions:
+ - name: a dimension per HTTP status code
+ - name: k8s_kubeproxy.rest_client_requests_by_method
+ description: HTTP Requests By Status Method
+ unit: requests/s
+ chart_type: stacked
+ dimensions:
+ - name: a dimension per HTTP method
+ - name: k8s_kubeproxy.http_request_duration
+ description: HTTP Requests Duration
+ unit: microseconds
+ chart_type: stacked
+ dimensions:
+ - name: "0.5"
+ - name: "0.9"
+ - name: "0.99"
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metrics.go b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metrics.go
new file mode 100644
index 000000000..1cc58f0df
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/metrics.go
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package k8s_kubeproxy
+
+import (
+ mtx "github.com/netdata/netdata/go/go.d.plugin/pkg/metrics"
+)
+
+func newMetrics() *metrics {
+ var mx metrics
+ mx.RESTClient.Requests.ByStatusCode = make(map[string]mtx.Gauge)
+ mx.RESTClient.Requests.ByMethod = make(map[string]mtx.Gauge)
+
+ return &mx
+}
+
+type metrics struct {
+ SyncProxyRules struct {
+ Count mtx.Gauge `stm:"count"`
+ Latency struct {
+ LE1000 mtx.Gauge `stm:"1000"`
+ LE2000 mtx.Gauge `stm:"2000"`
+ LE4000 mtx.Gauge `stm:"4000"`
+ LE8000 mtx.Gauge `stm:"8000"`
+ LE16000 mtx.Gauge `stm:"16000"`
+ LE32000 mtx.Gauge `stm:"32000"`
+ LE64000 mtx.Gauge `stm:"64000"`
+ LE128000 mtx.Gauge `stm:"128000"`
+ LE256000 mtx.Gauge `stm:"256000"`
+ LE512000 mtx.Gauge `stm:"512000"`
+ LE1024000 mtx.Gauge `stm:"1024000"`
+ LE2048000 mtx.Gauge `stm:"2048000"`
+ LE4096000 mtx.Gauge `stm:"4096000"`
+ LE8192000 mtx.Gauge `stm:"8192000"`
+ LE16384000 mtx.Gauge `stm:"16384000"`
+ Inf mtx.Gauge `stm:"+Inf"`
+ } `stm:"bucket"`
+ } `stm:"sync_proxy_rules"`
+ RESTClient struct {
+ Requests struct {
+ ByStatusCode map[string]mtx.Gauge `stm:""`
+ ByMethod map[string]mtx.Gauge `stm:""`
+ } `stm:"requests"`
+ } `stm:"rest_client"`
+ HTTP struct {
+ Request struct {
+ Duration struct {
+ Quantile05 mtx.Gauge `stm:"05"`
+ Quantile09 mtx.Gauge `stm:"09"`
+ Quantile099 mtx.Gauge `stm:"099"`
+ } `stm:"duration"`
+ } `stm:"request"`
+ } `stm:"http"`
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.json b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.json
new file mode 100644
index 000000000..984c3ed6e
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.json
@@ -0,0 +1,20 @@
+{
+ "update_every": 123,
+ "url": "ok",
+ "body": "ok",
+ "method": "ok",
+ "headers": {
+ "ok": "ok"
+ },
+ "username": "ok",
+ "password": "ok",
+ "proxy_url": "ok",
+ "proxy_username": "ok",
+ "proxy_password": "ok",
+ "timeout": 123.123,
+ "not_follow_redirects": true,
+ "tls_ca": "ok",
+ "tls_cert": "ok",
+ "tls_key": "ok",
+ "tls_skip_verify": true
+}
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.yaml b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.yaml
new file mode 100644
index 000000000..8558b61cc
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/config.yaml
@@ -0,0 +1,17 @@
+update_every: 123
+url: "ok"
+body: "ok"
+method: "ok"
+headers:
+ ok: "ok"
+username: "ok"
+password: "ok"
+proxy_url: "ok"
+proxy_username: "ok"
+proxy_password: "ok"
+timeout: 123.123
+not_follow_redirects: yes
+tls_ca: "ok"
+tls_cert: "ok"
+tls_key: "ok"
+tls_skip_verify: yes
diff --git a/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/metrics.txt b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/metrics.txt
new file mode 100644
index 000000000..7a10d8477
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/k8s_kubeproxy/testdata/metrics.txt
@@ -0,0 +1,190 @@
+# HELP apiserver_audit_event_total Counter of audit events generated and sent to the audit backend.
+# TYPE apiserver_audit_event_total counter
+apiserver_audit_event_total 0
+# HELP apiserver_audit_requests_rejected_total Counter of apiserver requests rejected due to an error in audit logging backend.
+# TYPE apiserver_audit_requests_rejected_total counter
+apiserver_audit_requests_rejected_total 0
+# HELP go_gc_duration_seconds A summary of the GC invocation durations.
+# TYPE go_gc_duration_seconds summary
+go_gc_duration_seconds{quantile="0"} 2.2652e-05
+go_gc_duration_seconds{quantile="0.25"} 5.9037e-05
+go_gc_duration_seconds{quantile="0.5"} 0.000113147
+go_gc_duration_seconds{quantile="0.75"} 0.000232939
+go_gc_duration_seconds{quantile="1"} 0.009002756
+go_gc_duration_seconds_sum 0.294305823
+go_gc_duration_seconds_count 755
+# HELP go_goroutines Number of goroutines that currently exist.
+# TYPE go_goroutines gauge
+go_goroutines 46
+# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
+# TYPE go_memstats_alloc_bytes gauge
+go_memstats_alloc_bytes 6.14748e+06
+# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.
+# TYPE go_memstats_alloc_bytes_total counter
+go_memstats_alloc_bytes_total 9.53406048e+08
+# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.
+# TYPE go_memstats_buck_hash_sys_bytes gauge
+go_memstats_buck_hash_sys_bytes 1.535744e+06
+# HELP go_memstats_frees_total Total number of frees.
+# TYPE go_memstats_frees_total counter
+go_memstats_frees_total 8.247964e+06
+# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started.
+# TYPE go_memstats_gc_cpu_fraction gauge
+go_memstats_gc_cpu_fraction 7.826953112615371e-06
+# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.
+# TYPE go_memstats_gc_sys_bytes gauge
+go_memstats_gc_sys_bytes 2.387968e+06
+# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.
+# TYPE go_memstats_heap_alloc_bytes gauge
+go_memstats_heap_alloc_bytes 6.14748e+06
+# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.
+# TYPE go_memstats_heap_idle_bytes gauge
+go_memstats_heap_idle_bytes 5.8466304e+07
+# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.
+# TYPE go_memstats_heap_inuse_bytes gauge
+go_memstats_heap_inuse_bytes 7.82336e+06
+# HELP go_memstats_heap_objects Number of allocated objects.
+# TYPE go_memstats_heap_objects gauge
+go_memstats_heap_objects 29543
+# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS.
+# TYPE go_memstats_heap_released_bytes gauge
+go_memstats_heap_released_bytes 0
+# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.
+# TYPE go_memstats_heap_sys_bytes gauge
+go_memstats_heap_sys_bytes 6.6289664e+07
+# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.
+# TYPE go_memstats_last_gc_time_seconds gauge
+go_memstats_last_gc_time_seconds 1.5530903816542802e+09
+# HELP go_memstats_lookups_total Total number of pointer lookups.
+# TYPE go_memstats_lookups_total counter
+go_memstats_lookups_total 0
+# HELP go_memstats_mallocs_total Total number of mallocs.
+# TYPE go_memstats_mallocs_total counter
+go_memstats_mallocs_total 8.277507e+06
+# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.
+# TYPE go_memstats_mcache_inuse_bytes gauge
+go_memstats_mcache_inuse_bytes 3456
+# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.
+# TYPE go_memstats_mcache_sys_bytes gauge
+go_memstats_mcache_sys_bytes 16384
+# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.
+# TYPE go_memstats_mspan_inuse_bytes gauge
+go_memstats_mspan_inuse_bytes 89832
+# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.
+# TYPE go_memstats_mspan_sys_bytes gauge
+go_memstats_mspan_sys_bytes 114688
+# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.
+# TYPE go_memstats_next_gc_bytes gauge
+go_memstats_next_gc_bytes 7.132208e+06
+# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.
+# TYPE go_memstats_other_sys_bytes gauge
+go_memstats_other_sys_bytes 596472
+# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.
+# TYPE go_memstats_stack_inuse_bytes gauge
+go_memstats_stack_inuse_bytes 819200
+# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.
+# TYPE go_memstats_stack_sys_bytes gauge
+go_memstats_stack_sys_bytes 819200
+# HELP go_memstats_sys_bytes Number of bytes obtained from system.
+# TYPE go_memstats_sys_bytes gauge
+go_memstats_sys_bytes 7.176012e+07
+# HELP go_threads Number of OS threads created
+# TYPE go_threads gauge
+go_threads 10
+# HELP http_request_duration_microseconds The HTTP request latencies in microseconds.
+# TYPE http_request_duration_microseconds summary
+http_request_duration_microseconds{handler="prometheus",quantile="0.5"} 1515.864
+http_request_duration_microseconds{handler="prometheus",quantile="0.9"} 3939.871
+http_request_duration_microseconds{handler="prometheus",quantile="0.99"} 9464.15
+http_request_duration_microseconds_sum{handler="prometheus"} 837819.5429999996
+http_request_duration_microseconds_count{handler="prometheus"} 378
+# HELP http_request_size_bytes The HTTP request sizes in bytes.
+# TYPE http_request_size_bytes summary
+http_request_size_bytes{handler="prometheus",quantile="0.5"} 377
+http_request_size_bytes{handler="prometheus",quantile="0.9"} 377
+http_request_size_bytes{handler="prometheus",quantile="0.99"} 377
+http_request_size_bytes_sum{handler="prometheus"} 142462
+http_request_size_bytes_count{handler="prometheus"} 378
+# HELP http_requests_total Total number of HTTP requests made.
+# TYPE http_requests_total counter
+http_requests_total{code="200",handler="prometheus",method="get"} 378
+# HELP http_response_size_bytes The HTTP response sizes in bytes.
+# TYPE http_response_size_bytes summary
+http_response_size_bytes{handler="prometheus",quantile="0.5"} 2414
+http_response_size_bytes{handler="prometheus",quantile="0.9"} 2419
+http_response_size_bytes{handler="prometheus",quantile="0.99"} 2423
+http_response_size_bytes_sum{handler="prometheus"} 911969
+http_response_size_bytes_count{handler="prometheus"} 378
+# HELP kubeproxy_sync_proxy_rules_latency_microseconds SyncProxyRules latency
+# TYPE kubeproxy_sync_proxy_rules_latency_microseconds histogram
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="1000"} 1
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="2000"} 1
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="4000"} 1
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="8000"} 1
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="16000"} 24
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="32000"} 2534
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="64000"} 2660
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="128000"} 2668
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="256000"} 2668
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="512000"} 2669
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="1.024e+06"} 2669
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="2.048e+06"} 2669
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="4.096e+06"} 2669
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="8.192e+06"} 2669
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="1.6384e+07"} 2669
+kubeproxy_sync_proxy_rules_latency_microseconds_bucket{le="+Inf"} 2669
+kubeproxy_sync_proxy_rules_latency_microseconds_sum 6.2885705e+07
+kubeproxy_sync_proxy_rules_latency_microseconds_count 2669
+# HELP kubernetes_build_info A metric with a constant '1' value labeled by major, minor, git version, git commit, git tree state, build date, Go version, and compiler from which Kubernetes was built, and platform on which it is running.
+# TYPE kubernetes_build_info gauge
+kubernetes_build_info{buildDate="2019-02-28T13:35:32Z",compiler="gc",gitCommit="c27b913fddd1a6c480c229191a087698aa92f0b1",gitTreeState="clean",gitVersion="v1.13.4",goVersion="go1.11.5",major="1",minor="13",platform="linux/amd64"} 1
+# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
+# TYPE process_cpu_seconds_total counter
+process_cpu_seconds_total 156.15
+# HELP process_max_fds Maximum number of open file descriptors.
+# TYPE process_max_fds gauge
+process_max_fds 1.048576e+06
+# HELP process_open_fds Number of open file descriptors.
+# TYPE process_open_fds gauge
+process_open_fds 11
+# HELP process_resident_memory_bytes Resident memory size in bytes.
+# TYPE process_resident_memory_bytes gauge
+process_resident_memory_bytes 3.5467264e+07
+# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
+# TYPE process_start_time_seconds gauge
+process_start_time_seconds 1.5530103809e+09
+# HELP process_virtual_memory_bytes Virtual memory size in bytes.
+# TYPE process_virtual_memory_bytes gauge
+process_virtual_memory_bytes 1.4047232e+08
+# HELP rest_client_request_latency_seconds Request latency in seconds. Broken down by verb and URL.
+# TYPE rest_client_request_latency_seconds histogram
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.001"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.002"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.004"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.008"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.016"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.032"} 2
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.064"} 2
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.128"} 2
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.256"} 3
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="0.512"} 3
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET",le="+Inf"} 3
+rest_client_request_latency_seconds_sum{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET"} 0.28126861
+rest_client_request_latency_seconds_count{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="GET"} 3
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.001"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.002"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.004"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.008"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.016"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.032"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.064"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.128"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.256"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="0.512"} 0
+rest_client_request_latency_seconds_bucket{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST",le="+Inf"} 1
+rest_client_request_latency_seconds_sum{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST"} 4.008446017
+rest_client_request_latency_seconds_count{url="https://192.168.99.124:8443/%7Bprefix%7D",verb="POST"} 1
+# HELP rest_client_requests_total Number of HTTP requests, partitioned by status code, method, and host.
+# TYPE rest_client_requests_total counter
+rest_client_requests_total{code="200",host="192.168.99.124:8443",method="GET"} 362
+rest_client_requests_total{code="201",host="192.168.99.124:8443",method="POST"} 1 \ No newline at end of file