diff --git a/packages/keystone/fetch.js b/packages/keystone/fetch.js new file mode 100644 index 00000000000..f0aea9726f9 --- /dev/null +++ b/packages/keystone/fetch.js @@ -0,0 +1,45 @@ +const nodeFetch = require('node-fetch') + +const { getExecutionContext } = require('./executionContext') +const { getLogger } = require('./logging') +const Mertrics = require('./metrics') + +const logger = getLogger('fetch') + +async function fetch (url, options) { + + const urlObject = new URL(url) + const host = urlObject.hostname + const path = urlObject.pathname + const metricUrl = host.replace(/[^a-zA-Z0-9]/g, '') + + const executionContext = getExecutionContext() + const parentReqId = executionContext.reqId + + const startTime = Date.now() + + try { + const response = await nodeFetch(url, options) + + const endTime = Date.now() + const elapsedTime = endTime - startTime + + logger.info({ msg: 'fetch: request successful', url, reqId: parentReqId, path, host, status: response.status, elapsedTime }) + Mertrics.increment({ name: 'fetch.status.' + metricUrl, value: response.status, tags: { path } }) + Mertrics.gauge({ name: 'fetch.time.' + metricUrl, value: elapsedTime, tags: { path } }) + + return response + } catch (error) { + const endTime = Date.now() + const elapsedTime = endTime - startTime + + logger.error({ msg: 'fetch: failed with error', url, path, host, reqId: parentReqId, error, elapsedTime }) + + Mertrics.increment({ name: 'fetch.error.' + metricUrl, value: 1, tags: { path } }) + throw error + } +} + +module.exports = { + fetch, +} \ No newline at end of file diff --git a/packages/keystone/metrics.js b/packages/keystone/metrics.js index 362ba7b1b0f..4bc61bc2702 100644 --- a/packages/keystone/metrics.js +++ b/packages/keystone/metrics.js @@ -51,23 +51,29 @@ const StatsDClient = new StatsD({ globalTags: { hostname: HOSTNAME, command: process.argv[1] }, }) -const gauge = ({ name, value }) => { +const gauge = ({ name, value, tags }) => { validateName(name) - StatsDClient.gauge(name, value) + StatsDClient.gauge(name, value, tags) } -const histogram = ({ name, value }) => { +const histogram = ({ name, value, tags }) => { validateName(name) - StatsDClient.histogram(name, value) + StatsDClient.histogram(name, value, tags) } -const count = ({ name, value }) => { +const increment = ({ name, value, tags }) => { validateName(name) - StatsDClient.count(name, value) + StatsDClient.increment(name, value, tags) +} + +const decrement = ({ name, value, tags }) => { + validateName(name) + StatsDClient.decrement(name, value, tags) } module.exports = { gauge, - count, + increment, + decrement, histogram, } \ No newline at end of file