diff --git a/spec/server_test.js b/spec/server_test.js index 53d5216dee60f42925978e88ceed304d4bb893b1..6079386f4688b894276ba6576d92c3bf3eeb8407 100644 --- a/spec/server_test.js +++ b/spec/server_test.js @@ -36,6 +36,9 @@ describe('Manifest service', () => { process.env.CACHE_TTL = 30000 }) + // Some say, this is not necessary to test + // But failing startups due to code errors in the probes will cause this to not work + // Therefore, we should keep this it('is healthy', async () => { const response = await request(app).get('/healthy') expect(response.statusCode).toBe(200) diff --git a/src/createApp.js b/src/createApp.js index ded121f1d227ec305d63afae423402c8653cb2cf..5e4ecc474141b3ba29ca29e045ad84a55ddf88ab 100644 --- a/src/createApp.js +++ b/src/createApp.js @@ -13,6 +13,7 @@ import health from '@cloudnative/health-connect' // Prometheus middleware for standard api metrics import promBundle from 'express-prom-bundle' +import promClient from 'prom-client' // Swagger UI for api-docs import swaggerUi from 'swagger-ui-express' @@ -26,6 +27,11 @@ const swaggerDocument = yaml.load(fs.readFileSync('./src/swagger.yaml', 'utf8')) const bypass = (request) => ignorePaths.includes(request.path) const metricsMiddleware = promBundle({ bypass, includePath: true }) +const startUpTimeGauge = new promClient.Gauge({ + name: 'manifest_service_startup_time', + help: 'Time to warm up cache' +}) + export function createApp () { // The app returned by express() is in fact a JavaScript Function, designed to be passed to Node’s HTTP servers as a callback to handle requests. @@ -36,6 +42,7 @@ export function createApp () { const healthCheck = new health.HealthChecker() const startupCheck = new health.StartupCheck('warmup cache', async function () { + const stopTimer = startUpTimeGauge.startTimer() try { const viteManifests = await loadViteManifests() const deps = viteManifestToDeps(viteManifests) @@ -43,6 +50,8 @@ export function createApp () { } catch (e) { logger.error(`Failed to get dependencies: ${e.message}`) throw e + } finally { + stopTimer() } }) healthCheck.registerStartupCheck(startupCheck) diff --git a/src/files.js b/src/files.js index 67e15471c879469bc02e4118bbab6b37f250b36c..84485fe94e26fe233a02b1596df5ebc64b531e11 100644 --- a/src/files.js +++ b/src/files.js @@ -1,6 +1,8 @@ import fetch from 'node-fetch' import crypto from 'crypto' import { config } from './config.js' +import promClient from 'prom-client' +import { getLogger } from './logger.js' async function fetchData (path, baseUrl) { const response = await fetch(new URL(path, baseUrl)) @@ -13,6 +15,15 @@ async function fetchData (path, baseUrl) { content }] } + +const fileCounter = new promClient.Counter({ + name: 'manifest_service_file_cache_fetches', + help: 'Number of fetched files' +}) +const fileErrorCounter = new promClient.Counter({ + name: 'manifest_service_file_cache_fetch_errors', + help: 'Number of errors while fetching files' +}) class FileCache { constructor () { this._cache = {} @@ -32,13 +43,17 @@ class FileCache { (m?.css?.indexOf(file) >= 0) ) if (!manifest) { - console.error('could not find manifest for', file) + getLogger().error('could not find manifest for', file) return null } return await fetchData(file, manifest.meta.baseUrl) - } catch (e) { console.error(e) } + } catch (e) { + fileErrorCounter.inc() + getLogger().error(e) + } }))).filter(data => Array.isArray(data) && data.length === 2)) } + fileCounter.inc(result.length) return result }())) this._cache = cache