Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions backend/src/monitoring/health.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Injectable, Optional } from '@nestjs/common';
import { Inject, Injectable, Optional } from '@nestjs/common';
import type { Redis } from 'ioredis';
import { DatabaseService } from '../common/database/database.service';
import { REDIS_CLIENT } from '../common/redis/redis.module';

export interface HealthStatus {
status: 'ok' | 'degraded' | 'down';
Expand All @@ -11,13 +13,17 @@ export interface HealthStatus {
export class HealthService {
private readonly startTime = Date.now();

constructor(@Optional() private readonly database?: DatabaseService) {}
constructor(
@Optional() private readonly database?: DatabaseService,
@Optional() @Inject(REDIS_CLIENT) private readonly redis?: Redis | null,
) {}

async check(): Promise<HealthStatus> {
const checks: Record<string, boolean> = {
api: true,
stellar: await this.checkStellar(),
database: await this.checkDatabase(),
redis: await this.checkRedis(),
memory: process.memoryUsage().heapUsed < 500 * 1024 * 1024,
};
const failing = Object.values(checks).filter(v => !v).length;
Expand All @@ -28,6 +34,22 @@ export class HealthService {
};
}

/**
* Redis is required infrastructure for rate limiting, idempotency keys, and
* the outbox — closes #219. An unconfigured REDIS_URL still reports healthy
* (this environment doesn't require Redis), but once configured a failed
* ping counts against overall health instead of being silently invisible.
*/
private async checkRedis(): Promise<boolean> {
if (!this.redis) return true;
try {
const pong = await this.redis.ping();
return pong === 'PONG';
} catch {
return false;
}
}

/**
* PostgreSQL is currently optional infrastructure — not yet a hard dependency of any
* service — so an unconfigured pool reports healthy (true) rather than degraded. Once
Expand Down