Skip to content

Commit

Permalink
add collector cache TTL
Browse files Browse the repository at this point in the history
Signed-off-by: Ananya Kumar Mallik <[email protected]>
  • Loading branch information
ananya-mallik-ps committed Dec 3, 2024
1 parent 99b7bfa commit 715e0fe
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 11 deletions.
44 changes: 44 additions & 0 deletions collectors/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,47 @@ func (d *descriptorCache) Store(prefix string, data []*monitoring.MetricDescript
defer d.lock.Unlock()
d.cache[prefix] = &entry
}

// collectorCache is a cache for MonitoringCollectors
type CollectorCache struct {
cache map[string]*collectorCacheEntry
lock sync.RWMutex
ttl time.Duration
}

// collectorCacheEntry is a cache entry for a MonitoringCollector
type collectorCacheEntry struct {
collector *MonitoringCollector
expiry time.Time
}

// NewCollectorCache returns a new CollectorCache with the given TTL
func NewCollectorCache(ttl time.Duration) *CollectorCache {
return &CollectorCache{
cache: make(map[string]*collectorCacheEntry),
ttl: ttl,
}
}

// Get returns a MonitoringCollector if the key is found and not expired
func (c *CollectorCache) Get(key string) (*MonitoringCollector, bool) {
c.lock.RLock()
defer c.lock.RUnlock()

entry, ok := c.cache[key]
if !ok || time.Now().After(entry.expiry) {
return nil, false
}
return entry.collector, true
}

func (c *CollectorCache) Store(key string, collector *MonitoringCollector) {
entry := &collectorCacheEntry{
collector: collector,
expiry: time.Now().Add(c.ttl),
}

c.lock.Lock()
defer c.lock.Unlock()
c.cache[key] = entry
}
33 changes: 22 additions & 11 deletions stackdriver_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"os"
"slices"
"strings"
"sync"
"time"

"github.com/PuerkitoBio/rehttp"
"github.com/alecthomas/kingpin/v2"
Expand Down Expand Up @@ -186,9 +186,7 @@ type handler struct {
metricsExtraFilters []collectors.MetricFilter
additionalGatherer prometheus.Gatherer
m *monitoring.Service

mu sync.RWMutex
collectors map[string]*collectors.MonitoringCollector
collectors *collectors.CollectorCache
}

func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Expand All @@ -207,27 +205,40 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

func newHandler(projectIDs []string, metricPrefixes []string, metricExtraFilters []collectors.MetricFilter, m *monitoring.Service, logger *slog.Logger, additionalGatherer prometheus.Gatherer) *handler {
ttl := 2 * time.Hour
// Add collector caching TTL as max of deltas aggregation or descriptor caching
if *monitoringMetricsAggregateDeltas || *monitoringDescriptorCacheTTL > 0 {
featureTTL := *monitoringMetricsDeltasTTL
if *monitoringDescriptorCacheTTL > featureTTL {
featureTTL = *monitoringDescriptorCacheTTL
}
if featureTTL > ttl {
ttl = featureTTL
}
}

logger.Info("Creating collector cache", "ttl", ttl)

h := &handler{
logger: logger,
projectIDs: projectIDs,
metricsPrefixes: metricPrefixes,
metricsExtraFilters: metricExtraFilters,
additionalGatherer: additionalGatherer,
m: m,
collectors: map[string]*collectors.MonitoringCollector{},
collectors: collectors.NewCollectorCache(ttl),
}

h.handler = h.innerHandler(nil)
return h
}

func (h *handler) getCollector(project string, filters map[string]bool) (*collectors.MonitoringCollector, error) {
h.mu.Lock()
defer h.mu.Unlock()
filterdPrefixes := h.filterMetricTypePrefixes(filters)
collectorKey := fmt.Sprintf("%s-%v", project, filterdPrefixes)

collectorKey := fmt.Sprintf("%s-%v", project, filters)
if c, ok := h.collectors[collectorKey]; ok {
return c, nil
if collector, found := h.collectors.Get(collectorKey); found {
return collector, nil
}

collector, err := collectors.NewMonitoringCollector(project, h.m, collectors.MonitoringCollectorOptions{
Expand All @@ -245,7 +256,7 @@ func (h *handler) getCollector(project string, filters map[string]bool) (*collec
if err != nil {
return nil, err
}
h.collectors[collectorKey] = collector
h.collectors.Store(collectorKey, collector)
return collector, nil
}

Expand Down

0 comments on commit 715e0fe

Please sign in to comment.