Skip to content

Commit fadeb9a

Browse files
feat(frontend): basic health check
1 parent 15effbb commit fadeb9a

File tree

6 files changed

+64
-4
lines changed

6 files changed

+64
-4
lines changed

frontend/app/.server/express/handlers.ts

-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export function rrRequestHandler(viteDevServer?: ViteDevServer) {
4646
return createRequestHandler({
4747
mode: serverEnvironment.NODE_ENV,
4848
getLoadContext: (request, response) => ({
49-
LogFactory: LogFactory,
5049
nonce: response.locals.nonce,
5150
session: request.session,
5251
}),

frontend/app/entry.server.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ import { getLanguage } from '~/utils/i18n-utils';
1717

1818
/* eslint-disable no-param-reassign */
1919

20+
const log = LogFactory.getLogger(import.meta.url);
21+
2022
export default async function handleRequest(
2123
request: Request,
2224
responseStatusCode: number,
2325
responseHeaders: Headers,
2426
routerContext: EntryContext,
2527
loadContext: AppLoadContext,
2628
) {
27-
const log = LogFactory.getLogger(import.meta.url);
28-
2929
const language = getLanguage(request);
3030
const i18n = await initI18next(language);
3131

@@ -86,7 +86,7 @@ export default async function handleRequest(
8686
}
8787

8888
// https://reactrouter.com/explanation/special-files#handleerror
89-
export function handleError(error: unknown, { context, request }: LoaderFunctionArgs | ActionFunctionArgs) {
89+
export function handleError(error: unknown, { context, params, request }: LoaderFunctionArgs | ActionFunctionArgs) {
9090
if (!request.signal.aborted) {
9191
const log = context.LogFactory.getLogger(import.meta.url);
9292
log.error('Uncaught error while handling request:', error);

frontend/app/routes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export default [
4242
route('/api/readyz', 'routes/api/readyz.ts'),
4343
route('/api/buildinfo', 'routes/api/buildinfo.ts'),
4444
route('/api/client-env', 'routes/api/client-env.ts'),
45+
route('/api/health', 'routes/api/health.ts'),
4546
route('/api/translations', 'routes/api/translations.ts'),
4647

4748
// auth routes

frontend/app/routes/api/health.ts

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import type { HealthCheckOptions } from '@dts-stn/health-checks';
2+
import { execute } from '@dts-stn/health-checks';
3+
4+
import type { Route } from './+types/health';
5+
6+
import { serverEnvironment } from '~/.server/environment';
7+
import { getRedisClient } from '~/.server/redis';
8+
9+
export async function loader({ context, params, request }: Route.LoaderArgs) {
10+
const { include, exclude, timeout } = Object.fromEntries(new URL(request.url).searchParams);
11+
12+
const redisHealthCheck = { name: 'redis', check: () => void getRedisClient().ping() };
13+
14+
const healthCheckOptions: HealthCheckOptions = {
15+
excludeComponents: toArray(exclude),
16+
includeComponents: toArray(include),
17+
includeDetails: isAuthorized(request),
18+
metadata: {
19+
buildId: serverEnvironment.BUILD_ID,
20+
version: serverEnvironment.BUILD_VERSION,
21+
},
22+
timeoutMs: toNumber(timeout),
23+
};
24+
25+
const useRedis = serverEnvironment.SESSION_TYPE === 'redis';
26+
27+
if (!useRedis) {
28+
healthCheckOptions.excludeComponents ??= [];
29+
healthCheckOptions.excludeComponents.push(redisHealthCheck.name);
30+
}
31+
32+
const summary = await execute([redisHealthCheck], healthCheckOptions);
33+
34+
return Response.json({ summary });
35+
}
36+
37+
function isAuthorized(request: Request): boolean {
38+
return false; // TODO
39+
}
40+
41+
function toArray(str?: string): string[] | undefined {
42+
const result = str?.split(',').filter(Boolean);
43+
return result && result.length > 0 ? result : undefined;
44+
}
45+
46+
function toNumber(str?: string): number | undefined {
47+
const num = parseInt(str ?? '');
48+
return isNaN(num) ? undefined : num;
49+
}

frontend/package-lock.json

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"typecheck": "react-router typegen && tsc"
1919
},
2020
"dependencies": {
21+
"@dts-stn/health-checks": "^2.0.0",
2122
"@opentelemetry/api": "^1.9.0",
2223
"@opentelemetry/auto-instrumentations-node": "^0.55.0",
2324
"@opentelemetry/exporter-metrics-otlp-proto": "^0.57.0",

0 commit comments

Comments
 (0)