diff --git a/cmd/app/grpc.go b/cmd/app/grpc.go index 4ec902fe1..e72d63e0a 100644 --- a/cmd/app/grpc.go +++ b/cmd/app/grpc.go @@ -33,9 +33,8 @@ import ( ctclient "github.com/google/certificate-transparency-go/client" grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - "github.com/prometheus/client_golang/prometheus" "github.com/sigstore/fulcio/pkg/ca" "github.com/sigstore/fulcio/pkg/config" gw "github.com/sigstore/fulcio/pkg/generated/protobuf" @@ -160,6 +159,10 @@ func (c *cachedTLSCert) GRPCCreds() grpc.ServerOption { func createGRPCServer(cfg *config.FulcioConfig, ctClient *ctclient.LogClient, baseca ca.CertificateAuthority, algorithmRegistry *signature.AlgorithmRegistryConfig, ip identity.IssuerPool) (*grpcServer, error) { logger, opts := log.SetupGRPCLogging() + reg := server.InitMetrics() + grpcMetrics := grpc_prometheus.NewServerMetrics(grpc_prometheus.WithServerHandlingTimeHistogram()) + reg.MustRegister(grpcMetrics) + serverOpts := []grpc.ServerOption{ grpc.UnaryInterceptor( grpcmw.ChainUnaryServer( @@ -167,7 +170,7 @@ func createGRPCServer(cfg *config.FulcioConfig, ctClient *ctclient.LogClient, ba middleware.UnaryRequestID(middleware.UseXRequestIDMetadataOption(true), middleware.XRequestMetadataLimitOption(128)), grpc_zap.UnaryServerInterceptor(logger, opts...), PassFulcioConfigThruContext(cfg), - grpc_prometheus.UnaryServerInterceptor, + grpcMetrics.UnaryServerInterceptor(), )), grpc.KeepaliveParams(keepalive.ServerParameters{ MaxConnectionIdle: viper.GetDuration("idle-connection-timeout"), @@ -193,18 +196,12 @@ func createGRPCServer(cfg *config.FulcioConfig, ctClient *ctclient.LogClient, ba health.RegisterHealthServer(myServer, grpcCAServer) // Register your gRPC service implementations. gw.RegisterCAServer(myServer, grpcCAServer) + grpcMetrics.InitializeMetrics(myServer) grpcServerEndpoint := fmt.Sprintf("%s:%s", viper.GetString("grpc-host"), viper.GetString("grpc-port")) return &grpcServer{myServer, grpcServerEndpoint, grpcCAServer, tlsCertWatcher}, nil } -func (g *grpcServer) setupPrometheus(reg *prometheus.Registry) { - grpcMetrics := grpc_prometheus.DefaultServerMetrics - grpcMetrics.EnableHandlingTimeHistogram() - reg.MustRegister(grpcMetrics, server.MetricLatency, server.RequestsCount) - grpc_prometheus.Register(g.Server) -} - func (g *grpcServer) startTCPListener(wg *sync.WaitGroup) { // lis is closed by g.Server.Serve() upon exit lis, err := net.Listen("tcp", g.grpcServerEndpoint) @@ -274,13 +271,17 @@ func (g *grpcServer) ExposesGRPCTLS() bool { func createLegacyGRPCServer(cfg *config.FulcioConfig, unixDomainSocket string, v2Server gw.CAServer) (*grpcServer, error) { logger, opts := log.SetupGRPCLogging() + reg := server.InitMetrics() + grpcMetrics := grpc_prometheus.NewServerMetrics(grpc_prometheus.WithServerHandlingTimeHistogram()) + reg.MustRegister(grpcMetrics) + myServer := grpc.NewServer(grpc.UnaryInterceptor( grpcmw.ChainUnaryServer( grpc_recovery.UnaryServerInterceptor(grpc_recovery.WithRecoveryHandlerContext(panicRecoveryHandler)), // recovers from per-transaction panics elegantly, so put it first middleware.UnaryRequestID(middleware.UseXRequestIDMetadataOption(true), middleware.XRequestMetadataLimitOption(128)), grpc_zap.UnaryServerInterceptor(logger, opts...), PassFulcioConfigThruContext(cfg), - grpc_prometheus.UnaryServerInterceptor, + grpcMetrics.UnaryServerInterceptor(), )), grpc.MaxRecvMsgSize(int(maxMsgSize))) @@ -288,6 +289,7 @@ func createLegacyGRPCServer(cfg *config.FulcioConfig, unixDomainSocket string, v // Register your gRPC service implementations. gw_legacy.RegisterCAServer(myServer, legacyGRPCCAServer) + grpcMetrics.InitializeMetrics(myServer) return &grpcServer{myServer, unixDomainSocket, v2Server, nil}, nil } diff --git a/cmd/app/serve.go b/cmd/app/serve.go index 0932e97a0..7d8bddd86 100644 --- a/cmd/app/serve.go +++ b/cmd/app/serve.go @@ -42,10 +42,9 @@ import ( "github.com/google/certificate-transparency-go/jsonclient" grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" certauth "github.com/sigstore/fulcio/pkg/ca" "github.com/sigstore/fulcio/pkg/ca/ephemeralca" @@ -361,13 +360,11 @@ func runServeCmd(cmd *cobra.Command, args []string) { //nolint: revive httpServerEndpoint := fmt.Sprintf("%v:%v", viper.GetString("http-host"), viper.GetString("http-port")) - reg := prometheus.NewRegistry() - grpcServer, err := createGRPCServer(cfg, ctClient, baseca, algorithmRegistry, ip) if err != nil { log.Logger.Fatal(err) } - grpcServer.setupPrometheus(reg) + grpcServer.startTCPListener(&wg) legacyGRPCServer, err := createLegacyGRPCServer(cfg, viper.GetString("legacy-unix-domain-socket"), grpcServer.caService) @@ -444,6 +441,11 @@ func checkServeCmdConfigFile() error { func StartDuplexServer(ctx context.Context, cfg *config.FulcioConfig, ctClient *ctclient.LogClient, baseca certauth.CertificateAuthority, algorithmRegistry *signature.AlgorithmRegistryConfig, host string, port, metricsPort int, ip identity.IssuerPool) error { logger, opts := log.SetupGRPCLogging() + // configure Prometheus + reg := server.InitMetrics() + grpcMetrics := grpc_prometheus.NewServerMetrics(grpc_prometheus.WithServerHandlingTimeHistogram()) + reg.MustRegister(grpcMetrics) + d := duplex.New( port, grpc.WithTransportCredentials(insecure.NewCredentials()), @@ -456,12 +458,14 @@ func StartDuplexServer(ctx context.Context, cfg *config.FulcioConfig, ctClient * middleware.UnaryRequestID(middleware.UseXRequestIDMetadataOption(true), middleware.XRequestMetadataLimitOption(128)), grpc_zap.UnaryServerInterceptor(logger, opts...), PassFulcioConfigThruContext(cfg), - grpc_prometheus.UnaryServerInterceptor, + grpcMetrics.UnaryServerInterceptor(), )), grpc.MaxRecvMsgSize(int(maxMsgSize)), runtime.WithForwardResponseOption(setResponseCodeModifier), ) + grpcMetrics.InitializeMetrics(d.Server) + // GRPC server grpcCAServer := server.NewGRPCCAServer(ctClient, baseca, algorithmRegistry, ip) protobuf.RegisterCAServer(d.Server, grpcCAServer) @@ -476,13 +480,6 @@ func StartDuplexServer(ctx context.Context, cfg *config.FulcioConfig, ctClient * return fmt.Errorf("registering legacy grpc ca handler: %w", err) } - // Prometheus - reg := prometheus.NewRegistry() - grpcMetrics := grpc_prometheus.DefaultServerMetrics - grpcMetrics.EnableHandlingTimeHistogram() - reg.MustRegister(grpcMetrics, server.MetricLatency, server.RequestsCount) - grpc_prometheus.Register(d.Server) - // Register prometheus handle. d.RegisterListenAndServeMetrics(metricsPort, false) diff --git a/go.mod b/go.mod index b5e8ec6a0..7dcb4f6db 100644 --- a/go.mod +++ b/go.mod @@ -18,8 +18,8 @@ require ( github.com/google/certificate-transparency-go v1.3.1 github.com/google/go-cmp v0.7.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 github.com/hashicorp/golang-lru v1.0.2 github.com/magiconair/properties v1.8.9 github.com/prometheus/client_golang v1.20.5 @@ -43,7 +43,7 @@ require ( go.step.sm/crypto v0.57.0 go.uber.org/zap v1.27.0 google.golang.org/api v0.218.0 - google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f + google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 google.golang.org/grpc v1.70.0 google.golang.org/protobuf v1.36.5 gopkg.in/yaml.v3 v3.0.1 @@ -51,13 +51,13 @@ require ( ) require ( - cloud.google.com/go v0.116.0 // indirect + cloud.google.com/go v0.118.0 // indirect cloud.google.com/go/auth v0.14.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/iam v1.2.2 // indirect - cloud.google.com/go/kms v1.20.4 // indirect - cloud.google.com/go/longrunning v0.6.2 // indirect + cloud.google.com/go/iam v1.3.1 // indirect + cloud.google.com/go/kms v1.20.5 // indirect + cloud.google.com/go/longrunning v0.6.4 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect @@ -102,6 +102,8 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.14.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -165,8 +167,8 @@ require ( golang.org/x/term v0.29.0 // indirect golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.9.0 // indirect - google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/genproto v0.0.0-20250124145028-65684f501c47 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect gopkg.in/ini.v1 v1.67.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect ) diff --git a/go.sum b/go.sum index 7d5440900..fce46cda2 100644 --- a/go.sum +++ b/go.sum @@ -3,20 +3,20 @@ chainguard.dev/go-grpc-kit v0.17.7/go.mod h1:JroMzTY9mdhKe/bvtyChgfECaNh80+bMZH3 chainguard.dev/sdk v0.1.29 h1:GNcCw5NoyvylhlUbVD8JMmrPaeYyrshaHHjEWnvcCGI= chainguard.dev/sdk v0.1.29/go.mod h1:DqywTjZ5glB/gUCKkrecO0LywyfcAd5v7IPo2+d91qA= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= -cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= +cloud.google.com/go v0.118.0 h1:tvZe1mgqRxpiVa3XlIGMiPcEUbP1gNXELgD4y/IXmeQ= +cloud.google.com/go v0.118.0/go.mod h1:zIt2pkedt/mo+DQjcT4/L3NDxzHPR29j5HcclNH+9PM= cloud.google.com/go/auth v0.14.0 h1:A5C4dKV/Spdvxcl0ggWwWEzzP7AZMJSEIgrkngwhGYM= cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A= cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= -cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= -cloud.google.com/go/kms v1.20.4 h1:CJ0hMpOg1ANN9tx/a/GPJ+Uxudy8k6f3fvGFuTHiE5A= -cloud.google.com/go/kms v1.20.4/go.mod h1:gPLsp1r4FblUgBYPOcvI/bUPpdMg2Jm1ZVKU4tQUfcc= -cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= -cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= +cloud.google.com/go/iam v1.3.1 h1:KFf8SaT71yYq+sQtRISn90Gyhyf4X8RGgeAVC8XGf3E= +cloud.google.com/go/iam v1.3.1/go.mod h1:3wMtuyT4NcbnYNPLMBzYRFiEfjKfJlLVLrisE7bwm34= +cloud.google.com/go/kms v1.20.5 h1:aQQ8esAIVZ1atdJRxihhdxGQ64/zEbJoJnCz/ydSmKg= +cloud.google.com/go/kms v1.20.5/go.mod h1:C5A8M1sv2YWYy1AE6iSrnddSG9lRGdJq5XEdBy28Lmw= +cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg= +cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs= cloud.google.com/go/security v1.18.3 h1:ya9gfY1ign6Yy25VMMMgZ9xy7D/TczDB0ElXcyWmEVE= cloud.google.com/go/security v1.18.3/go.mod h1:NmlSnEe7vzenMRoTLehUwa/ZTZHDQE59IPRevHcpCe4= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= @@ -173,10 +173,14 @@ github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrk github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 h1:JYghRBlGCZyCF2wNUJ8W0cwaQdtpcssJ4CgC406g+WU= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 h1:VD1gqscl4nYs1YxVuSdemTrSgTKrwOWDK0FVFMqm+Cg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0/go.mod h1:4EgsQoS4TOhJizV+JTFg40qx1Ofh3XmXEQNBpgvNT40= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -518,12 +522,12 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= -google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= -google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA= -google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/genproto v0.0.0-20250124145028-65684f501c47 h1:SI8Hf7K4+uVYchXqZiMfP44PZ83xomMWovbcFfm0P8Q= +google.golang.org/genproto v0.0.0-20250124145028-65684f501c47/go.mod h1:qbZzneIOXSq+KFAFut9krLfRLZiFLzZL5u2t8SV83EE= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= diff --git a/pkg/server/metrics.go b/pkg/server/metrics.go index de437b772..c6c8e8895 100644 --- a/pkg/server/metrics.go +++ b/pkg/server/metrics.go @@ -16,39 +16,54 @@ package server import ( + "sync" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "sigs.k8s.io/release-utils/version" ) var ( - metricNewEntries = promauto.NewCounter(prometheus.CounterOpts{ - Name: "fulcio_new_certs", - Help: "The total number of certificates generated", - }) - - MetricLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Name: "fulcio_api_latency", - Help: "API Latency on calls", - }, []string{"code", "method"}) - - RequestsCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "http_requests_total", - Help: "Count all HTTP requests", - }, []string{"code", "method"}) - - _ = promauto.NewGaugeFunc( - prometheus.GaugeOpts{ - Namespace: "fulcio", - Name: "build_info", - Help: "A metric with a constant '1' value labeled by version, revision, branch, and goversion from which fulcio was built.", - ConstLabels: prometheus.Labels{ - "version": version.GetVersionInfo().GitVersion, - "revision": version.GetVersionInfo().GitCommit, - "build_date": version.GetVersionInfo().BuildDate, - "goversion": version.GetVersionInfo().GoVersion, - }, - }, - func() float64 { return 1 }, - ) + metricNewEntries prometheus.Counter + MetricLatency *prometheus.HistogramVec + RequestsCount *prometheus.CounterVec ) + +// InitMetrics will create a single registry to share across the application +func InitMetrics() *prometheus.Registry { + return sync.OnceValue[*prometheus.Registry](func() *prometheus.Registry { + + reg := prometheus.NewRegistry() + metricsFactory := promauto.With(reg) + metricNewEntries = metricsFactory.NewCounter(prometheus.CounterOpts{ + Name: "fulcio_new_certs", + Help: "The total number of certificates generated", + }) + + MetricLatency = metricsFactory.NewHistogramVec(prometheus.HistogramOpts{ + Name: "fulcio_api_latency", + Help: "API Latency on calls", + }, []string{"code", "method"}) + + RequestsCount = metricsFactory.NewCounterVec(prometheus.CounterOpts{ + Name: "http_requests_total", + Help: "Count all HTTP requests", + }, []string{"code", "method"}) + + _ = metricsFactory.NewGaugeFunc( + prometheus.GaugeOpts{ + Namespace: "fulcio", + Name: "build_info", + Help: "A metric with a constant '1' value labeled by version, revision, branch, and goversion from which fulcio was built.", + ConstLabels: prometheus.Labels{ + "version": version.GetVersionInfo().GitVersion, + "revision": version.GetVersionInfo().GitCommit, + "build_date": version.GetVersionInfo().BuildDate, + "goversion": version.GetVersionInfo().GoVersion, + }, + }, + func() float64 { return 1 }, + ) + return reg + })() +}