Skip to content

Commit

Permalink
feat: integrate prometheus metrics handler and expose basic metrics (#…
Browse files Browse the repository at this point in the history
…226)

* feat: integrate prometheus metrics handler and expose basic metrics

* fix obsolete metric record

* fix lint

* improve prometheus metrics recording

* fix lint

* small optimization
  • Loading branch information
floreks authored Jun 18, 2024
1 parent 8db49ca commit afea748
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 15 deletions.
26 changes: 26 additions & 0 deletions cmd/agent/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"fmt"
"net/http"

"github.com/prometheus/client_golang/prometheus/promhttp"
"k8s.io/klog/v2"
)

const (
prometheusMetricsPath = "/metrics"
prometheusMetricsPort = 8000
)

func init() {
go initPrometheusMetrics()
}

func initPrometheusMetrics() {
http.Handle(prometheusMetricsPath, promhttp.Handler())

if err := http.ListenAndServe(fmt.Sprintf(":%d", prometheusMetricsPort), nil); err != nil {
klog.Fatal(err)
}
}
7 changes: 3 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
github.com/pluralsh/controller-reconcile-helper v0.0.4
github.com/pluralsh/gophoenix v0.1.3-0.20231201014135-dff1b4309e34
github.com/pluralsh/polly v0.1.10
github.com/prometheus/client_golang v1.19.1
github.com/samber/lo v1.39.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -150,7 +151,6 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
Expand All @@ -172,9 +172,8 @@ require (
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/zerolog v1.29.0 // indirect
Expand Down Expand Up @@ -207,7 +206,7 @@ require (
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/oauth2 v0.14.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
Expand Down
14 changes: 6 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,6 @@ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ=
github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
Expand Down Expand Up @@ -543,17 +541,17 @@ github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjz
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
Expand Down Expand Up @@ -797,8 +795,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down
73 changes: 73 additions & 0 deletions internal/metrics/metrics_prometheus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package metrics

import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

var (
recorder = (&prometheusRecorder{}).init()
)

type prometheusRecorder struct {
discoveryAPICacheRefreshCounter prometheus.Counter
discoveryAPICacheRefreshErrorCounter prometheus.Counter
serviceReconciliationCounter *prometheus.CounterVec
serviceReconciliationErrorCounter *prometheus.CounterVec
stackRunJobsCreatedCounter prometheus.Counter
}

func (in *prometheusRecorder) DiscoveryAPICacheRefresh(err error) {
if err != nil {
in.discoveryAPICacheRefreshErrorCounter.Inc()
return
}

in.discoveryAPICacheRefreshCounter.Inc()
}

func (in *prometheusRecorder) ServiceReconciliation(serviceID, serviceName string, err error) {
if err != nil {
in.serviceReconciliationErrorCounter.WithLabelValues(serviceID, serviceName).Inc()
return
}

in.serviceReconciliationCounter.WithLabelValues(serviceID, serviceName).Inc()
}

func (in *prometheusRecorder) StackRunJobCreation() {
in.stackRunJobsCreatedCounter.Inc()
}

func (in *prometheusRecorder) init() Recorder {
in.discoveryAPICacheRefreshCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: DiscoveryAPICacheRefreshMetricName,
Help: DiscoveryAPICacheRefreshMetricDescription,
})

in.discoveryAPICacheRefreshErrorCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: DiscoveryAPICacheRefreshErrorMetricName,
Help: DiscoveryAPICacheRefreshErrorMetricDescription,
})

in.serviceReconciliationCounter = promauto.NewCounterVec(prometheus.CounterOpts{
Name: ServiceReconciliationMetricName,
Help: ServiceReconciliationMetricDescription,
}, []string{ServiceReconciliationMetricLabelServiceID, ServiceReconciliationMetricLabelServiceName})

in.serviceReconciliationErrorCounter = promauto.NewCounterVec(prometheus.CounterOpts{
Name: ServiceReconciliationErrorMetricName,
Help: ServiceReconciliationErrorMetricDescription,
}, []string{ServiceReconciliationMetricLabelServiceID, ServiceReconciliationMetricLabelServiceName})

in.stackRunJobsCreatedCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: StackRunJobsCreatedMetricName,
Help: StackRunJobsCreatedMetricDescription,
})

return in
}

func Record() Recorder {
return recorder
}
27 changes: 27 additions & 0 deletions internal/metrics/metrics_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package metrics

const (
DiscoveryAPICacheRefreshMetricName = "agent_discoveryapi_cache_refresh_total"
DiscoveryAPICacheRefreshMetricDescription = "The total number of Discovery API cache refresh attempts"

DiscoveryAPICacheRefreshErrorMetricName = "agent_discoveryapi_cache_refresh_error_total"
DiscoveryAPICacheRefreshErrorMetricDescription = "The total number of Discovery API cache refresh errors"

ServiceReconciliationMetricName = "agent_service_reconciliations_total"
ServiceReconciliationMetricDescription = "The total number of service reconciliations"

ServiceReconciliationErrorMetricName = "agent_service_reconciliation_errors_total"
ServiceReconciliationErrorMetricDescription = "The total number of service reconciliation errors"

ServiceReconciliationMetricLabelServiceID = "service_id"
ServiceReconciliationMetricLabelServiceName = "service_name"

StackRunJobsCreatedMetricName = "agent_stack_runs_created_total"
StackRunJobsCreatedMetricDescription = "The total number of created stack runs"
)

type Recorder interface {
DiscoveryAPICacheRefresh(err error)
ServiceReconciliation(serviceID, serviceName string, err error)
StackRunJobCreation()
}
3 changes: 2 additions & 1 deletion pkg/controller/namespaces/socket_publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package namespaces

import (
console "github.com/pluralsh/console-client-go"
"github.com/pluralsh/deployment-operator/pkg/client"
"k8s.io/client-go/util/workqueue"

"github.com/pluralsh/deployment-operator/pkg/client"
)

type socketPublisher struct {
Expand Down
6 changes: 5 additions & 1 deletion pkg/controller/service/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

clienterrors "github.com/pluralsh/deployment-operator/internal/errors"
"github.com/pluralsh/deployment-operator/internal/helpers"
"github.com/pluralsh/deployment-operator/internal/metrics"
"github.com/pluralsh/deployment-operator/internal/utils"
"github.com/pluralsh/deployment-operator/pkg/applier"
"github.com/pluralsh/deployment-operator/pkg/client"
Expand Down Expand Up @@ -109,10 +110,11 @@ func NewServiceReconciler(ctx context.Context, consoleClient client.Client, conf
}

_ = helpers.BackgroundPollUntilContextCancel(ctx, 5*time.Minute, true, true, func(_ context.Context) (done bool, err error) {
if err := CapabilitiesAPIVersions(discoveryClient); err != nil {
if err = CapabilitiesAPIVersions(discoveryClient); err != nil {
logger.Error(err, "can't fetch API versions")
}

metrics.Record().DiscoveryAPICacheRefresh(err)
return false, nil
})

Expand Down Expand Up @@ -293,6 +295,8 @@ func (s *ServiceReconciler) Reconcile(ctx context.Context, id string) (result re
s.UpdateErrorStatus(ctx, id, err)
}
}

metrics.Record().ServiceReconciliation(id, svc.Name, err)
}()

logger.V(2).Info("local", "flag", Local)
Expand Down
2 changes: 2 additions & 0 deletions pkg/controller/stacks/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/log"

"github.com/pluralsh/deployment-operator/internal/metrics"
consoleclient "github.com/pluralsh/deployment-operator/pkg/client"
)

Expand Down Expand Up @@ -93,6 +94,7 @@ func (r *StackReconciler) reconcileRunJob(ctx context.Context, run *console.Stac
return nil, err
}

metrics.Record().StackRunJobCreation()
if err := r.ConsoleClient.UpdateStackRun(run.ID, console.StackRunAttributes{
Status: run.Status,
JobRef: &console.NamespacedName{
Expand Down
3 changes: 2 additions & 1 deletion pkg/controller/stacks/socket_publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package stacks

import (
console "github.com/pluralsh/console-client-go"
"github.com/pluralsh/deployment-operator/pkg/client"
"k8s.io/client-go/util/workqueue"

"github.com/pluralsh/deployment-operator/pkg/client"
)

type socketPublisher struct {
Expand Down

0 comments on commit afea748

Please sign in to comment.