@lokalise/fastify-extras
Version:
Opinionated set of fastify plugins, commonly used in Lokalise
73 lines • 2.49 kB
JavaScript
import fp from 'fastify-plugin';
const VALID_PROMETHEUS_NAME_REGEX = /[a-zA-Z_:][a-zA-Z0-9_:]*/;
/**
* Execute healthcheck and calculate the check time
*/
export const wrapHealthCheckForPrometheus = (healthCheck, healthcheckName) => {
return {
name: healthcheckName,
checker: async (app) => {
const startTime = Date.now();
const response = await healthCheck(app);
const checkTimeInMsecs = Date.now() - startTime;
return {
checkPassed: !!response.result,
checkTimeInMsecs,
};
},
};
};
function plugin(app, opts, done) {
const invalidNames = [];
for (const healthcheck of opts.healthChecks) {
if (!VALID_PROMETHEUS_NAME_REGEX.test(healthcheck.name)) {
invalidNames.push(healthcheck.name);
}
}
if (invalidNames.length > 0) {
return done(new Error(`Invalid healthcheck names: ${JSON.stringify(invalidNames)}`));
}
try {
const promClient = app.metrics.client;
if (!promClient) {
throw new Error('Prometheus client is not registered');
}
for (const check of opts.healthChecks) {
new promClient.Gauge({
name: `${check.name}_availability`,
help: `Whether ${check.name} was available at the time`,
async collect() {
const checkResult = await check.checker(app);
if (checkResult.checkPassed) {
this.set(1);
}
else {
this.set(0);
}
},
});
new promClient.Gauge({
name: `${check.name}_latency_msecs`,
help: `How long the healthcheck for ${check.name} took`,
async collect() {
const checkResult = await check.checker(app);
if (checkResult.checkPassed) {
this.set(checkResult.checkTimeInMsecs);
}
else {
this.set(checkResult.checkTimeInMsecs ?? 0);
}
},
});
}
}
catch (err) {
return done(err);
}
done();
}
export const healthcheckMetricsPlugin = fp(plugin, {
fastify: '5.x',
name: 'healthcheck-metrics-plugin',
});
//# sourceMappingURL=healthcheckMetricsPlugin.js.map