From a2d4ce18adafbd79380a7feb6e3f5c80049cc2bb Mon Sep 17 00:00:00 2001 From: Karl Persson Date: Thu, 5 Oct 2023 09:17:40 +0200 Subject: [PATCH] IDForwarding: Add basic metrics (#75798) * IDService: Add basic metrics * IDService: Add more metrics --------- Co-authored-by: Gabriel MABILLE --- pkg/services/auth/idimpl/metrics.go | 56 ++++++++++++++++++++++++ pkg/services/auth/idimpl/service.go | 23 +++++++--- pkg/services/auth/idimpl/service_test.go | 7 +-- 3 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 pkg/services/auth/idimpl/metrics.go diff --git a/pkg/services/auth/idimpl/metrics.go b/pkg/services/auth/idimpl/metrics.go new file mode 100644 index 00000000000..0cd3f460391 --- /dev/null +++ b/pkg/services/auth/idimpl/metrics.go @@ -0,0 +1,56 @@ +package idimpl + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +const ( + metricsNamespace = "grafana" + metricsSubSystem = "idforwarding" +) + +func newMetrics(reg prometheus.Registerer) *metrics { + m := &metrics{ + tokenSigningCounter: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: metricsNamespace, + Subsystem: metricsSubSystem, + Name: "idforwarding_token_signing_total", + Help: "Number of token signings", + }), + tokenSigningFromCacheCounter: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: metricsNamespace, + Subsystem: metricsSubSystem, + Name: "idforwarding_token_signing_from_cache_total", + Help: "Number of signed tokens retrieved from cache", + }), + failedTokenSigningCounter: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: metricsNamespace, + Subsystem: metricsSubSystem, + Name: "idforwarding_failed_token_signing_total", + Help: "Number of failed token signings", + }), + tokenSigningDurationHistogram: prometheus.NewHistogram(prometheus.HistogramOpts{ + Namespace: metricsNamespace, + Subsystem: metricsSubSystem, + Name: "idforwarding_token_signing_duration_seconds", + Help: "Histogram of token signing duration", + Buckets: []float64{0.1, 0.25, 0.5, 1, 2, 5, 10}, + }), + } + + if reg != nil { + reg.MustRegister(m.tokenSigningCounter) + reg.MustRegister(m.tokenSigningFromCacheCounter) + reg.MustRegister(m.failedTokenSigningCounter) + reg.MustRegister(m.tokenSigningDurationHistogram) + } + + return m +} + +type metrics struct { + tokenSigningCounter prometheus.Counter + tokenSigningFromCacheCounter prometheus.Counter + failedTokenSigningCounter prometheus.Counter + tokenSigningDurationHistogram prometheus.Histogram +} diff --git a/pkg/services/auth/idimpl/service.go b/pkg/services/auth/idimpl/service.go index 8e41db7a8ee..19a33033a81 100644 --- a/pkg/services/auth/idimpl/service.go +++ b/pkg/services/auth/idimpl/service.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/setting" + "github.com/prometheus/client_golang/prometheus" ) const ( @@ -26,9 +27,9 @@ var _ auth.IDService = (*Service)(nil) func ProvideService( cfg *setting.Cfg, signer auth.IDSigner, cache remotecache.CacheStorage, - features featuremgmt.FeatureToggles, authnService authn.Service, + features featuremgmt.FeatureToggles, authnService authn.Service, reg prometheus.Registerer, ) *Service { - s := &Service{cfg, log.New("id-service"), signer, cache} + s := &Service{cfg, log.New("id-service"), signer, cache, newMetrics(reg)} if features.IsEnabled(featuremgmt.FlagIdForwarding) { authnService.RegisterPostAuthHook(s.hook, 140) @@ -38,22 +39,29 @@ func ProvideService( } type Service struct { - cfg *setting.Cfg - logger log.Logger - signer auth.IDSigner - cache remotecache.CacheStorage + cfg *setting.Cfg + logger log.Logger + signer auth.IDSigner + cache remotecache.CacheStorage + metrics *metrics } func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (string, error) { + defer func(t time.Time) { + s.metrics.tokenSigningDurationHistogram.Observe(time.Since(t).Seconds()) + }(time.Now()) + namespace, identifier := id.GetNamespacedID() cacheKey := prefixCacheKey(id.GetCacheKey()) cachedToken, err := s.cache.Get(ctx, cacheKey) if err == nil { + s.metrics.tokenSigningFromCacheCounter.Inc() s.logger.Debug("Cached token found", "namespace", namespace, "id", identifier) return string(cachedToken), nil } + s.metrics.tokenSigningCounter.Inc() s.logger.Debug("Sign new id token", "namespace", namespace, "id", identifier) now := time.Now() @@ -69,11 +77,12 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri }) if err != nil { + s.metrics.failedTokenSigningCounter.Inc() return "", err } if err := s.cache.Set(ctx, cacheKey, []byte(token), cacheTTL); err != nil { - s.logger.Error("failed to set cache", "error", err) + s.logger.Error("Failed to add id token to cache", "error", err) } return token, nil diff --git a/pkg/services/auth/idimpl/service_test.go b/pkg/services/auth/idimpl/service_test.go index c9c571342d3..14a7fb36d5e 100644 --- a/pkg/services/auth/idimpl/service_test.go +++ b/pkg/services/auth/idimpl/service_test.go @@ -3,11 +3,12 @@ package idimpl import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/authn/authntest" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/setting" - "github.com/stretchr/testify/assert" ) func Test_ProvideService(t *testing.T) { @@ -21,7 +22,7 @@ func Test_ProvideService(t *testing.T) { }, } - _ = ProvideService(setting.NewCfg(), nil, nil, features, authnService) + _ = ProvideService(setting.NewCfg(), nil, nil, features, authnService, nil) assert.True(t, hookRegistered) }) @@ -35,7 +36,7 @@ func Test_ProvideService(t *testing.T) { }, } - _ = ProvideService(setting.NewCfg(), nil, nil, features, authnService) + _ = ProvideService(setting.NewCfg(), nil, nil, features, authnService, nil) assert.False(t, hookRegistered) }) }