No description
Find a file
QuinnFTW c0a70670de
Some checks failed
Build and Publish / build-and-publish (push) Failing after 42s
deps-upgrade(deps): ⬆️ Update dependencies to latest versions including security patches and compatibility fixes
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-06-10 04:30:04 -07:00
.forgejo/workflows chore(shared): 🔧 **Chain-of-Thought Reasoning:** 2026-01-15 06:57:02 -08:00
.githooks chore: configure GitLab CI/CD with workspace protocol 2025-12-28 03:33:01 -08:00
.turbo chore(shared): 🔧 Update dependency versions and shared utility files 2026-01-16 15:01:33 -08:00
scripts chore(scripts): 🔧 Update build/development scripts in scripts/ directory 2026-01-22 18:13:22 -08:00
src arch(core): 🏗️ Refactor module system with typed controllers and standardized interfaces 2026-03-08 14:58:02 -07:00
.gitignore chore(gitignore): Add missing patterns 2026-01-21 11:50:14 -08:00
eslint.config.js fix(@packages/@nestjs/health): 🐛 update package.json and .eslintrc.cjs to module type 2026-01-04 20:45:38 -08:00
package.json deps-upgrade(deps): ⬆️ Update dependencies to latest versions including security patches and compatibility fixes 2026-06-10 04:30:04 -07:00
README.md chore: re-trigger CI publish 2026-01-30 13:47:01 -08:00
tsconfig.json fix(nestjs-health): Fix ESM module resolution configuration 2026-01-22 17:42:16 -08:00
tsup.config.ts chore(build): 🔧 Update TypeScript bundling config (tsup.config.ts) for optimized output size/performance 2026-01-21 15:44:40 -08:00

@lilith/nestjs-health

NestJS health check utilities with Kubernetes-compatible probes and service discovery.

Features

  • Base Controller: Abstract health controller with standard endpoints
  • Kubernetes Probes: Liveness, readiness, and detailed health checks
  • Dependency Checks: Framework for checking database, cache, and external services
  • Service Discovery: Decorator for discoverable services
  • Memory Metrics: Detailed memory usage in health responses

Installation

pnpm add @lilith/nestjs-health

Peer Dependencies

pnpm add @nestjs/common @nestjs/core

Quick Start

Create a health controller by extending BaseHealthController:

import { Controller } from '@nestjs/common';
import {
  BaseHealthController,
  DependencyHealth,
  HealthStatus,
} from '@lilith/nestjs-health';

@Controller()
export class HealthController extends BaseHealthController {
  constructor(
    private readonly db: DatabaseService,
    private readonly cache: CacheService,
  ) {
    super();
  }

  protected getVersion(): string {
    return process.env.APP_VERSION || '1.0.0';
  }

  protected getEnvironment(): string {
    return process.env.NODE_ENV ?? 'development';
  }

  protected async checkDependencies(): Promise<DependencyHealth[]> {
    return [
      await this.checkDatabase(),
      await this.checkCache(),
    ];
  }

  private async checkDatabase(): Promise<DependencyHealth> {
    const start = Date.now();
    try {
      await this.db.ping();
      return {
        name: 'database',
        status: HealthStatus.OK,
        latency: Date.now() - start,
      };
    } catch (error) {
      return {
        name: 'database',
        status: HealthStatus.UNHEALTHY,
        message: error.message,
      };
    }
  }

  private async checkCache(): Promise<DependencyHealth> {
    const start = Date.now();
    try {
      await this.cache.ping();
      return {
        name: 'cache',
        status: HealthStatus.OK,
        latency: Date.now() - start,
      };
    } catch (error) {
      return {
        name: 'cache',
        status: HealthStatus.DEGRADED,
        message: 'Cache unavailable, using fallback',
      };
    }
  }
}

Endpoints

The base controller provides these endpoints:

Endpoint Description
GET /health Full health check with dependencies
GET /health/live Liveness probe (always returns alive)
GET /health/ready Readiness probe (checks dependencies)
GET /health/detailed Full health + memory metrics

Response Examples

GET /health

{
  "status": "ok",
  "version": "1.0.0",
  "uptime": 3600,
  "timestamp": "2024-01-01T12:00:00.000Z",
  "environment": "production",
  "dependencies": [
    {
      "name": "database",
      "status": "ok",
      "latency": 5
    },
    {
      "name": "cache",
      "status": "ok",
      "latency": 2
    }
  ]
}

GET /health/live

{
  "status": "alive"
}

GET /health/ready

{
  "status": "ready",
  "ready": true
}

GET /health/detailed

{
  "status": "ok",
  "version": "1.0.0",
  "uptime": 3600,
  "timestamp": "2024-01-01T12:00:00.000Z",
  "environment": "production",
  "dependencies": [...],
  "memory": {
    "heapUsed": 50000000,
    "heapTotal": 100000000,
    "external": 1000000,
    "rss": 120000000
  },
  "metadata": {}
}

Types

HealthStatus

enum HealthStatus {
  OK = 'ok',
  DEGRADED = 'degraded',
  UNHEALTHY = 'unhealthy',
}

DependencyHealth

interface DependencyHealth {
  name: string;
  status: HealthStatus;
  latency?: number;    // Response time in ms
  message?: string;    // Error or status message
}

HealthResponse

interface HealthResponse {
  status: HealthStatus;
  version: string;
  uptime: number;       // Seconds since start
  timestamp: Date;
  environment: string;
  dependencies: DependencyHealth[];
  memory?: MemoryInfo;
  metadata?: Record<string, unknown>;
}

Service Discovery

Use the @Discoverable() decorator to mark services for discovery:

import { Controller } from '@nestjs/common';
import { Discoverable } from '@lilith/nestjs-health';

@Controller()
@Discoverable({
  name: 'user-service',
  version: '1.0.0',
  tags: ['api', 'users'],
})
export class UserController {
  // ...
}

Getting Discoverable Metadata

import { getDiscoverableMetadata } from '@lilith/nestjs-health';

const metadata = getDiscoverableMetadata(UserController);
// { name: 'user-service', version: '1.0.0', tags: ['api', 'users'] }

Override Methods

Customize the health controller by overriding methods:

@Controller()
export class HealthController extends BaseHealthController {
  // Required: Return your app version
  protected getVersion(): string {
    return '1.0.0';
  }

  // Optional: Override environment detection
  protected getEnvironment(): string {
    return process.env.NODE_ENV ?? 'development';
  }

  // Optional: Add dependency health checks
  protected async checkDependencies(): Promise<DependencyHealth[]> {
    return [];
  }

  // Optional: Add custom metadata to detailed response
  protected getMetadata(): Record<string, unknown> {
    return {
      nodeVersion: process.version,
      hostname: os.hostname(),
    };
  }
}

License

MIT

Final test 1767646209