From bfb957cb6fd50911617b1f4ff985946f17ff3980 Mon Sep 17 00:00:00 2001 From: Milan Pavlik Date: Fri, 16 Sep 2022 07:37:49 +0000 Subject: [PATCH] [baseserver] Add metric with version of the server, use in public api and usage --- components/common-go/baseserver/metrics.go | 37 +++++++++++++++++++ components/common-go/baseserver/options.go | 13 ++++++- .../common-go/baseserver/options_test.go | 2 + components/common-go/baseserver/server.go | 7 ++++ components/public-api-server/cmd/run.go | 2 +- .../public-api-server/pkg/server/server.go | 3 +- components/usage/cmd/run.go | 2 +- components/usage/pkg/server/server.go | 6 ++- 8 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 components/common-go/baseserver/metrics.go diff --git a/components/common-go/baseserver/metrics.go b/components/common-go/baseserver/metrics.go new file mode 100644 index 00000000000000..f6751edf0f1e5b --- /dev/null +++ b/components/common-go/baseserver/metrics.go @@ -0,0 +1,37 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License-AGPL.txt in the project root for license information. + +package baseserver + +import ( + "fmt" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + serverVersionGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: "gitpod", + Subsystem: "server", + Name: "version", + Help: "Gauge of the current version of a gitpod server", + }, []string{"version"}) +) + +func registerMetrics(reg *prometheus.Registry) error { + metrics := []prometheus.Collector{ + serverVersionGauge, + } + for _, metric := range metrics { + err := reg.Register(metric) + if err != nil { + return fmt.Errorf("failed to register metric: %w", err) + } + } + + return nil +} + +func reportServerVersion(version string) { + serverVersionGauge.WithLabelValues(version).Set(1) +} diff --git a/components/common-go/baseserver/options.go b/components/common-go/baseserver/options.go index 812c3d32e732a0..312ce73fec3de6 100644 --- a/components/common-go/baseserver/options.go +++ b/components/common-go/baseserver/options.go @@ -19,6 +19,9 @@ import ( type options struct { logger *logrus.Entry + // version is the version of this application + version string + config *Configuration // closeTimeout is the amount we allow for the server to shut down cleanly @@ -36,7 +39,8 @@ type options struct { func defaultOptions() *options { return &options{ - logger: log.New(), + logger: log.New(), + version: "unknown", config: &Configuration{ Services: ServicesConfiguration{ GRPC: nil, // disabled by default @@ -61,6 +65,13 @@ func WithConfig(config *Configuration) Option { } } +func WithVersion(version string) Option { + return func(opts *options) error { + opts.version = version + return nil + } +} + func WithUnderTest() Option { return func(opts *options) error { opts.underTest = true diff --git a/components/common-go/baseserver/options_test.go b/components/common-go/baseserver/options_test.go index 3a63e930f40a25..fa39d1f697209a 100644 --- a/components/common-go/baseserver/options_test.go +++ b/components/common-go/baseserver/options_test.go @@ -32,6 +32,7 @@ func TestOptions(t *testing.T) { WithMetricsRegistry(registry), WithHealthHandler(health), WithGRPCHealthService(grpcHealthService), + WithVersion("foo-bar"), } actual, err := evaluateOptions(defaultOptions(), opts...) require.NoError(t, err) @@ -48,6 +49,7 @@ func TestOptions(t *testing.T) { metricsRegistry: registry, healthHandler: health, grpcHealthCheck: grpcHealthService, + version: "foo-bar", } require.Equal(t, expected, actual) diff --git a/components/common-go/baseserver/server.go b/components/common-go/baseserver/server.go index 36f38afc544329..9ab3bda7baf24b 100644 --- a/components/common-go/baseserver/server.go +++ b/components/common-go/baseserver/server.go @@ -320,6 +320,13 @@ func (s *Server) initializeMetrics() error { return fmt.Errorf("failed to register process collectors: %w", err) } + err = registerMetrics(s.MetricsRegistry()) + if err != nil { + return fmt.Errorf("failed to register baseserver metrics: %w", err) + } + + reportServerVersion(s.options.version) + return nil } diff --git a/components/public-api-server/cmd/run.go b/components/public-api-server/cmd/run.go index dbc2202c103962..3a2232bae5ff0e 100644 --- a/components/public-api-server/cmd/run.go +++ b/components/public-api-server/cmd/run.go @@ -21,7 +21,7 @@ var runCommand = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { cfg := getConfig() - if err := server.Start(log.Log, cfg); err != nil { + if err := server.Start(log.Log, Version, cfg); err != nil { log.WithError(err).Fatal("cannot start server") } }, diff --git a/components/public-api-server/pkg/server/server.go b/components/public-api-server/pkg/server/server.go index 044eecc956a767..e9de61689cde6e 100644 --- a/components/public-api-server/pkg/server/server.go +++ b/components/public-api-server/pkg/server/server.go @@ -25,7 +25,7 @@ import ( "github.com/sirupsen/logrus" ) -func Start(logger *logrus.Entry, cfg *config.Configuration) error { +func Start(logger *logrus.Entry, version string, cfg *config.Configuration) error { logger.WithField("config", cfg).Info("Starting public-api.") gitpodAPI, err := url.Parse(cfg.GitpodServiceURL) @@ -39,6 +39,7 @@ func Start(logger *logrus.Entry, cfg *config.Configuration) error { baseserver.WithLogger(logger), baseserver.WithConfig(cfg.Server), baseserver.WithMetricsRegistry(registry), + baseserver.WithVersion(version), ) if err != nil { return fmt.Errorf("failed to initialize public api server: %w", err) diff --git a/components/usage/cmd/run.go b/components/usage/cmd/run.go index e23c044fe7fc78..0a7ed289d9db31 100644 --- a/components/usage/cmd/run.go +++ b/components/usage/cmd/run.go @@ -37,7 +37,7 @@ func run() *cobra.Command { log.WithError(err).Fatal("Failed to get config. Did you specify --config correctly?") } - err = server.Start(cfg) + err = server.Start(cfg, Version) if err != nil { log.WithError(err).Fatal("Failed to start usage server.") } diff --git a/components/usage/pkg/server/server.go b/components/usage/pkg/server/server.go index f8e30b311d9aad..91c50ea8681e5b 100644 --- a/components/usage/pkg/server/server.go +++ b/components/usage/pkg/server/server.go @@ -40,7 +40,7 @@ type Config struct { DefaultSpendingLimit db.DefaultSpendingLimit `json:"defaultSpendingLimit"` } -func Start(cfg Config) error { +func Start(cfg Config, version string) error { log.WithField("config", cfg).Info("Starting usage component.") conn, err := db.Connect(db.ConnectionParams{ @@ -53,7 +53,9 @@ func Start(cfg Config) error { return fmt.Errorf("failed to establish database connection: %w", err) } - var serverOpts []baseserver.Option + serverOpts := []baseserver.Option{ + baseserver.WithVersion(version), + } if cfg.Server != nil { serverOpts = append(serverOpts, baseserver.WithConfig(cfg.Server)) }