From 4435e2829da76a1e3acb09278105879db0d8ee9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20B=C3=A4ume?= <julian.baeume@open-xchange.com> Date: Wed, 17 Aug 2022 11:37:00 +0200 Subject: [PATCH] add first dedicated metrics to analyse cache behaviour this should help to get insights about how the caches are filled locally --- src/files.js | 9 +++++++++ src/manifests.js | 2 +- src/version.js | 27 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/files.js b/src/files.js index 1836884..cc9703c 100644 --- a/src/files.js +++ b/src/files.js @@ -7,12 +7,19 @@ import { NotFoundError } from './errors.js' import * as redis from './redis.js' import zlib from 'node:zlib' import { promisify } from 'node:util' +import { Gauge } from 'prom-client' + const gzip = promisify(zlib.gzip) const compressFileSize = Number(process.env.COMPRESS_FILE_SIZE) const compressionMimeTypes = (process.env.COMPRESS_FILE_TYPES || '').replace(/([.+*?^$()[\]{}|])/g, '\\$1').split(' ') const compressionWhitelistRegex = new RegExp(`^(${compressionMimeTypes.join('|')})($|;)`, 'i') +export const fileCacheSizeGauge = new Gauge({ + name: 'file_cache_size', + help: 'Number of entries in file cache' +}) + export function createWritable (body) { if (typeof body !== 'string' && !(body instanceof Buffer)) return JSON.stringify(body) return body @@ -96,6 +103,7 @@ export function getFile ({ version, path }) { if (body) { logger.debug(`[Files] Resolve from redis: ${key}`) + fileCacheSizeGauge.inc() return (cache.getCache()[key] = { body, ...JSON.parse(meta) }) } } @@ -113,6 +121,7 @@ export function getFile ({ version, path }) { // overwrite cache with synchronous data logger.debug(`[Files] Store in memory: ${key}`) + fileCacheSizeGauge.inc() return (cache.getCache()[key] = dataFromServer) })() diff --git a/src/manifests.js b/src/manifests.js index 937b0bf..bf014cc 100644 --- a/src/manifests.js +++ b/src/manifests.js @@ -27,7 +27,7 @@ export async function fetchViteManifests () { return viteManifests.reduce((memo, manifest) => Object.assign(memo, manifest), {}) } -export function getViteManifests ({ version }) { +export async function getViteManifests ({ version }) { return cache.get(getRedisKey({ version, name: 'viteManifests' }), () => fetchViteManifests()) } diff --git a/src/version.js b/src/version.js index 387f259..990dfcb 100644 --- a/src/version.js +++ b/src/version.js @@ -3,9 +3,27 @@ import { getRedisKey, hash } from './util.js' import { logger } from './logger.js' import * as cache from './cache.js' import * as redis from './redis.js' +import { Gauge } from 'prom-client' +import { getViteManifests } from './manifests.js' let latestVersion +const manifestFileEntriesGauge = new Gauge({ + name: 'manifest_file_entries', + help: 'Number of entries in merged vite manifest (number of all known files)', + async collect () { + const version = latestVersion + this.set({ version }, Object.keys(await getViteManifests({ version })).length) + }, + labelNames: ['version'] +}) + +const versionUpdateGauge = new Gauge({ + name: 'version_update_event', + help: 'Timestamp of a version update event', + labelNames: ['version'] +}) + export const fetchLatestVersion = async () => { const infos = await Promise.all(configMap.urls.map(async baseUrl => { try { @@ -36,6 +54,7 @@ export async function getLatestVersion () { const version = await redis.client.get(getRedisKey({ name: 'latestVersion' })) if (version) { logger.info(`[Version] Got initial version from redis: '${version}'`) + versionUpdateGauge.setToCurrentTime({ version }) return (latestVersion = version) } } @@ -61,6 +80,7 @@ export function registerLatestVersionListener (client) { if (channel !== key) return logger.info(`[Version] Received 'updateLatestVersion' event. Clearing cache. New version: '${version}'`) await configMap.load() + versionUpdateGauge.setToCurrentTime({ version }) cache.clear() latestVersion = version }) @@ -73,6 +93,12 @@ export async function updateVersionProcessor () { getLatestVersion(), fetchLatestVersion() ]) + + // don't wait for the data, can be done in background + getViteManifests({ fetchedVersion }).then(manifests => { + manifestFileEntriesGauge.set({ version: fetchedVersion }, Object.keys(manifests).length) + }) + if (storedVersion === fetchedVersion) { logger.info(`[Version] No new version has been found. No update needed. Current version: ${storedVersion}`) return fetchedVersion @@ -91,6 +117,7 @@ export async function updateVersionProcessor () { await redis.client.set(getRedisKey({ name: 'prevProcessedVersion' }), fetchedVersion) } } else { + versionUpdateGauge.setToCurrentTime({ version: latestVersion }) // if redis is disabled, this will only be trigger by a setInterval and not from a redis event logger.info('[Version] Clear local cache due to version update.') cache.clear() -- GitLab