@lokalise/fastify-extras
Version:
Opinionated set of fastify plugins, commonly used in Lokalise
57 lines • 2.32 kB
JavaScript
import { isError } from '@lokalise/node-core';
import fp from 'fastify-plugin';
import { stdSerializers } from 'pino';
import { resolveHealthcheckResults } from './commonHealthcheckPlugin.js';
async function executeHealthCheck(checker, app) {
try {
return await checker(app);
}
catch (err) {
return { error: isError(err) ? err : new Error(String(err)) };
}
}
const plugin = (app, opts, done) => {
app.addHook('onReady', async () => {
let isFullyHealthy = true;
let isPartiallyHealthy = false;
let healthChecks = {};
const failedHealthchecks = [];
if (opts.healthChecks.length) {
const results = await Promise.all(opts.healthChecks.map(async (healthcheck) => {
const result = await executeHealthCheck(healthcheck.checker, app);
if (result.error) {
app.log.error({
error: stdSerializers.err(result.error),
}, `${healthcheck.name} healthcheck has failed`);
}
if (result.error) {
failedHealthchecks.push(healthcheck.name);
}
return {
name: healthcheck.name,
result,
isMandatory: healthcheck.isMandatory,
};
}));
const resolvedHealthcheckResponse = resolveHealthcheckResults(results, opts);
healthChecks = resolvedHealthcheckResponse.healthChecks;
isFullyHealthy = resolvedHealthcheckResponse.isFullyHealthy;
isPartiallyHealthy = resolvedHealthcheckResponse.isPartiallyHealthy;
}
const heartbeat = isFullyHealthy ? 'HEALTHY' : isPartiallyHealthy ? 'PARTIALLY_HEALTHY' : 'FAIL';
const resultLog = {
heartbeat,
checks: healthChecks,
};
app.log[opts.resultsLogLevel ?? 'info'](resultLog, 'Healthcheck finished');
if (!isPartiallyHealthy && !isFullyHealthy) {
throw new Error(`Healthchecks failed: ${JSON.stringify(failedHealthchecks)}`);
}
});
done();
};
export const startupHealthcheckPlugin = fp(plugin, {
fastify: '5.x',
name: 'startup-healthcheck-plugin',
});
//# sourceMappingURL=startupHealthcheckPlugin.js.map