Skip to content

Commit

Permalink
feat(frontend): basic health check
Browse files Browse the repository at this point in the history
  • Loading branch information
gregory-j-baker committed Dec 23, 2024
1 parent 15effbb commit b76a084
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 4 deletions.
1 change: 0 additions & 1 deletion frontend/app/.server/express/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export function rrRequestHandler(viteDevServer?: ViteDevServer) {
return createRequestHandler({
mode: serverEnvironment.NODE_ENV,
getLoadContext: (request, response) => ({
LogFactory: LogFactory,
nonce: response.locals.nonce,
session: request.session,
}),
Expand Down
6 changes: 3 additions & 3 deletions frontend/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ import { getLanguage } from '~/utils/i18n-utils';

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

const log = LogFactory.getLogger(import.meta.url);

export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
routerContext: EntryContext,
loadContext: AppLoadContext,
) {
const log = LogFactory.getLogger(import.meta.url);

const language = getLanguage(request);
const i18n = await initI18next(language);

Expand Down Expand Up @@ -86,7 +86,7 @@ export default async function handleRequest(
}

// https://reactrouter.com/explanation/special-files#handleerror
export function handleError(error: unknown, { context, request }: LoaderFunctionArgs | ActionFunctionArgs) {
export function handleError(error: unknown, { context, params, request }: LoaderFunctionArgs | ActionFunctionArgs) {
if (!request.signal.aborted) {
const log = context.LogFactory.getLogger(import.meta.url);
log.error('Uncaught error while handling request:', error);
Expand Down
1 change: 1 addition & 0 deletions frontend/app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default [
route('/api/readyz', 'routes/api/readyz.ts'),
route('/api/buildinfo', 'routes/api/buildinfo.ts'),
route('/api/client-env', 'routes/api/client-env.ts'),
route('/api/health', 'routes/api/health.ts'),
route('/api/translations', 'routes/api/translations.ts'),

// auth routes
Expand Down
47 changes: 47 additions & 0 deletions frontend/app/routes/api/health.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { HealthCheckOptions } from '@dts-stn/health-checks';
import { execute } from '@dts-stn/health-checks';

import type { Route } from './+types/health';

import { serverEnvironment } from '~/.server/environment';
import { getRedisClient } from '~/.server/redis';

export async function loader({ context, params, request }: Route.LoaderArgs) {
const { include, exclude, timeout } = Object.fromEntries(new URL(request.url).searchParams);

const redisHealthCheck = { name: 'redis', check: () => void getRedisClient().ping() };

const healthCheckOptions: HealthCheckOptions = {
excludeComponents: toArray(exclude),
includeComponents: toArray(include),
includeDetails: isAuthorized(request),
metadata: {
buildId: serverEnvironment.BUILD_ID,
version: serverEnvironment.BUILD_VERSION,
},
timeoutMs: toNumber(timeout),
};

if (serverEnvironment.SESSION_TYPE !== 'redis') {
healthCheckOptions.excludeComponents ??= [];
healthCheckOptions.excludeComponents.push(redisHealthCheck.name);
}

const summary = await execute([redisHealthCheck], healthCheckOptions);

return Response.json({ summary });
}

function isAuthorized(request: Request): boolean {
return false; // TODO
}

function toArray(str?: string): string[] | undefined {
const result = str?.split(',').filter(Boolean);
return result && result.length > 0 ? result : undefined;
}

function toNumber(str?: string): number | undefined {
const num = parseInt(str ?? '');
return isNaN(num) ? undefined : num;
}
10 changes: 10 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"typecheck": "react-router typegen && tsc"
},
"dependencies": {
"@dts-stn/health-checks": "^2.0.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-node": "^0.55.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.57.0",
Expand Down

0 comments on commit b76a084

Please sign in to comment.