Skip to content

Commit 2e85438

Browse files
committed
Add metric example to simple-csi
Signed-off-by: Jing Liu <[email protected]>
1 parent 81eaeda commit 2e85438

File tree

6 files changed

+88
-10
lines changed

6 files changed

+88
-10
lines changed

examples/simple/go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ replace github.com/cert-manager/csi-lib => ../../
77
require (
88
github.com/cert-manager/cert-manager v1.19.1
99
github.com/cert-manager/csi-lib v0.0.0-00010101000000-000000000000
10+
github.com/go-logr/logr v1.4.3
11+
github.com/prometheus/client_golang v1.23.2
12+
golang.org/x/sync v0.17.0
1013
k8s.io/client-go v0.34.1
1114
k8s.io/klog/v2 v2.130.1
1215
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
@@ -23,7 +26,6 @@ require (
2326
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
2427
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
2528
github.com/go-ldap/ldap/v3 v3.4.12 // indirect
26-
github.com/go-logr/logr v1.4.3 // indirect
2729
github.com/go-logr/zapr v1.3.0 // indirect
2830
github.com/go-openapi/jsonpointer v0.22.1 // indirect
2931
github.com/go-openapi/jsonreference v0.21.2 // indirect
@@ -43,7 +45,6 @@ require (
4345
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
4446
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
4547
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
46-
github.com/prometheus/client_golang v1.23.2 // indirect
4748
github.com/prometheus/client_model v0.6.2 // indirect
4849
github.com/prometheus/common v0.66.1 // indirect
4950
github.com/prometheus/procfs v0.17.0 // indirect

examples/simple/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwE
171171
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
172172
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
173173
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
174+
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
175+
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
174176
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
175177
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
176178
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

examples/simple/main.go

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,23 @@ import (
2828
"flag"
2929
"fmt"
3030
"net"
31+
"net/http"
3132
"net/url"
3233
"strings"
3334
"time"
3435

3536
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
3637
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
3738
cmclient "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned"
39+
"github.com/cert-manager/cert-manager/pkg/client/informers/externalversions"
3840
"github.com/cert-manager/cert-manager/pkg/util/pki"
3941
"github.com/cert-manager/csi-lib/driver"
4042
"github.com/cert-manager/csi-lib/manager"
4143
"github.com/cert-manager/csi-lib/metadata"
44+
"github.com/cert-manager/csi-lib/metrics"
4245
"github.com/cert-manager/csi-lib/storage"
46+
"github.com/prometheus/client_golang/prometheus"
47+
"golang.org/x/sync/errgroup"
4348
"k8s.io/client-go/rest"
4449
"k8s.io/klog/v2/klogr"
4550
"k8s.io/utils/clock"
@@ -103,13 +108,23 @@ func main() {
103108

104109
store.FSGroupVolumeAttributeKey = FsGroupKey
105110

106-
d, err := driver.New(context.Background(), *endpoint, log, driver.Options{
111+
cmClient := cmclient.NewForConfigOrDie(restConfig)
112+
113+
ctx, cancel := context.WithCancel(context.Background())
114+
defer cancel()
115+
116+
metricsHandler, err := startMetricsServer(ctx, *nodeID, log, cmClient, store)
117+
if err != nil {
118+
panic("failed to setup metrics server: " + err.Error())
119+
}
120+
121+
d, err := driver.New(ctx, *endpoint, log, driver.Options{
107122
DriverName: "csi.cert-manager.io",
108123
DriverVersion: "v0.0.1",
109124
NodeID: *nodeID,
110125
Store: store,
111126
Manager: manager.NewManagerOrDie(manager.Options{
112-
Client: cmclient.NewForConfigOrDie(restConfig),
127+
Client: cmClient,
113128
MetadataReader: store,
114129
Clock: clock.RealClock{},
115130
Log: &log,
@@ -118,6 +133,7 @@ func main() {
118133
GenerateRequest: generateRequest,
119134
SignRequest: signRequest,
120135
WriteKeypair: (&writer{store: store}).writeKeypair,
136+
Metrics: metricsHandler,
121137
}),
122138
})
123139
if err != nil {
@@ -350,3 +366,62 @@ func keyUsagesFromAttributes(usagesCSV string) []cmapi.KeyUsage {
350366

351367
return keyUsages
352368
}
369+
370+
// startMetricsServer starts a server listening on port 6443, until the supplied context is cancelled,
371+
// after which the server will gracefully shutdown (within 5 seconds).
372+
func startMetricsServer(
373+
rootCtx context.Context,
374+
nodeId string,
375+
logger logr.Logger,
376+
cmClient *cmclient.Clientset,
377+
metadataReader storage.MetadataReader,
378+
) (*metrics.Metrics, error) {
379+
g, ctx := errgroup.WithContext(rootCtx)
380+
defer func() {
381+
if err := g.Wait(); err != nil {
382+
logger.Error(err, "fail to stop metric server")
383+
}
384+
}()
385+
386+
metricsHandler := metrics.New(&logger, prometheus.NewRegistry())
387+
388+
certRequestInformerFactory := externalversions.NewSharedInformerFactory(cmClient, 5*time.Second)
389+
certRequestInformer := certRequestInformerFactory.Certmanager().V1().CertificateRequests()
390+
metricsHandler.SetupCertificateRequestCollector(nodeId, metadataReader, certRequestInformer.Lister())
391+
392+
listenConfig := &net.ListenConfig{}
393+
metricsLn, err := listenConfig.Listen(ctx, "tcp", "127.0.0.1:6443")
394+
if err != nil {
395+
return nil, err
396+
}
397+
metricsServer := &http.Server{
398+
Addr: metricsLn.Addr().String(),
399+
ReadTimeout: 8 * time.Second,
400+
WriteTimeout: 8 * time.Second,
401+
MaxHeaderBytes: 1 << 20, // 1 MiB
402+
Handler: metricsHandler.DefaultHandler(),
403+
}
404+
405+
g.Go(func() error {
406+
certRequestInformerFactory.Start(ctx.Done())
407+
certRequestInformerFactory.WaitForCacheSync(ctx.Done())
408+
return nil
409+
})
410+
g.Go(func() error {
411+
<-rootCtx.Done()
412+
// allow a timeout for graceful shutdown
413+
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
414+
defer cancel()
415+
416+
// nolint: contextcheck
417+
return metricsServer.Shutdown(shutdownCtx)
418+
})
419+
g.Go(func() error {
420+
logger.Info("starting metrics server", "address", metricsLn.Addr())
421+
if err := metricsServer.Serve(metricsLn); err != http.ErrServerClosed {
422+
return err
423+
}
424+
return nil
425+
})
426+
return metricsHandler, nil
427+
}

metrics/certificaterequest_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func TestCertificateRequestMetrics(t *testing.T) {
228228
assert.NoError(t, err)
229229
fakeMetadata := storage.NewMemoryFS()
230230
fakeMetadata.RegisterMetadata(test.meta)
231-
m.SetupCertificateRequestCollector(internalapiutil.HashIdentifier(testNodeName), fakeMetadata, certRequestInformer.Lister())
231+
m.SetupCertificateRequestCollector(testNodeName, fakeMetadata, certRequestInformer.Lister())
232232

233233
if err := testutil.CollectAndCompare(m.certificateRequestCollector,
234234
strings.NewReader(expiryMetadata+test.expectedExpiry),
@@ -355,7 +355,7 @@ func TestCertificateRequestCache(t *testing.T) {
355355

356356
testLog := testr.New(t)
357357
m := New(&testLog, prometheus.NewRegistry())
358-
m.SetupCertificateRequestCollector(testNodeNameHash, fakeMetadata, certRequestInformer.Lister())
358+
m.SetupCertificateRequestCollector(testNodeName, fakeMetadata, certRequestInformer.Lister())
359359

360360
// Check all three metrics exist
361361
if err := testutil.CollectAndCompare(m.certificateRequestCollector,

metrics/metrics.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/prometheus/client_golang/prometheus"
2525
"github.com/prometheus/client_golang/prometheus/promhttp"
2626

27+
internalapiutil "github.com/cert-manager/csi-lib/internal/api/util"
2728
"github.com/cert-manager/csi-lib/storage"
2829
)
2930

@@ -95,8 +96,8 @@ func (m *Metrics) DefaultHandler() http.Handler {
9596
return mux
9697
}
9798

98-
func (m *Metrics) SetupCertificateRequestCollector(nodeNameHash string, metadataReader storage.MetadataReader, certificateRequestLister cmlisters.CertificateRequestLister) {
99-
m.certificateRequestCollector = NewCertificateRequestCollector(nodeNameHash, metadataReader, certificateRequestLister)
99+
func (m *Metrics) SetupCertificateRequestCollector(nodeId string, metadataReader storage.MetadataReader, certificateRequestLister cmlisters.CertificateRequestLister) {
100+
m.certificateRequestCollector = NewCertificateRequestCollector(internalapiutil.HashIdentifier(nodeId), metadataReader, certificateRequestLister)
100101
m.registry.MustRegister(m.certificateRequestCollector)
101102
}
102103

test/integration/metrics_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import (
4141
"k8s.io/apimachinery/pkg/util/wait"
4242
fakeclock "k8s.io/utils/clock/testing"
4343

44-
internalapiutil "github.com/cert-manager/csi-lib/internal/api/util"
4544
"github.com/cert-manager/csi-lib/manager"
4645
"github.com/cert-manager/csi-lib/metadata"
4746
"github.com/cert-manager/csi-lib/metrics"
@@ -108,7 +107,7 @@ func TestMetricsServer(t *testing.T) {
108107
// https://github.com/kubernetes/client-go/blob/5a019202120ab4dd7dfb3788e5cb87269f343ebe/tools/cache/shared_informer.go#L575
109108
factory := externalversions.NewSharedInformerFactory(fakeClient, time.Second)
110109
certRequestInformer := factory.Certmanager().V1().CertificateRequests()
111-
metricsHandler.SetupCertificateRequestCollector(internalapiutil.HashIdentifier(testNodeId), store, certRequestInformer.Lister())
110+
metricsHandler.SetupCertificateRequestCollector(testNodeId, store, certRequestInformer.Lister())
112111
factory.Start(ctx.Done())
113112
factory.WaitForCacheSync(ctx.Done())
114113

0 commit comments

Comments
 (0)