EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
health.js
Go to the documentation of this file.
1/**
2 * @file health.js
3 * @module HealthRoutes
4 * @description Health check and service testing endpoints for infrastructure monitoring. Provides status checks for llama.cpp AI service, Redis cache, and PostgreSQL database. Used by load balancers, monitoring systems, and DevOps dashboards.
5 * @see {@link ../services/llamaCppService} for llama.cpp integration
6 * @see {@link ../services/db} for database connection
7 * @see {@link ../config/redis} for Redis configuration
8 * @apiDefine HealthGroup Health
9 * @apiGroup Health
10 * @apiError (Error 500) ServerError Service test failed (for test endpoints).
11 */
12
13// Health check route for AI and infrastructure
14const express = require('express');
15const router = express.Router();
16const { healthCheck: llamaHealthCheck, getModelInfo } = require('../services/llamaCppService');
17const Redis = require('ioredis');
18
19/**
20 * @api {get} /health Health check for all services
21 * @apiName GetHealth
22 * @apiGroup Health
23 * @apiDescription Comprehensive health check for all backend services including llama.cpp AI service, Redis cache, and PostgreSQL database. Always returns 200 OK to keep load balancers happy even if individual services are degraded. Use service-level status fields to determine actual health.
24 * @apiSuccess {string} status Overall status ("ok").
25 * @apiSuccess {string} timestamp Health check timestamp.
26 * @apiSuccess {object} services Service-specific health status.
27 * @apiSuccess {object} services.llamaCpp Llama.cpp AI service status.
28 * @apiSuccess {string} services.llamaCpp.status Service status (healthy, unhealthy, error).
29 * @apiSuccess {string} services.llamaCpp.endpoint Llama.cpp endpoint URL.
30 * @apiSuccess {object} [services.llamaCpp.model] Model information (if healthy).
31 * @apiSuccess {object} services.redis Redis cache status.
32 * @apiSuccess {string} services.redis.status Service status (healthy, error).
33 * @apiSuccess {Object} services.database PostgreSQL database status.
34 * @apiSuccess {string} services.database.status Service status (healthy, unhealthy, error).
35 * @apiExample {curl} Example usage:
36 * curl https://api.example.com/health
37 * @apiExample {json} Response example:
38 * {
39 * "status": "ok",
40 * "timestamp": "2026-03-12T10:30:00Z",
41 * "services": {
42 * "llamaCpp": {
43 * "status": "healthy",
44 * "endpoint": "http://localhost:8080",
45 * "model": "Qwen2.5-14B-Instruct"
46 * },
47 * "redis": {
48 * "status": "healthy",
49 * "host": "localhost",
50 * "port": 6379
51 * },
52 * "database": {
53 * "status": "healthy"
54 * }
55 * }
56 * }
57 */
58router.get('/health', async (req, res) => {
59 const health = {
60 status: 'ok',
61 timestamp: new Date().toISOString(),
62 services: {}
63 };
64
65 // Check llama.cpp
66 try {
67 const llamaHealthy = await llamaHealthCheck();
68 health.services.llamaCpp = {
69 status: llamaHealthy ? 'healthy' : 'unhealthy',
70 endpoint: process.env.LLAMA_CPP_ENDPOINT || 'http://localhost:8080'
71 };
72
73 if (llamaHealthy) {
74 const modelInfo = await getModelInfo();
75 if (modelInfo) {
76 health.services.llamaCpp.model = modelInfo;
77 }
78 }
79 } catch (error) {
80 health.services.llamaCpp = {
81 status: 'error',
82 error: error.message
83 };
84 // Don't mark as degraded - llama.cpp might be slow to respond
85 console.warn('[Health] llama.cpp check failed:', error.message);
86 }
87
88 // Check Redis
89 try {
90 const redisConfig = require('../config/redis');
91 const redis = new Redis({
92 ...redisConfig,
93 lazyConnect: true
94 });
95
96 await redis.connect();
97 await redis.ping();
98
99 health.services.redis = {
100 status: 'healthy',
101 host: process.env.REDIS_HOST || 'localhost',
102 port: process.env.REDIS_PORT || 6379
103 };
104
105 redis.disconnect();
106 } catch (error) {
107 health.services.redis = {
108 status: 'error',
109 error: error.message
110 };
111 // Don't mark as degraded - Redis might be initializing
112 console.warn('[Health] Redis check failed:', error.message);
113 }
114
115 // Check database (if DB module exists)
116 try {
117 const db = require('../services/db');
118 const result = await db.query('SELECT 1 as health');
119 health.services.database = {
120 status: result ? 'healthy' : 'unhealthy'
121 };
122 } catch (error) {
123 health.services.database = {
124 status: 'error',
125 error: error.message
126 };
127 // Don't mark as degraded - DB might be initializing
128 console.warn('[Health] Database check failed:', error.message);
129 }
130
131 // Always return 200 for DO health checks - the API is running
132 res.status(200).json(health);
133});
134
135/**
136 * @api {post} /health/test-llama Test llama.cpp AI endpoint
137 * @apiName TestLlama
138 * @apiGroup Health
139 * @apiDescription Test llama.cpp AI service by sending a sample text for rewriting. Returns the AI-generated output and endpoint information. Used for verifying AI service functionality and model responsiveness.
140 * @apiParam {string} [text="Hello, this is a test."] Test input text to send to llama.cpp.
141 * @apiSuccess {boolean} success Operation success status.
142 * @apiSuccess {string} input Input text sent to llama.cpp.
143 * @apiSuccess {string} output AI-generated output from llama.cpp.
144 * @apiSuccess {string} endpoint Llama.cpp endpoint URL.
145 * @apiError (Error 500) ServerError Llama.cpp service unreachable or error.
146 * @apiExample {curl} Example usage:
147 * curl -X POST -d '{"text":"Test message"}' https://api.example.com/health/test-llama
148 */
149router.post('/test-llama', async (req, res) => {
150 const { callLlama } = require('../services/llamaCppService');
151 const { text = 'Hello, this is a test.' } = req.body;
152
153 try {
154 const result = await callLlama(text, 'rewrite');
155 res.json({
156 success: true,
157 input: text,
158 output: result,
159 endpoint: process.env.LLAMA_CPP_ENDPOINT
160 });
161 } catch (error) {
162 res.status(500).json({
163 success: false,
164 error: error.message,
165 endpoint: process.env.LLAMA_CPP_ENDPOINT
166 });
167 }
168});
169
170/**
171 * @api {get} /health/test-redis Test Redis connection
172 * @apiName TestRedis
173 * @apiGroup Health
174 * @apiDescription Test Redis cache connection and functionality by performing set/get operations with a test key. Key expires after 10 seconds. Used for verifying Redis connectivity and read/write operations.
175 * @apiSuccess {boolean} success Operation success status.
176 * @apiSuccess {string} message Status message.
177 * @apiSuccess {number} testValue Value that was set and retrieved.
178 * @apiSuccess {string} host Redis host.
179 * @apiSuccess {number} port Redis port.
180 * @apiError (Error 500) ServerError Redis connection or operation failed.
181 * @apiExample {curl} Example usage:
182 * curl https://api.example.com/health/test-redis
183 */
184router.get('/test-redis', async (req, res) => {
185 try {
186 const redisConfig = require('../config/redis');
187 const redis = new Redis(redisConfig);
188
189 const testKey = 'health:test';
190 const testValue = Date.now().toString();
191
192 await redis.set(testKey, testValue, 'EX', 10);
193 const retrieved = await redis.get(testKey);
194
195 redis.disconnect();
196
197 res.json({
198 success: true,
199 written: testValue,
200 retrieved,
201 match: testValue === retrieved,
202 config: {
203 host: process.env.REDIS_HOST || 'localhost',
204 port: process.env.REDIS_PORT || 6379,
205 passwordSet: !!process.env.REDIS_PASSWORD
206 }
207 });
208 } catch (error) {
209 res.status(500).json({
210 success: false,
211 error: error.message
212 });
213 }
214});
215
216module.exports = router;