# Monitoring and Observability ## Monitoring Stack - **Frontend Monitoring:** Browser console errors (dev), future: Sentry for production error tracking - **Backend Monitoring:** Winston structured logging, health check endpoint for uptime - **Error Tracking:** Console logs (dev), future: Sentry or LogRocket - **Performance Monitoring:** Lighthouse audits (manual), future: Web Vitals reporting ## Key Metrics **Frontend Metrics:** - **Core Web Vitals:** - LCP (Largest Contentful Paint): <2.5s - FID (First Input Delay): <100ms - CLS (Cumulative Layout Shift): <0.1 - **JavaScript errors:** Track with Error Boundaries - **API response times:** Log slow requests (>1s) - **User interactions:** Button clicks, form submissions **Backend Metrics:** - **Request rate:** Requests per second - **Error rate:** 4xx/5xx responses per minute - **Response time:** P50, P95, P99 latency - **Database query performance:** Slow queries (>100ms) - **Open Library API:** Success rate, response times **Health Check Endpoint:** ```javascript // GET /api/health app.get('/api/health', async (req, res) => { try { // Check database connection await prisma.$queryRaw`SELECT 1`; res.json({ status: 'ok', timestamp: new Date().toISOString(), uptime: process.uptime(), database: 'connected', }); } catch (error) { res.status(503).json({ status: 'error', timestamp: new Date().toISOString(), database: 'disconnected', }); } }); ``` **Logging (Winston):** ```javascript // utils/logger.js const winston = require('winston'); const logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ new winston.transports.Console({ format: winston.format.simple(), }), // Add file transport for production // new winston.transports.File({ filename: 'error.log', level: 'error' }), ], }); module.exports = logger; // Usage: logger.info('Book created', { bookId: 123, title: 'Test Book' }); logger.error('API error', { error: err.message, stack: err.stack }); ``` ---