diff --git a/go.mod b/go.mod index 391424223..3394ae383 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/openshift/client-go v0.0.0-20220525160904-9e1acff93e4a github.com/openshift/installer v0.9.0-master.0.20191219195746-103098955ced github.com/openshift/library-go v0.0.0-20220525173854-9b950a41acdc - github.com/prometheus/common v0.32.1 + github.com/prometheus/client_golang v1.12.1 github.com/spf13/cobra v1.4.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 diff --git a/manifests/06-deployment-ibm-cloud-managed.yaml b/manifests/06-deployment-ibm-cloud-managed.yaml index 94067c18a..7dab2674c 100644 --- a/manifests/06-deployment-ibm-cloud-managed.yaml +++ b/manifests/06-deployment-ibm-cloud-managed.yaml @@ -20,10 +20,6 @@ spec: labels: app: insights-operator spec: - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault containers: - args: - start @@ -42,17 +38,18 @@ spec: value: 0.0.1-snapshot image: quay.io/openshift/origin-insights-operator:latest name: insights-operator - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] ports: - - containerPort: 8443 - name: https + - containerPort: 8080 + name: metrics resources: requests: cpu: 10m memory: 30Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL terminationMessagePolicy: FallbackToLogsOnError volumeMounts: - mountPath: /var/lib/insights-operator @@ -65,9 +62,34 @@ spec: readOnly: true - mountPath: /var/run/secrets/serving-cert name: serving-cert + - args: + - --logtostderr + - --secure-listen-address=:8443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:8080/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + image: quay.io/openshift/origin-kube-rbac-proxy:latest + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + resources: + requests: + cpu: 1m + memory: 20Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: serving-cert + readOnly: false nodeSelector: beta.kubernetes.io/os: linux priorityClassName: system-cluster-critical + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault serviceAccountName: operator tolerations: - effect: NoSchedule diff --git a/manifests/06-deployment.yaml b/manifests/06-deployment.yaml index 40cb41ae7..061d7cf3a 100644 --- a/manifests/06-deployment.yaml +++ b/manifests/06-deployment.yaml @@ -78,8 +78,8 @@ spec: - mountPath: /var/run/secrets/serving-cert name: serving-cert ports: - - containerPort: 8443 - name: https + - containerPort: 8080 + name: metrics resources: requests: cpu: 10m @@ -99,3 +99,24 @@ spec: - start - -v=4 - --config=/etc/insights-operator/server.yaml + - name: kube-rbac-proxy + image: quay.io/openshift/origin-kube-rbac-proxy:latest + args: + - --logtostderr + - --secure-listen-address=:8443 + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --upstream=http://127.0.0.1:8080/ + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + ports: + - containerPort: 8443 + name: https + resources: + requests: + cpu: 1m + memory: 20Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: serving-cert + readOnly: false diff --git a/manifests/image-references b/manifests/image-references index 700edaa52..d53cc8ac2 100644 --- a/manifests/image-references +++ b/manifests/image-references @@ -6,3 +6,7 @@ spec: from: kind: "DockerImage" name: "quay.io/openshift/origin-insights-operator:latest" + - name: kube-rbac-proxy + from: + kind: "DockerImage" + name: "quay.io/openshift/origin-kube-rbac-proxy:latest" diff --git a/pkg/cmd/start/start.go b/pkg/cmd/start/start.go index 0de4b1512..3af7a0059 100644 --- a/pkg/cmd/start/start.go +++ b/pkg/cmd/start/start.go @@ -168,7 +168,6 @@ func runOperator(operator *controller.Operator, cfg *controllercmd.ControllerCom builder := controllercmd.NewController("openshift-insights-operator", operator.Run). WithKubeConfigFile(cmd.Flags().Lookup("kubeconfig").Value.String(), nil). WithLeaderElection(operatorConfig.LeaderElection, "", "openshift-insights-operator-lock"). - WithServer(operatorConfig.ServingInfo, operatorConfig.Authentication, operatorConfig.Authorization). WithRestartOnChange(exitOnChangeReactorCh, startingFileContent, observedFiles...) if err := builder.Run(ctx2, unstructured); err != nil { klog.Error(err) diff --git a/pkg/controller/operator.go b/pkg/controller/operator.go index 42df5970e..bb2cce641 100644 --- a/pkg/controller/operator.go +++ b/pkg/controller/operator.go @@ -24,6 +24,7 @@ import ( "github.com/openshift/insights-operator/pkg/controller/periodic" "github.com/openshift/insights-operator/pkg/controller/status" "github.com/openshift/insights-operator/pkg/gather" + "github.com/openshift/insights-operator/pkg/insights" "github.com/openshift/insights-operator/pkg/insights/insightsclient" "github.com/openshift/insights-operator/pkg/insights/insightsreport" "github.com/openshift/insights-operator/pkg/insights/insightsuploader" @@ -53,6 +54,9 @@ func (s *Operator) Run(ctx context.Context, controller *controllercmd.Controller } s.Controller = cont + // Start the Prometheus metrics server. + go insights.RunMetricsServer() + // these are operator clients kubeClient, err := kubernetes.NewForConfig(controller.ProtoKubeConfig) if err != nil { diff --git a/pkg/insights/insightsclient/insightsclient.go b/pkg/insights/insightsclient/insightsclient.go index 58e5d4b24..27298c25a 100644 --- a/pkg/insights/insightsclient/insightsclient.go +++ b/pkg/insights/insightsclient/insightsclient.go @@ -20,13 +20,13 @@ import ( "k8s.io/client-go/pkg/version" "k8s.io/client-go/rest" "k8s.io/client-go/transport" - "k8s.io/component-base/metrics" - "k8s.io/component-base/metrics/legacyregistry" "k8s.io/klog/v2" configv1 "github.com/openshift/api/config/v1" configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" + "github.com/openshift/insights-operator/pkg/insights" + "github.com/prometheus/client_golang/prometheus" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apimachineryversion "k8s.io/apimachinery/pkg/version" @@ -265,29 +265,16 @@ func (c *Client) createAndWriteMIMEHeader(source *Source, mw *multipart.Writer, } var ( - counterRequestSend = metrics.NewCounterVec(&metrics.CounterOpts{ + counterRequestSend = prometheus.NewCounterVec(prometheus.CounterOpts{ Name: "insightsclient_request_send_total", Help: "Tracks the number of metrics sends", }, []string{"client", "status_code"}) - counterRequestRecvReport = metrics.NewCounterVec(&metrics.CounterOpts{ + counterRequestRecvReport = prometheus.NewCounterVec(prometheus.CounterOpts{ Name: "insightsclient_request_recvreport_total", Help: "Tracks the number of reports requested", }, []string{"client", "status_code"}) ) func init() { - err := legacyregistry.Register( - counterRequestSend, - ) - if err != nil { - fmt.Println(err) - } - - err = legacyregistry.Register( - counterRequestRecvReport, - ) - if err != nil { - fmt.Println(err) - } - + insights.MustRegisterMetricCollectors(counterRequestSend, counterRequestRecvReport) } diff --git a/pkg/insights/insightsreport/insightsreport.go b/pkg/insights/insightsreport/insightsreport.go index b8917f044..ba5b69c19 100644 --- a/pkg/insights/insightsreport/insightsreport.go +++ b/pkg/insights/insightsreport/insightsreport.go @@ -8,14 +8,14 @@ import ( "time" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/component-base/metrics" - "k8s.io/component-base/metrics/legacyregistry" "k8s.io/klog/v2" "github.com/openshift/insights-operator/pkg/authorizer" "github.com/openshift/insights-operator/pkg/config/configobserver" "github.com/openshift/insights-operator/pkg/controllerstatus" + "github.com/openshift/insights-operator/pkg/insights" "github.com/openshift/insights-operator/pkg/insights/insightsclient" + "github.com/prometheus/client_golang/prometheus" ) // Controller gathers the report from Smart Proxy @@ -38,10 +38,13 @@ type InsightsReporter interface { ArchiveUploaded() <-chan struct{} } -var ( +const ( + insightsLastGatherTimeName = "insightsclient_last_gather_time" +) +var ( // insightsStatus contains a metric with the latest report information - insightsStatus = metrics.NewGaugeVec(&metrics.GaugeOpts{ + insightsStatus = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: "health", Subsystem: "statuses", Name: "insights", @@ -51,28 +54,11 @@ var ( retryThreshold = 2 // insightsLastGatherTime contains time of the last Insights data gathering - insightsLastGatherTime = metrics.NewGauge(&metrics.GaugeOpts{ - Name: "insightsclient_last_gather_time", + insightsLastGatherTime = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: insightsLastGatherTimeName, }) ) -func init() { - err := legacyregistry.Register(insightsStatus) - if err != nil { - fmt.Println(err) - } - err = legacyregistry.Register(insightsLastGatherTime) - if err != nil { - fmt.Println(err) - } - - insightsStatus.WithLabelValues("low").Set(float64(-1)) - insightsStatus.WithLabelValues("moderate").Set(float64(-1)) - insightsStatus.WithLabelValues("important").Set(float64(-1)) - insightsStatus.WithLabelValues("critical").Set(float64(-1)) - insightsStatus.WithLabelValues("total").Set(float64(-1)) -} - // New initializes and returns a Gatherer func New(client *insightsclient.Client, configurator configobserver.Configurator, reporter InsightsReporter) *Controller { return &Controller{ @@ -286,8 +272,18 @@ func updateInsightsMetrics(report SmartProxyReport) { t, err := time.Parse(time.RFC3339, string(report.Meta.GatheredAt)) if err != nil { - klog.Errorf("Metric %s not updated. Failed to parse time: %v", insightsLastGatherTime.Name, err) + klog.Errorf("Metric %s not updated. Failed to parse time: %v", insightsLastGatherTimeName, err) return } insightsLastGatherTime.Set(float64(t.Unix())) } + +func init() { + insights.MustRegisterMetricCollectors(insightsStatus, insightsLastGatherTime) + + insightsStatus.WithLabelValues("low").Set(float64(-1)) + insightsStatus.WithLabelValues("moderate").Set(float64(-1)) + insightsStatus.WithLabelValues("important").Set(float64(-1)) + insightsStatus.WithLabelValues("critical").Set(float64(-1)) + insightsStatus.WithLabelValues("total").Set(float64(-1)) +} diff --git a/pkg/insights/metrics.go b/pkg/insights/metrics.go new file mode 100644 index 000000000..9c9a360e1 --- /dev/null +++ b/pkg/insights/metrics.go @@ -0,0 +1,45 @@ +package insights + +import ( + "net/http" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" + "github.com/prometheus/client_golang/prometheus/promhttp" + "k8s.io/klog/v2" +) + +var ( + insightsMetricsRegistry *prometheus.Registry +) + +func init() { + insightsMetricsRegistry = prometheus.NewRegistry() + MustRegisterMetricCollectors( + collectors.NewGoCollector(), + collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), + ) +} + +// RunMetricsServer starts an HTTP server for the Insights metrics registry. +// The server will run synchronously in an infinite loop. In case of an error, +// it will be logged, and the server will be restarted after a short sleep +// (to avoid spamming the log with the same error). +func RunMetricsServer() { + mux := http.NewServeMux() + mux.Handle("/metrics", promhttp.HandlerFor(insightsMetricsRegistry, promhttp.HandlerOpts{})) + for { + klog.Info("Starting the Prometheus metrics server") + klog.Errorf("Unable to serve metrics: %v", http.ListenAndServe(":8080", mux)) + time.Sleep(time.Minute) + } +} + +// RegisterMetricCollector registers a new metric collector or a new metric in +// the Insights metrics registry. This function should be called from init() +// functions only, because it uses the MustRegister method, and therefore panics +// in case of an error. +func MustRegisterMetricCollectors(collectors ...prometheus.Collector) { + insightsMetricsRegistry.MustRegister(collectors...) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/collectors.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/collectors.go new file mode 100644 index 000000000..c4d0f5c35 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/collectors.go @@ -0,0 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package collectors provides implementations of prometheus.Collector to +// conveniently collect process and Go-related metrics. +package collectors diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector.go new file mode 100644 index 000000000..e09f149d7 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector.go @@ -0,0 +1,119 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collectors + +import ( + "database/sql" + + "github.com/prometheus/client_golang/prometheus" +) + +type dbStatsCollector struct { + db *sql.DB + + maxOpenConnections *prometheus.Desc + + openConnections *prometheus.Desc + inUseConnections *prometheus.Desc + idleConnections *prometheus.Desc + + waitCount *prometheus.Desc + waitDuration *prometheus.Desc + maxIdleClosed *prometheus.Desc + maxIdleTimeClosed *prometheus.Desc + maxLifetimeClosed *prometheus.Desc +} + +// NewDBStatsCollector returns a collector that exports metrics about the given *sql.DB. +// See https://golang.org/pkg/database/sql/#DBStats for more information on stats. +func NewDBStatsCollector(db *sql.DB, dbName string) prometheus.Collector { + fqName := func(name string) string { + return "go_sql_" + name + } + return &dbStatsCollector{ + db: db, + maxOpenConnections: prometheus.NewDesc( + fqName("max_open_connections"), + "Maximum number of open connections to the database.", + nil, prometheus.Labels{"db_name": dbName}, + ), + openConnections: prometheus.NewDesc( + fqName("open_connections"), + "The number of established connections both in use and idle.", + nil, prometheus.Labels{"db_name": dbName}, + ), + inUseConnections: prometheus.NewDesc( + fqName("in_use_connections"), + "The number of connections currently in use.", + nil, prometheus.Labels{"db_name": dbName}, + ), + idleConnections: prometheus.NewDesc( + fqName("idle_connections"), + "The number of idle connections.", + nil, prometheus.Labels{"db_name": dbName}, + ), + waitCount: prometheus.NewDesc( + fqName("wait_count_total"), + "The total number of connections waited for.", + nil, prometheus.Labels{"db_name": dbName}, + ), + waitDuration: prometheus.NewDesc( + fqName("wait_duration_seconds_total"), + "The total time blocked waiting for a new connection.", + nil, prometheus.Labels{"db_name": dbName}, + ), + maxIdleClosed: prometheus.NewDesc( + fqName("max_idle_closed_total"), + "The total number of connections closed due to SetMaxIdleConns.", + nil, prometheus.Labels{"db_name": dbName}, + ), + maxIdleTimeClosed: prometheus.NewDesc( + fqName("max_idle_time_closed_total"), + "The total number of connections closed due to SetConnMaxIdleTime.", + nil, prometheus.Labels{"db_name": dbName}, + ), + maxLifetimeClosed: prometheus.NewDesc( + fqName("max_lifetime_closed_total"), + "The total number of connections closed due to SetConnMaxLifetime.", + nil, prometheus.Labels{"db_name": dbName}, + ), + } +} + +// Describe implements Collector. +func (c *dbStatsCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- c.maxOpenConnections + ch <- c.openConnections + ch <- c.inUseConnections + ch <- c.idleConnections + ch <- c.waitCount + ch <- c.waitDuration + ch <- c.maxIdleClosed + ch <- c.maxLifetimeClosed + c.describeNewInGo115(ch) +} + +// Collect implements Collector. +func (c *dbStatsCollector) Collect(ch chan<- prometheus.Metric) { + stats := c.db.Stats() + ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections)) + ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections)) + ch <- prometheus.MustNewConstMetric(c.inUseConnections, prometheus.GaugeValue, float64(stats.InUse)) + ch <- prometheus.MustNewConstMetric(c.idleConnections, prometheus.GaugeValue, float64(stats.Idle)) + ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount)) + ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds()) + ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed)) + ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed)) + c.collectNewInGo115(ch, stats) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_go115.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_go115.go new file mode 100644 index 000000000..6d152fbf1 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_go115.go @@ -0,0 +1,31 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build go1.15 +// +build go1.15 + +package collectors + +import ( + "database/sql" + + "github.com/prometheus/client_golang/prometheus" +) + +func (c *dbStatsCollector) describeNewInGo115(ch chan<- *prometheus.Desc) { + ch <- c.maxIdleTimeClosed +} + +func (c *dbStatsCollector) collectNewInGo115(ch chan<- prometheus.Metric, stats sql.DBStats) { + ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed)) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_pre_go115.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_pre_go115.go new file mode 100644 index 000000000..65235069d --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_pre_go115.go @@ -0,0 +1,27 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !go1.15 +// +build !go1.15 + +package collectors + +import ( + "database/sql" + + "github.com/prometheus/client_golang/prometheus" +) + +func (c *dbStatsCollector) describeNewInGo115(ch chan<- *prometheus.Desc) {} + +func (c *dbStatsCollector) collectNewInGo115(ch chan<- prometheus.Metric, stats sql.DBStats) {} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/expvar_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/expvar_collector.go new file mode 100644 index 000000000..3aa8d0590 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/expvar_collector.go @@ -0,0 +1,57 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collectors + +import "github.com/prometheus/client_golang/prometheus" + +// NewExpvarCollector returns a newly allocated expvar Collector. +// +// An expvar Collector collects metrics from the expvar interface. It provides a +// quick way to expose numeric values that are already exported via expvar as +// Prometheus metrics. Note that the data models of expvar and Prometheus are +// fundamentally different, and that the expvar Collector is inherently slower +// than native Prometheus metrics. Thus, the expvar Collector is probably great +// for experiments and prototying, but you should seriously consider a more +// direct implementation of Prometheus metrics for monitoring production +// systems. +// +// The exports map has the following meaning: +// +// The keys in the map correspond to expvar keys, i.e. for every expvar key you +// want to export as Prometheus metric, you need an entry in the exports +// map. The descriptor mapped to each key describes how to export the expvar +// value. It defines the name and the help string of the Prometheus metric +// proxying the expvar value. The type will always be Untyped. +// +// For descriptors without variable labels, the expvar value must be a number or +// a bool. The number is then directly exported as the Prometheus sample +// value. (For a bool, 'false' translates to 0 and 'true' to 1). Expvar values +// that are not numbers or bools are silently ignored. +// +// If the descriptor has one variable label, the expvar value must be an expvar +// map. The keys in the expvar map become the various values of the one +// Prometheus label. The values in the expvar map must be numbers or bools again +// as above. +// +// For descriptors with more than one variable label, the expvar must be a +// nested expvar map, i.e. where the values of the topmost map are maps again +// etc. until a depth is reached that corresponds to the number of labels. The +// leaves of that structure must be numbers or bools as above to serve as the +// sample values. +// +// Anything that does not fit into the scheme above is silently ignored. +func NewExpvarCollector(exports map[string]*prometheus.Desc) prometheus.Collector { + //nolint:staticcheck // Ignore SA1019 until v2. + return prometheus.NewExpvarCollector(exports) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector.go new file mode 100644 index 000000000..edaa4e50b --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector.go @@ -0,0 +1,69 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collectors + +import "github.com/prometheus/client_golang/prometheus" + +// NewGoCollector returns a collector that exports metrics about the current Go +// process. This includes memory stats. To collect those, runtime.ReadMemStats +// is called. This requires to “stop the world”, which usually only happens for +// garbage collection (GC). Take the following implications into account when +// deciding whether to use the Go collector: +// +// 1. The performance impact of stopping the world is the more relevant the more +// frequently metrics are collected. However, with Go1.9 or later the +// stop-the-world time per metrics collection is very short (~25µs) so that the +// performance impact will only matter in rare cases. However, with older Go +// versions, the stop-the-world duration depends on the heap size and can be +// quite significant (~1.7 ms/GiB as per +// https://go-review.googlesource.com/c/go/+/34937). +// +// 2. During an ongoing GC, nothing else can stop the world. Therefore, if the +// metrics collection happens to coincide with GC, it will only complete after +// GC has finished. Usually, GC is fast enough to not cause problems. However, +// with a very large heap, GC might take multiple seconds, which is enough to +// cause scrape timeouts in common setups. To avoid this problem, the Go +// collector will use the memstats from a previous collection if +// runtime.ReadMemStats takes more than 1s. However, if there are no previously +// collected memstats, or their collection is more than 5m ago, the collection +// will block until runtime.ReadMemStats succeeds. +// +// NOTE: The problem is solved in Go 1.15, see +// https://github.com/golang/go/issues/19812 for the related Go issue. +func NewGoCollector() prometheus.Collector { + //nolint:staticcheck // Ignore SA1019 until v2. + return prometheus.NewGoCollector() +} + +// NewBuildInfoCollector returns a collector collecting a single metric +// "go_build_info" with the constant value 1 and three labels "path", "version", +// and "checksum". Their label values contain the main module path, version, and +// checksum, respectively. The labels will only have meaningful values if the +// binary is built with Go module support and from source code retrieved from +// the source repository (rather than the local file system). This is usually +// accomplished by building from outside of GOPATH, specifying the full address +// of the main package, e.g. "GO111MODULE=on go run +// github.com/prometheus/client_golang/examples/random". If built without Go +// module support, all label values will be "unknown". If built with Go module +// support but using the source code from the local file system, the "path" will +// be set appropriately, but "checksum" will be empty and "version" will be +// "(devel)". +// +// This collector uses only the build information for the main module. See +// https://github.com/povilasv/prommod for an example of a collector for the +// module dependencies. +func NewBuildInfoCollector() prometheus.Collector { + //nolint:staticcheck // Ignore SA1019 until v2. + return prometheus.NewBuildInfoCollector() +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/process_collector.go new file mode 100644 index 000000000..24558f50a --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/process_collector.go @@ -0,0 +1,56 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collectors + +import "github.com/prometheus/client_golang/prometheus" + +// ProcessCollectorOpts defines the behavior of a process metrics collector +// created with NewProcessCollector. +type ProcessCollectorOpts struct { + // PidFn returns the PID of the process the collector collects metrics + // for. It is called upon each collection. By default, the PID of the + // current process is used, as determined on construction time by + // calling os.Getpid(). + PidFn func() (int, error) + // If non-empty, each of the collected metrics is prefixed by the + // provided string and an underscore ("_"). + Namespace string + // If true, any error encountered during collection is reported as an + // invalid metric (see NewInvalidMetric). Otherwise, errors are ignored + // and the collected metrics will be incomplete. (Possibly, no metrics + // will be collected at all.) While that's usually not desired, it is + // appropriate for the common "mix-in" of process metrics, where process + // metrics are nice to have, but failing to collect them should not + // disrupt the collection of the remaining metrics. + ReportErrors bool +} + +// NewProcessCollector returns a collector which exports the current state of +// process metrics including CPU, memory and file descriptor usage as well as +// the process start time. The detailed behavior is defined by the provided +// ProcessCollectorOpts. The zero value of ProcessCollectorOpts creates a +// collector for the current process with an empty namespace string and no error +// reporting. +// +// The collector only works on operating systems with a Linux-style proc +// filesystem and on Microsoft Windows. On other operating systems, it will not +// collect any metrics. +func NewProcessCollector(opts ProcessCollectorOpts) prometheus.Collector { + //nolint:staticcheck // Ignore SA1019 until v2. + return prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{ + PidFn: opts.PidFn, + Namespace: opts.Namespace, + ReportErrors: opts.ReportErrors, + }) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 9a6a0cb38..9e2f00e1f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -192,7 +192,9 @@ github.com/pkg/profile # github.com/pmezard/go-difflib v1.0.0 github.com/pmezard/go-difflib/difflib # github.com/prometheus/client_golang v1.12.1 +## explicit github.com/prometheus/client_golang/prometheus +github.com/prometheus/client_golang/prometheus/collectors github.com/prometheus/client_golang/prometheus/internal github.com/prometheus/client_golang/prometheus/promhttp github.com/prometheus/client_golang/prometheus/testutil @@ -200,7 +202,6 @@ github.com/prometheus/client_golang/prometheus/testutil/promlint # github.com/prometheus/client_model v0.2.0 github.com/prometheus/client_model/go # github.com/prometheus/common v0.32.1 -## explicit github.com/prometheus/common/expfmt github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg github.com/prometheus/common/model