Skip to content

Commit 903116d

Browse files
committed
add kcp operator custom metrics
Signed-off-by: olalekan odukoya <[email protected]>
1 parent d4b5a9c commit 903116d

File tree

9 files changed

+461
-2
lines changed

9 files changed

+461
-2
lines changed

cmd/main.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/kcp-dev/kcp-operator/internal/controller/kubeconfig"
4242
"github.com/kcp-dev/kcp-operator/internal/controller/rootshard"
4343
"github.com/kcp-dev/kcp-operator/internal/controller/shard"
44+
"github.com/kcp-dev/kcp-operator/internal/metrics"
4445
"github.com/kcp-dev/kcp-operator/internal/reconciling"
4546
operatorv1alpha1 "github.com/kcp-dev/kcp-operator/sdk/apis/operator/v1alpha1"
4647
)
@@ -190,6 +191,12 @@ func main() {
190191
}
191192
// +kubebuilder:scaffold:builder
192193

194+
metrics.RegisterMetrics()
195+
196+
metricsCollector := metrics.NewMetricsCollector(mgr.GetClient())
197+
ctx := ctrl.SetupSignalHandler()
198+
go metricsCollector.Start(ctx)
199+
193200
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
194201
setupLog.Error(err, "unable to set up health check")
195202
os.Exit(1)
@@ -200,7 +207,7 @@ func main() {
200207
}
201208

202209
setupLog.Info("starting manager")
203-
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
210+
if err := mgr.Start(ctx); err != nil {
204211
setupLog.Error(err, "problem running manager")
205212
os.Exit(1)
206213
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/kcp-dev/kcp-operator/sdk v0.0.0-00010101000000-000000000000
1414
github.com/kcp-dev/kcp/sdk v0.27.1
1515
github.com/kcp-dev/logicalcluster/v3 v3.0.5
16+
github.com/prometheus/client_golang v1.20.5
1617
github.com/stretchr/testify v1.10.0
1718
go.uber.org/zap v1.27.0
1819
k8c.io/reconciler v0.5.0
@@ -68,7 +69,6 @@ require (
6869
github.com/onsi/gomega v1.35.1 // indirect
6970
github.com/pkg/errors v0.9.1 // indirect
7071
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
71-
github.com/prometheus/client_golang v1.20.5 // indirect
7272
github.com/prometheus/client_model v0.6.1 // indirect
7373
github.com/prometheus/common v0.61.0 // indirect
7474
github.com/prometheus/procfs v0.15.1 // indirect

internal/controller/frontproxy/controller.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package frontproxy
1919
import (
2020
"context"
2121
"fmt"
22+
"time"
2223

2324
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
2425

@@ -38,6 +39,7 @@ import (
3839
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3940

4041
"github.com/kcp-dev/kcp-operator/internal/controller/util"
42+
"github.com/kcp-dev/kcp-operator/internal/metrics"
4143
"github.com/kcp-dev/kcp-operator/internal/resources"
4244
"github.com/kcp-dev/kcp-operator/internal/resources/frontproxy"
4345
operatorv1alpha1 "github.com/kcp-dev/kcp-operator/sdk/apis/operator/v1alpha1"
@@ -89,12 +91,19 @@ func (r *FrontProxyReconciler) SetupWithManager(mgr ctrl.Manager) error {
8991
// +kubebuilder:rbac:groups=core,resources=services;configmaps;secrets,verbs=get;list;watch;create;update;patch;delete
9092

9193
func (r *FrontProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, recErr error) {
94+
startTime := time.Now()
95+
defer func() {
96+
duration := time.Since(startTime)
97+
metrics.RecordReconciliationMetrics(metrics.FrontProxyResourceType, duration.Seconds(), recErr)
98+
}()
99+
92100
logger := log.FromContext(ctx)
93101
logger.V(4).Info("Reconciling")
94102

95103
var frontProxy operatorv1alpha1.FrontProxy
96104
if err := r.Get(ctx, req.NamespacedName, &frontProxy); err != nil {
97105
if ctrlruntimeclient.IgnoreNotFound(err) != nil {
106+
metrics.RecordReconciliationError(metrics.FrontProxyResourceType, err.Error())
98107
return ctrl.Result{}, fmt.Errorf("failed to get FrontProxy object: %w", err)
99108
}
100109

@@ -108,6 +117,14 @@ func (r *FrontProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
108117
recErr = kerrors.NewAggregate([]error{recErr, err})
109118
}
110119

120+
metrics.RecordObjectMetrics(
121+
metrics.FrontProxyResourceType,
122+
frontProxy.Name,
123+
req.Namespace,
124+
string(frontProxy.Status.Phase),
125+
frontProxy.Status.Conditions,
126+
)
127+
111128
return ctrl.Result{}, recErr
112129
}
113130

internal/controller/kubeconfig/controller.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
"sigs.k8s.io/controller-runtime/pkg/log"
4141

4242
"github.com/kcp-dev/kcp-operator/internal/controller/util"
43+
"github.com/kcp-dev/kcp-operator/internal/metrics"
4344
"github.com/kcp-dev/kcp-operator/internal/reconciling"
4445
"github.com/kcp-dev/kcp-operator/internal/resources"
4546
"github.com/kcp-dev/kcp-operator/internal/resources/kubeconfig"
@@ -74,6 +75,12 @@ func (r *KubeconfigReconciler) SetupWithManager(mgr ctrl.Manager) error {
7475
// Reconcile is part of the main kubernetes reconciliation loop which aims to
7576
// move the current state of the cluster closer to the desired state.
7677
func (r *KubeconfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
78+
startTime := time.Now()
79+
defer func() {
80+
duration := time.Since(startTime)
81+
metrics.RecordReconciliationMetrics(metrics.KubeconfigResourceType, duration.Seconds(), nil)
82+
}()
83+
7784
logger := log.FromContext(ctx)
7885
logger.V(4).Info("Reconciling")
7986

@@ -83,6 +90,7 @@ func (r *KubeconfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
8390
if apierrors.IsNotFound(err) {
8491
return ctrl.Result{}, nil
8592
}
93+
metrics.RecordReconciliationError(metrics.KubeconfigResourceType, err.Error())
8694
return ctrl.Result{}, err
8795
}
8896

@@ -113,6 +121,14 @@ func (r *KubeconfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
113121
recErr = kerrors.NewAggregate([]error{recErr, err})
114122
}
115123

124+
metrics.RecordObjectMetrics(
125+
metrics.KubeconfigResourceType,
126+
kc.Name,
127+
req.Namespace,
128+
string(kc.Status.Phase),
129+
kc.Status.Conditions,
130+
)
131+
116132
return ctrl.Result{}, recErr
117133
}
118134

internal/controller/rootshard/controller.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"fmt"
2222
"sort"
23+
"time"
2324

2425
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
2526
k8creconciling "k8c.io/reconciler/pkg/reconciling"
@@ -40,6 +41,7 @@ import (
4041
"sigs.k8s.io/controller-runtime/pkg/reconcile"
4142

4243
"github.com/kcp-dev/kcp-operator/internal/controller/util"
44+
"github.com/kcp-dev/kcp-operator/internal/metrics"
4345
"github.com/kcp-dev/kcp-operator/internal/reconciling"
4446
"github.com/kcp-dev/kcp-operator/internal/resources"
4547
"github.com/kcp-dev/kcp-operator/internal/resources/frontproxy"
@@ -99,12 +101,19 @@ func (r *RootShardReconciler) SetupWithManager(mgr ctrl.Manager) error {
99101
// For more details, check Reconcile and its Result here:
100102
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/reconcile
101103
func (r *RootShardReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, recErr error) {
104+
startTime := time.Now()
105+
defer func() {
106+
duration := time.Since(startTime)
107+
metrics.RecordReconciliationMetrics(metrics.RootShardResourceType, duration.Seconds(), recErr)
108+
}()
109+
102110
logger := log.FromContext(ctx)
103111
logger.V(4).Info("Reconciling")
104112

105113
var rootShard operatorv1alpha1.RootShard
106114
if err := r.Get(ctx, req.NamespacedName, &rootShard); err != nil {
107115
if ctrlruntimeclient.IgnoreNotFound(err) != nil {
116+
metrics.RecordReconciliationError(metrics.RootShardResourceType, err.Error())
108117
return ctrl.Result{}, fmt.Errorf("failed to find %s/%s: %w", req.Namespace, req.Name, err)
109118
}
110119

@@ -118,6 +127,14 @@ func (r *RootShardReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
118127
recErr = kerrors.NewAggregate([]error{recErr, err})
119128
}
120129

130+
metrics.RecordObjectMetrics(
131+
metrics.RootShardResourceType,
132+
rootShard.Name,
133+
req.Namespace,
134+
string(rootShard.Status.Phase),
135+
rootShard.Status.Conditions,
136+
)
137+
121138
return ctrl.Result{}, recErr
122139
}
123140

internal/controller/shard/controller.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package shard
1919
import (
2020
"context"
2121
"fmt"
22+
"time"
2223

2324
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
2425
k8creconciling "k8c.io/reconciler/pkg/reconciling"
@@ -39,6 +40,7 @@ import (
3940
"sigs.k8s.io/controller-runtime/pkg/reconcile"
4041

4142
"github.com/kcp-dev/kcp-operator/internal/controller/util"
43+
"github.com/kcp-dev/kcp-operator/internal/metrics"
4244
"github.com/kcp-dev/kcp-operator/internal/reconciling"
4345
"github.com/kcp-dev/kcp-operator/internal/resources"
4446
"github.com/kcp-dev/kcp-operator/internal/resources/shard"
@@ -90,12 +92,19 @@ func (r *ShardReconciler) SetupWithManager(mgr ctrl.Manager) error {
9092
// +kubebuilder:rbac:groups=core,resources=secrets;services,verbs=get;list;watch;create;update;patch;delete
9193

9294
func (r *ShardReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, recErr error) {
95+
startTime := time.Now()
96+
defer func() {
97+
duration := time.Since(startTime)
98+
metrics.RecordReconciliationMetrics(metrics.ShardResourceType, duration.Seconds(), recErr)
99+
}()
100+
93101
logger := log.FromContext(ctx)
94102
logger.V(4).Info("Reconciling Shard object")
95103

96104
var s operatorv1alpha1.Shard
97105
if err := r.Get(ctx, req.NamespacedName, &s); err != nil {
98106
if ctrlruntimeclient.IgnoreNotFound(err) != nil {
107+
metrics.RecordReconciliationError(metrics.ShardResourceType, err.Error())
99108
return ctrl.Result{}, fmt.Errorf("failed to get shard: %w", err)
100109
}
101110

@@ -108,6 +117,14 @@ func (r *ShardReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
108117
recErr = kerrors.NewAggregate([]error{recErr, err})
109118
}
110119

120+
metrics.RecordObjectMetrics(
121+
metrics.ShardResourceType,
122+
s.Name,
123+
req.Namespace,
124+
string(s.Status.Phase),
125+
s.Status.Conditions,
126+
)
127+
111128
return ctrl.Result{}, recErr
112129
}
113130

0 commit comments

Comments
 (0)