diff --git a/pkg/infra/metrics/metrics.go b/pkg/infra/metrics/metrics.go index 73a390bdf22..4dd89888b0c 100644 --- a/pkg/infra/metrics/metrics.go +++ b/pkg/infra/metrics/metrics.go @@ -6,6 +6,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/grafana/grafana/pkg/infra/metrics/metricutil" + "github.com/grafana/grafana/pkg/services/accesscontrol" pubdash "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/setting" ) @@ -104,6 +105,9 @@ var ( // MAccessEvaluationCount is a metric gauge for total number of evaluation requests MAccessEvaluationCount prometheus.Counter + // MAccessPermissionsCacheUsage is a metric counter for cache usage + MAccessPermissionsCacheUsage *prometheus.CounterVec + // MPublicDashboardRequestCount is a metric counter for public dashboards requests MPublicDashboardRequestCount prometheus.Counter @@ -590,6 +594,12 @@ func init() { Buckets: prometheus.ExponentialBuckets(0.001, 10, 6), }) + MAccessPermissionsCacheUsage = metricutil.NewCounterVecStartingAtZero(prometheus.CounterOpts{ + Name: "access_permissions_cache_usage", + Help: "access control permissions cache hit/miss", + Namespace: ExporterName, + }, []string{"status"}, map[string][]string{"status": accesscontrol.CacheUsageStatuses}) + StatsTotalLibraryPanels = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "stat_totals_library_panels", Help: "total amount of library panels in the database", @@ -708,6 +718,8 @@ func initMetricVars(reg prometheus.Registerer) { MAccessPermissionsSummary, MAccessEvaluationsSummary, MAccessSearchPermissionsSummary, + MAccessEvaluationCount, + MAccessPermissionsCacheUsage, MAlertingActiveAlerts, MStatTotalDashboards, MStatTotalFolders, @@ -728,7 +740,6 @@ func initMetricVars(reg prometheus.Registerer) { StatsTotalAnnotations, StatsTotalAlertRules, StatsTotalRuleGroups, - MAccessEvaluationCount, StatsTotalLibraryPanels, StatsTotalLibraryVariables, StatsTotalDataKeys, diff --git a/pkg/services/accesscontrol/acimpl/service.go b/pkg/services/accesscontrol/acimpl/service.go index 7f71d48643b..13f10c43a97 100644 --- a/pkg/services/accesscontrol/acimpl/service.go +++ b/pkg/services/accesscontrol/acimpl/service.go @@ -151,11 +151,13 @@ func (s *Service) getCachedUserPermissions(ctx context.Context, user identity.Re if !options.ReloadCache { permissions, ok := s.cache.Get(key) if ok { + metrics.MAccessPermissionsCacheUsage.WithLabelValues(accesscontrol.CacheHit).Inc() s.log.Debug("Using cached permissions", "key", key) return permissions.([]accesscontrol.Permission), nil } } + metrics.MAccessPermissionsCacheUsage.WithLabelValues(accesscontrol.CacheMiss).Inc() s.log.Debug("Fetch permissions from store", "key", key) permissions, err := s.getUserPermissions(ctx, user, options) if err != nil { diff --git a/pkg/services/accesscontrol/models.go b/pkg/services/accesscontrol/models.go index 2e848e2ab37..ce353e721c5 100644 --- a/pkg/services/accesscontrol/models.go +++ b/pkg/services/accesscontrol/models.go @@ -13,7 +13,15 @@ import ( "github.com/grafana/grafana/pkg/util/errutil" ) -var ErrInternal = errutil.Internal("accesscontrol.internal") +const ( + CacheHit = "hit" + CacheMiss = "miss" +) + +var ( + ErrInternal = errutil.Internal("accesscontrol.internal") + CacheUsageStatuses = []string{CacheHit, CacheMiss} +) // RoleRegistration stores a role and its assignments to built-in roles // (Viewer, Editor, Admin, Grafana Admin)