feat(08-01): Health monitoring & logging infrastructure
- Set up Winston structured logging with console and file outputs - Create GET /api/health endpoint with uptime, database status, response times - Add request logging middleware (method, path, statusCode, duration) - Create health monitoring module with database connectivity checks - Log all HTTP requests with timing information - Log auth events (login, register) and data modifications - Replace console.log/error with structured logger calls - Update backend README with logging configuration documentation - Add tests for health endpoint and logging middleware - Logs directory: logs/combined.log and logs/error.log Deliverables met: ✓ Structured logging (Winston) integrated ✓ Enhanced health endpoint with uptime & database info ✓ Request logging middleware attached to all routes ✓ Comprehensive logging documentation in README.md ✓ Tests passing for health and logging functionality ✓ All critical operations logged with context
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const { Pool } = require('pg');
|
||||
|
||||
// Mock logger
|
||||
const mockLogger = {
|
||||
info: () => {},
|
||||
error: () => {},
|
||||
warn: () => {},
|
||||
debug: () => {}
|
||||
};
|
||||
|
||||
test('Health endpoint returns status and uptime', async () => {
|
||||
const mockPool = {
|
||||
query: async () => ({ rows: [{ now: new Date() }] })
|
||||
};
|
||||
|
||||
const { getHealthStatus, getUptime } = require('../src/utils/health');
|
||||
|
||||
// Test getUptime function
|
||||
const uptime = getUptime();
|
||||
assert(typeof uptime === 'number', 'Uptime should be a number');
|
||||
assert(uptime >= 0, 'Uptime should be non-negative');
|
||||
|
||||
// Test getHealthStatus function with mock pool
|
||||
const health = await getHealthStatus(mockPool);
|
||||
assert(health.status, 'Health should have status');
|
||||
assert(['healthy', 'degraded', 'unhealthy'].includes(health.status), 'Status should be valid');
|
||||
assert(typeof health.uptime === 'number', 'Uptime should be a number');
|
||||
assert(health.timestamp, 'Health should have timestamp');
|
||||
assert(health.database, 'Health should have database info');
|
||||
});
|
||||
|
||||
test('Health endpoint handles database errors gracefully', async () => {
|
||||
const mockPoolError = {
|
||||
query: async () => {
|
||||
throw new Error('Database connection failed');
|
||||
}
|
||||
};
|
||||
|
||||
const { getHealthStatus } = require('../src/utils/health');
|
||||
|
||||
const health = await getHealthStatus(mockPoolError);
|
||||
assert.equal(health.status, 'unhealthy', 'Status should be unhealthy on DB error');
|
||||
assert.equal(health.database.connected, false, 'Database should show disconnected');
|
||||
assert(health.database.error, 'Should include error message');
|
||||
});
|
||||
|
||||
test('Request logging middleware logs HTTP requests', () => {
|
||||
const { default: requestLogger } = require('../src/middleware/requestLogger');
|
||||
|
||||
// Mock request and response objects
|
||||
const mockReq = {
|
||||
method: 'GET',
|
||||
path: '/api/health',
|
||||
ip: '127.0.0.1',
|
||||
get: () => 'test-agent'
|
||||
};
|
||||
|
||||
const mockRes = {
|
||||
statusCode: 200,
|
||||
send: function(data) { return data; }
|
||||
};
|
||||
|
||||
const mockNext = () => {};
|
||||
|
||||
// The middleware should not throw
|
||||
assert.doesNotThrow(() => {
|
||||
requestLogger(mockReq, mockRes, mockNext);
|
||||
}, 'Middleware should not throw on valid request');
|
||||
});
|
||||
|
||||
console.log('✓ Health monitoring and logging tests passed');
|
||||
Reference in New Issue
Block a user