添加Health健康检查端点
This commit is contained in:
@@ -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 };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
13
server/db.js
13
server/db.js
@@ -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
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user