From aa38e6af4fd637708371c22a123681bb1a008488 Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Sun, 26 May 2019 09:33:09 +0200 Subject: [PATCH] feat: host stats (#3812) Collects latency stats for hosts and dumps them at the end of each run. --- lib/util/got/cache-get.js | 4 ++++ lib/util/got/index.js | 9 ++++++++- lib/util/got/stats.js | 40 +++++++++++++++++++++++++++++++++++++ lib/workers/global/index.js | 2 ++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 lib/util/got/stats.js diff --git a/lib/util/got/cache-get.js b/lib/util/got/cache-get.js index b5e3855263..f830ab02e7 100644 --- a/lib/util/got/cache-get.js +++ b/lib/util/got/cache-get.js @@ -9,6 +9,10 @@ const clone = input => JSON.parse(JSON.stringify(input)); module.exports = got.create({ options: {}, handler: (options, next) => { + // istanbul ignore if + if (!global.repoCache) { + return next(options); + } if (options.method === 'GET') { const cacheKey = crypto .createHash('md5') diff --git a/lib/util/got/index.js b/lib/util/got/index.js index 4c45f911d2..92e03756d0 100644 --- a/lib/util/got/index.js +++ b/lib/util/got/index.js @@ -3,6 +3,7 @@ const cacheGet = require('./cache-get'); const renovateAgent = require('./renovate-agent'); const hostRules = require('./host-rules'); const auth = require('./auth'); +const stats = require('./stats'); /* * This is the default got instance for Renovate. @@ -12,4 +13,10 @@ const auth = require('./auth'); * Important: always put the renovateAgent one last, to make sure the correct user agent is used */ -module.exports = got.mergeInstances(cacheGet, renovateAgent, hostRules, auth); +module.exports = got.mergeInstances( + cacheGet, + renovateAgent, + hostRules, + auth, + stats.instance +); diff --git a/lib/util/got/stats.js b/lib/util/got/stats.js new file mode 100644 index 0000000000..c64b73b7cd --- /dev/null +++ b/lib/util/got/stats.js @@ -0,0 +1,40 @@ +const got = require('got'); + +let stats = {}; + +// istanbul ignore next +module.exports.resetStats = () => { + stats = {}; +}; + +// istanbul ignore next +module.exports.printStats = () => { + logger.trace({ stats }, 'Host transfer stats (milliseconds)'); + const hostStats = {}; + for (const [hostname, entries] of Object.entries(stats)) { + const res = {}; + res.requests = entries.length; + res.sum = 0; + entries.forEach(entry => { + res.sum += entry; + }); + res.average = Math.round(res.sum / res.requests); + res.median = entries[Math.floor(entries.length / 2)]; + hostStats[hostname] = res; + } + logger.debug({ hostStats }, 'Host request stats (milliseconds)'); +}; + +module.exports.instance = got.create({ + options: {}, + handler: (options, next) => { + const start = new Date(); + const nextPromise = next(options); + nextPromise.on('response', () => { + const elapsed = new Date() - start; + stats[options.hostname] = stats[options.hostname] || []; + stats[options.hostname].push(elapsed); + }); + return nextPromise; + }, +}); diff --git a/lib/workers/global/index.js b/lib/workers/global/index.js index 19595b85d1..b691550d93 100644 --- a/lib/workers/global/index.js +++ b/lib/workers/global/index.js @@ -10,6 +10,7 @@ const { appName } = require('../../config/app-strings'); const { autodiscoverRepositories } = require('./autodiscover'); const { initPlatform } = require('../../platform'); const hostRules = require('../../util/host-rules'); +const { printStats } = require('../../util/got/stats'); module.exports = { start, @@ -68,6 +69,7 @@ async function start() { await repositoryWorker.renovateRepository(repoConfig); } logger.setMeta({}); + printStats(); logger.info(`${appName} finished`); } catch (err) /* istanbul ignore next */ { if (err.message.startsWith('Init: ')) { -- GitLab