- Initialize Git repository with main branch - Create comprehensive .gitignore for Node.js, React, and environment files - Set up directory structure (frontend/, backend/, docs/) - Create detailed README.md with project overview and setup instructions - Add .env.example with all required environment variables - Configure Prettier for consistent code formatting All acceptance criteria met: ✅ Git repository initialized with appropriate .gitignore ✅ Directory structure matches Technical Assumptions ✅ README.md created with project overview and setup docs ✅ .env.example file with all required environment variables ✅ Prettier config files added for code formatting consistency 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
80 lines
2.1 KiB
Markdown
80 lines
2.1 KiB
Markdown
# 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 });
|
|
```
|
|
|
|
---
|