Healthchecks
Healthchecks
Healthchecks are a proven way to verify that your application is working correctly,
usually they consist if simple operations to verify that each part of your program is working,
such as a database query to check if connectivity works.
In Basica, they can be easily added in all your services by implementing IHealthcheck.
Any registered service or entrypoint implementing IHealthcheck will also be registered as an healthcheck.
Implementing IHealthcheck
- Classes
- Object Factory
import { IHealthcheck } from "@basica/core";
export class MyService implements IHealthcheck {
async healthcheck(signal: AbortSignal) {
// query the db
}
}
import { IHealthcheckManager, IEntrypoint } from "@basica/core";
export class MyEntrypoint implements IEntrypoint {
constructor(private readonly healthcheckManager: IHealthcheckManager) {}
async start(signal: AbortSignal) {
const results = await this.healthcheckManager.healthcheck();
if (Object.values(results).some((r) => r.status != "healthy")) {
throw new Error("some healthchecks are unhealthy");
}
}
async stop(signal: AbortSignal) {
// ...
}
}
import { IHealthcheck } from "@basica/core";
export const createMyService = () => ({
healthcheck: async (signal: AbortSignal) => {
// query the db
}
}) satisfies IHealthcheck;
import { IHealthcheckManager, IEntrypoint } from "@basica/core";
export const createMyEntrypoint = (healthcheckManager: IHealthcheckManager) => ({
start: async (signal: AbortSignal) => {
const results = await healthcheckManager.healthcheck();
if (Object.values(results).some((r) => r.status != "healthy")) {
throw new Error("some healthchecks are unhealthy");
}
},
stop: async (signal: AbortSignal) => {
// ...
}
}) satisfies IEntrypoint;
// ...
const app = new AppBuilder(container)
.configureLifecycle((b) =>
b.addHealthcheck("my-service", () => container.myService)
.addEntrypoint("test", (deps, healthchecks) => createMyEntrypoint(healthchecks))
)
.build();
app.run()
The healthcheck manager
IHealthcheckManager runs every registered healthcheck and returns their results keyed by name.
Entrypoints receive it as the second argument of their factory, so they can expose health over
their transport:
b.addEntrypoint("test", (deps, healthchecks) => createMyEntrypoint(healthchecks))
If you need it outside an entrypoint, the builder exposes it directly:
await b.healthcheckManager.healthcheck(); // runs every registered healthcheck
The registered checks themselves are available as items on app.healthchecks (and
builder.healthchecks), the same way registered services and entrypoints are on app.services and
app.entrypoints.