Skip to main content
Glama
healthcheck.ts2.21 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { MEDPLUM_VERSION } from '@medplum/core'; import type { Request, Response } from 'express'; import os from 'node:os'; import type { Pool } from 'pg'; import { DatabaseMode, getDatabasePool } from './database'; import type { RecordMetricOptions } from './otel/otel'; import { setGauge } from './otel/otel'; import { getRedis } from './redis'; const hostname = os.hostname(); const BASE_METRIC_OPTIONS = { attributes: { hostname } } satisfies RecordMetricOptions; const METRIC_IN_SECS_OPTIONS = { ...BASE_METRIC_OPTIONS, options: { unit: 's' } } satisfies RecordMetricOptions; export async function healthcheckHandler(_req: Request, res: Response): Promise<void> { const writerPool = getDatabasePool(DatabaseMode.WRITER); const readerPool = getDatabasePool(DatabaseMode.READER); let startTime = Date.now(); const postgresWriterOk = await testPostgres(writerPool); const writerRoundtripMs = Date.now() - startTime; setGauge('medplum.db.healthcheckRTT', writerRoundtripMs / 1000, { ...METRIC_IN_SECS_OPTIONS, attributes: { ...METRIC_IN_SECS_OPTIONS.attributes, dbInstanceType: 'writer' }, }); if (writerPool !== readerPool) { startTime = Date.now(); await testPostgres(readerPool); const readerRoundtripMs = Date.now() - startTime; setGauge('medplum.db.healthcheckRTT', readerRoundtripMs / 1000, { ...METRIC_IN_SECS_OPTIONS, attributes: { ...METRIC_IN_SECS_OPTIONS.attributes, dbInstanceType: 'reader' }, }); } startTime = Date.now(); const redisOk = await testRedis(); const redisRoundtripMs = Date.now() - startTime; setGauge('medplum.redis.healthcheckRTT', redisRoundtripMs / 1000, METRIC_IN_SECS_OPTIONS); res.json({ ok: true, version: MEDPLUM_VERSION, platform: process.platform, runtime: process.version, postgres: postgresWriterOk, redis: redisOk, }); } async function testPostgres(pool: Pool): Promise<boolean> { return (await pool.query(`SELECT 1 AS "status"`)).rows[0].status === 1; } async function testRedis(): Promise<boolean> { return (await getRedis().ping()) === 'PONG'; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server