Healthcheck #51
50
src/routes/health/+server.ts
Normal file
50
src/routes/health/+server.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { storagePath } from '$lib';
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { stat, access, constants } from 'fs/promises';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
type Status = 'OK' | 'ERROR';
|
||||
type Result = { status: Status; checks: Checks };
|
||||
|
||||
type Checks = { [key: string]: CheckResult };
|
||||
type CheckResult = true | string;
|
||||
|
||||
const fileExists = async (path: string) => !!(await stat(path).catch(() => false));
|
||||
const isDirectory = async (path: string) =>
|
||||
!!(await stat(path)
|
||||
.then((s) => s.isDirectory())
|
||||
.catch(() => false));
|
||||
const isWritable = async (path: string) =>
|
||||
await access(path, constants.W_OK)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
const checkStoragePath = async (path: string): Promise<CheckResult> => {
|
||||
if (!fileExists(path)) {
|
||||
return '`STORAGE_PATH` does not exist';
|
||||
} else if (!isDirectory(path)) {
|
||||
return '`STORAGE_PATH` is not a directory';
|
||||
} else if (!isWritable(path)) {
|
||||
return '`STORAGE_PATH` is not writable';
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
export const GET: RequestHandler = async () => {
|
||||
const storagePathResult = await checkStoragePath(storagePath);
|
||||
|
||||
const checks: Checks = {
|
||||
storagePath: storagePathResult,
|
||||
};
|
||||
|
||||
const healthy = Object.values(checks)
|
||||
.map((r) => (r === true ? true : false))
|
||||
.reduce((prev, next) => prev && next, true);
|
||||
|
||||
const status = healthy ? 'OK' : 'ERROR';
|
||||
|
||||
const result: Result = { status, checks };
|
||||
const httpStatus = healthy ? 200 : 500;
|
||||
|
||||
return json(result, { status: httpStatus, headers: { healthy: healthy.toString() } });
|
||||
};
|
Reference in New Issue
Block a user