Skip to content

Commit

Permalink
πŸš€ feat: added cache metrics to the prometheus monitor (cyclops-ui#474)
Browse files Browse the repository at this point in the history
* πŸš€ feat: added cache metrics to the prometheus monitor

* πŸ”€ fix: changed type of cache metrics to gauge from counter

- refactored to `Set` the latest cache metric instead of using `Add`
  • Loading branch information
naineel1209 authored Jul 29, 2024
1 parent 30297d9 commit 0229ded
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 4 deletions.
3 changes: 3 additions & 0 deletions cyclops-ctrl/cmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"strconv"
"time"

_ "github.com/joho/godotenv/autoload"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -80,6 +81,8 @@ func main() {

renderer := render.NewRenderer(k8sClient)

prometheus.StartCacheMetricsUpdater(&monitor, templatesRepo.ReturnCache(), 10*time.Second, setupLog)

handler, err := handler.New(templatesRepo, k8sClient, renderer, telemetryClient, monitor)
if err != nil {
panic(err)
Expand Down
86 changes: 82 additions & 4 deletions cyclops-ctrl/internal/prometheus/handler.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,80 @@
package prometheus

import (
"time"

"github.com/dgraph-io/ristretto"
"github.com/go-logr/logr"
"github.com/prometheus/client_golang/prometheus"
"sigs.k8s.io/controller-runtime/pkg/metrics"
)

type Monitor struct {
ModulesDeployed prometheus.Gauge
ModulesDeployed prometheus.Gauge
CacheHits prometheus.Gauge
CacheMisses prometheus.Gauge
CacheKeysAdded prometheus.Gauge
CacheCostAdded prometheus.Gauge
CacheKeysEvicted prometheus.Gauge
CacheCostEvicted prometheus.Gauge
}

func NewMonitor(logger logr.Logger) (Monitor, error) {

m := Monitor{
ModulesDeployed: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "modules_deployed",
Help: "No of modules Inc or Dec",
Namespace: "cyclops",
}),
CacheHits: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cache_hits",
Help: "No of cache hits",
Namespace: "cyclops",
}),
CacheMisses: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cache_misses",
Help: "No of cache misses",
Namespace: "cyclops",
}),
CacheKeysAdded: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cache_keys_added",
Help: "No of cache keys added",
Namespace: "cyclops",
}),
CacheCostAdded: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cache_cost_added",
Help: "No of cache cost added",
Namespace: "cyclops",
}),
CacheKeysEvicted: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cache_keys_evicted",
Help: "No of cache keys evicted",
Namespace: "cyclops",
}),
CacheCostEvicted: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cache_cost_evicted",
Help: "No of cache cost evicted",
Namespace: "cyclops",
}),
}
if err := metrics.Registry.Register(m.ModulesDeployed); err != nil {
logger.Error(err, "unable to connect prometheus")
return Monitor{}, err

metricsList :=
[]prometheus.Collector{
m.ModulesDeployed,
m.CacheHits,
m.CacheMisses,
m.CacheKeysAdded,
m.CacheCostAdded,
m.CacheKeysEvicted,
m.CacheCostEvicted,
}

for _, metric := range metricsList {
if err := metrics.Registry.Register(metric); err != nil {
logger.Error(err, "unable to connect prometheus")
return Monitor{}, err
}
}

return m, nil
Expand All @@ -33,3 +87,27 @@ func (m *Monitor) IncModule() {
func (m *Monitor) DecModule() {
m.ModulesDeployed.Dec()
}

func (m *Monitor) UpdateCacheMetrics(cache *ristretto.Cache) {
cacheMetrics := cache.Metrics

m.CacheHits.Set(float64(cacheMetrics.Hits()))
m.CacheMisses.Set(float64(cacheMetrics.Misses()))
m.CacheKeysAdded.Set(float64(cacheMetrics.KeysAdded()))
m.CacheCostAdded.Set(float64(cacheMetrics.CostAdded()))
m.CacheKeysEvicted.Set(float64(cacheMetrics.KeysEvicted()))
m.CacheCostEvicted.Set(float64(cacheMetrics.CostEvicted()))
}

func StartCacheMetricsUpdater(m *Monitor, cache *ristretto.Cache, interval time.Duration, logger logr.Logger) {
go func() {
ticker := time.NewTicker(interval)
defer ticker.Stop()

logger.Info("starting cache metrics updater")

for range ticker.C {
m.UpdateCacheMetrics(cache)
}
}()
}
5 changes: 5 additions & 0 deletions cyclops-ctrl/internal/template/cache/inmemory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func NewInMemoryTemplatesCache() Templates {
NumCounters: 1e7, // number of keys to track frequency of (10M).
MaxCost: 1 << 30, // maximum cost of cache (1GB).
BufferItems: 64, // number of keys per Get buffer.
Metrics: true,
})
if err != nil {
panic(err)
Expand Down Expand Up @@ -82,6 +83,10 @@ func (t Templates) SetTemplateInitialValues(repo, path, version string, values m
t.cache.Wait()
}

func (t Templates) ReturnCache() *ristretto.Cache {
return t.cache
}

func templateKey(repo, path, version string) string {
return fmt.Sprintf("template:%v/%v@%v", repo, path, version)
}
Expand Down
6 changes: 6 additions & 0 deletions cyclops-ctrl/internal/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/auth"
"github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models"
"github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models/helm"
"github.com/dgraph-io/ristretto"
)

type Repo struct {
Expand All @@ -18,6 +19,7 @@ type templateCache interface {
SetTemplate(repo, path, version string, template *models.Template)
GetTemplateInitialValues(repo, path, version string) (map[string]interface{}, bool)
SetTemplateInitialValues(repo, path, version string, values map[string]interface{})
ReturnCache() *ristretto.Cache
}

func NewRepo(credResolver auth.TemplatesResolver, tc templateCache) *Repo {
Expand Down Expand Up @@ -106,3 +108,7 @@ func (r Repo) loadDependenciesInitialValues(metadata *helm.Metadata) (map[string

return initialValues, nil
}

func (r Repo) ReturnCache() *ristretto.Cache {
return r.cache.ReturnCache()
}

0 comments on commit 0229ded

Please sign in to comment.