diff --git a/CHANGELOG.md b/CHANGELOG.md index 00622f2f603cb2bedf73b9443c733b3ee101fb30..eb56601ad2b51ce64f1c58fcc7a121d781de080f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Pass-through the `Accept-Language` header for URL previews, with options to set a default. * Experimental support for IPFS. * Consistent inclusion of a charset for certain text `Content-Type`s. +* New metrics for the cache composition reality (`media_cache_num_live_bytes_used` and `media_cache_num_live_items`). ### Fixed diff --git a/internal_cache/media_cache.go b/internal_cache/media_cache.go index 83cea4a6219b0be677899dc567733cbcc06ba356..ab3db53b8d730649432d7a82473bd34a51dbc62d 100644 --- a/internal_cache/media_cache.go +++ b/internal_cache/media_cache.go @@ -70,6 +70,11 @@ func Get() *MediaCache { logrus.Infof("Record %s has been evicted from the cache", recordId) }) + metrics.OnBeforeMetricsRequested(func() { + metrics.CacheLiveNumBytes.With(prometheus.Labels{"cache": "media"}).Set(float64(instance.getUnderlyingUsedBytes())) + metrics.CacheNumLiveItems.With(prometheus.Labels{"cache": "media"}).Set(float64(instance.getUnderlyingItemCount())) + }) + go func() { rctx := rcontext.Initial().LogWithFields(logrus.Fields{"task": "cache_cleanup"}) for _ = range instance.cleanupTimer.C { @@ -102,6 +107,19 @@ func (c *MediaCache) Stop() { c.cleanupTimer.Stop() } +func (c *MediaCache) getUnderlyingUsedBytes() int64 { + var size int64 = 0 + for _, entry := range c.cache.Items() { + f := entry.Object.(*cachedFile) + size += int64(f.Contents.Len()) + } + return size +} + +func (c *MediaCache) getUnderlyingItemCount() int { + return c.cache.ItemCount() +} + func (c *MediaCache) IncrementDownloads(fileHash string) { if !c.enabled { return diff --git a/metrics/listeners.go b/metrics/listeners.go new file mode 100644 index 0000000000000000000000000000000000000000..e757165b69ea1bbcb8029404181ccb47d13c5eda --- /dev/null +++ b/metrics/listeners.go @@ -0,0 +1,7 @@ +package metrics + +var beforeMetricsCalledFns = make([]func(), 0) + +func OnBeforeMetricsRequested(fn func()) { + beforeMetricsCalledFns = append(beforeMetricsCalledFns, fn) +} diff --git a/metrics/metrics.go b/metrics/metrics.go index 8260b4abf6e353b4015549b30babf3586fa8f99f..47a1336fe74d6c21fa45f1b4481a0bbb0ffb5e44 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -25,9 +25,15 @@ var CacheEvictions = prometheus.NewCounterVec(prometheus.CounterOpts{ var CacheNumItems = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: "media_cache_num_items", }, []string{"cache"}) +var CacheNumLiveItems = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "media_cache_num_live_items", +}, []string{"cache"}) var CacheNumBytes = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: "media_cache_num_bytes_used", }, []string{"cache"}) +var CacheLiveNumBytes = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "media_cache_num_live_bytes_used", +}, []string{"cache"}) var ThumbnailsGenerated = prometheus.NewCounterVec(prometheus.CounterOpts{ Name: "media_thumbnails_generated_total", }, []string{"width", "height", "method", "animated", "origin"}) @@ -46,7 +52,9 @@ func init() { prometheus.MustRegister(CacheMisses) prometheus.MustRegister(CacheEvictions) prometheus.MustRegister(CacheNumItems) + prometheus.MustRegister(CacheNumLiveItems) prometheus.MustRegister(CacheNumBytes) + prometheus.MustRegister(CacheLiveNumBytes) prometheus.MustRegister(ThumbnailsGenerated) prometheus.MustRegister(MediaDownloaded) prometheus.MustRegister(UrlPreviewsGenerated) diff --git a/metrics/webserver.go b/metrics/webserver.go index 0585eced699ff867a6ecf61bc07bea04b7e5e3a5..14339591943cdef65f522d838ae9c4c057ffed96 100644 --- a/metrics/webserver.go +++ b/metrics/webserver.go @@ -13,14 +13,22 @@ import ( var srv *http.Server +func internalHandler(res http.ResponseWriter, req *http.Request) { + logrus.Info("Updating live metrics for cache") + for _, fn := range beforeMetricsCalledFns { + fn() + } + promhttp.Handler().ServeHTTP(res, req) +} + func Init() { if !config.Get().Metrics.Enabled { logrus.Info("Metrics disabled") return } rtr := http.NewServeMux() - rtr.Handle("/metrics", promhttp.Handler()) - rtr.Handle("/_media/metrics", promhttp.Handler()) + rtr.HandleFunc("/metrics", internalHandler) + rtr.HandleFunc("/_media/metrics", internalHandler) address := config.Get().Metrics.BindAddress + ":" + strconv.Itoa(config.Get().Metrics.Port) srv = &http.Server{Addr: address, Handler: rtr}