添加Health健康检查端点

This commit is contained in:
CN-JS-HuiBai
2026-04-05 21:13:27 +08:00
parent a103c7dbf5
commit e8e23c5af8
3 changed files with 68 additions and 2 deletions

View File

@@ -63,6 +63,17 @@ const cache = {
} catch (e) {
// ignore
}
},
async checkHealth() {
if (!redis) return { status: 'down', error: 'Valkey client not initialized' };
try {
const result = await redis.ping();
if (result === 'PONG') return { status: 'up' };
return { status: 'down', error: 'Invalid ping response' };
} catch (e) {
return { status: 'down', error: e.message };
}
}
};

View File

@@ -18,9 +18,20 @@ function initPool() {
});
}
async function checkHealth() {
try {
if (!pool) return { status: 'down', error: 'Database pool not initialized' };
await pool.query('SELECT 1');
return { status: 'up' };
} catch (err) {
return { status: 'down', error: err.message };
}
}
initPool();
module.exports = {
query: (...args) => pool.query(...args),
initPool
initPool,
checkHealth
};

View File

@@ -51,6 +51,50 @@ async function checkDb() {
}
checkDb();
// --- Health API ---
app.get('/health', async (req, res) => {
try {
const dbStatus = await db.checkHealth();
const cacheStatus = await cache.checkHealth();
const isAllOk = dbStatus.status === 'up' && cacheStatus.status === 'up';
const healthInfo = {
status: isAllOk ? 'ok' : 'error',
timestamp: new Date().toISOString(),
service: {
status: 'running',
uptime: Math.floor(process.uptime()),
memory_usage: {
rss: Math.floor(process.memoryUsage().rss / 1024 / 1024) + ' MB',
heapTotal: Math.floor(process.memoryUsage().heapTotal / 1024 / 1024) + ' MB'
},
node_version: process.version
},
checks: {
database: {
name: 'MySQL',
status: dbStatus.status,
message: dbStatus.error || 'Connected'
},
valkey: {
name: 'Valkey (Redis)',
status: cacheStatus.status,
message: cacheStatus.error || 'Connected'
}
}
};
if (isAllOk) {
res.json(healthInfo);
} else {
res.status(500).json(healthInfo);
}
} catch (err) {
res.status(500).json({ status: 'error', message: err.message });
}
});
// --- Auth API ---
app.post('/api/auth/login', async (req, res) => {
const { username, password } = req.body;
@@ -313,7 +357,7 @@ app.post('/api/setup/admin', async (req, res) => {
// Middleware to protect routes & enforce setup
app.use(async (req, res, next) => {
// Allow system files and setup APIs
if (req.path.startsWith('/api/setup') || req.path === '/init.html' || req.path.startsWith('/css/') || req.path.startsWith('/js/') || req.path.startsWith('/fonts/')) {
if (req.path === '/health' || req.path.startsWith('/api/setup') || req.path === '/init.html' || req.path.startsWith('/css/') || req.path.startsWith('/js/') || req.path.startsWith('/fonts/')) {
return next();
}