344 lines
8.4 KiB
Markdown
344 lines
8.4 KiB
Markdown
# 📝 Centralized Logging System
|
|
|
|
This guide covers the **centralized, high-performance logging system** implemented using **Pino** - the fastest JSON logger for Node.js applications.
|
|
|
|
## 🎯 **Architecture Overview**
|
|
|
|
### **Single Logger System**
|
|
|
|
- ✅ **Backend (BFF)**: `nestjs-pino` with Pino
|
|
- ✅ **Frontend**: Custom structured logger compatible with backend
|
|
- ✅ **Shared**: Common interfaces and configurations
|
|
- ❌ **No more mixed logging systems**
|
|
|
|
### **Benefits of Centralization**
|
|
|
|
- 🚀 **Performance**: Pino is 5x faster than winston
|
|
- 🔒 **Security**: Automatic sensitive data sanitization
|
|
- 📊 **Structured**: JSON logging for better parsing
|
|
- 🌐 **Correlation**: Request tracking across services
|
|
- 📈 **Monitoring**: Easy integration with log aggregation'
|
|
- this implemetnatin requires more type safety faeteur
|
|
|
|
## 🏗️ **Implementation**
|
|
|
|
### **Backend (BFF) - NestJS + Pino**
|
|
|
|
```typescript
|
|
// ✅ CORRECT: Use nestjs-pino Logger
|
|
import { Logger } from "nestjs-pino";
|
|
|
|
@Injectable()
|
|
export class UserService {
|
|
constructor(@Inject(Logger) private readonly logger: Logger) {}
|
|
|
|
async findUser(id: string) {
|
|
this.logger.info(`Finding user ${id}`);
|
|
// ... implementation
|
|
}
|
|
}
|
|
```
|
|
|
|
### **Frontend - Structured Logger**
|
|
|
|
```typescript
|
|
// ✅ CORRECT: Use shared logger interface
|
|
import { logger } from "@/lib/logger";
|
|
|
|
export function handleApiCall() {
|
|
logger.logApiCall("/api/users", "GET", 200, 150);
|
|
logger.logUserAction("user123", "login");
|
|
}
|
|
```
|
|
|
|
## 🚫 **What NOT to Do**
|
|
|
|
### **❌ Don't Use Multiple Logging Systems**
|
|
|
|
```typescript
|
|
// ❌ WRONG: Mixing logging systems
|
|
import { Logger } from "@nestjs/common"; // Don't use this - REMOVED
|
|
import { Logger } from "nestjs-pino"; // ✅ Use this - CENTRALIZED
|
|
|
|
// ❌ WRONG: Console logging in production
|
|
console.log("User logged in"); // Don't use console.log
|
|
logger.info("User logged in"); // Use structured logger
|
|
```
|
|
|
|
### **✅ Current Status: FULLY CENTRALIZED**
|
|
|
|
- **All BFF services** now use `nestjs-pino` Logger
|
|
- **No more** `@nestjs/common` Logger imports
|
|
- **No more** `new Logger()` instantiations
|
|
- **Single logging system** throughout the entire backend
|
|
|
|
### **❌ Don't Use Console Methods**
|
|
|
|
```typescript
|
|
// ❌ WRONG: Direct console usage
|
|
console.log("Debug info");
|
|
console.error("Error occurred");
|
|
console.warn("Warning message");
|
|
|
|
// ✅ CORRECT: Structured logging
|
|
logger.debug("Debug info");
|
|
logger.error("Error occurred");
|
|
logger.warn("Warning message");
|
|
```
|
|
|
|
## 🔧 **Configuration**
|
|
|
|
### **Environment Variables**
|
|
|
|
```bash
|
|
# Logging configuration
|
|
LOG_LEVEL=info # error, warn, info, debug, trace
|
|
APP_NAME=customer-portal-bff # Service identifier
|
|
NODE_ENV=development # Environment context
|
|
```
|
|
|
|
### **Log Levels**
|
|
|
|
| Level | Numeric | Description |
|
|
| ------- | ------- | ------------------------------------ |
|
|
| `error` | 0 | Errors that need immediate attention |
|
|
| `warn` | 1 | Warnings that should be monitored |
|
|
| `info` | 2 | General information about operations |
|
|
| `debug` | 3 | Detailed debugging information |
|
|
| `trace` | 4 | Very detailed tracing information |
|
|
|
|
## 📝 **Usage Examples**
|
|
|
|
### **Basic Logging**
|
|
|
|
```typescript
|
|
// Simple messages
|
|
logger.info("User authentication successful");
|
|
logger.warn("Rate limit approaching");
|
|
logger.error("Database connection failed");
|
|
|
|
// With structured data
|
|
logger.info("Invoice created", {
|
|
invoiceId: "INV-001",
|
|
amount: 99.99,
|
|
userId: "user123",
|
|
});
|
|
```
|
|
|
|
### **API Call Logging**
|
|
|
|
```typescript
|
|
// Automatic API call logging
|
|
logger.logApiCall("/api/invoices", "POST", 201, 250, {
|
|
userId: "user123",
|
|
invoiceId: "INV-001",
|
|
});
|
|
```
|
|
|
|
### **User Action Logging**
|
|
|
|
```typescript
|
|
// User activity tracking
|
|
logger.logUserAction("user123", "password_change", {
|
|
ipAddress: "192.168.1.1",
|
|
userAgent: "Mozilla/5.0...",
|
|
});
|
|
```
|
|
|
|
### **Error Logging**
|
|
|
|
```typescript
|
|
// Comprehensive error logging
|
|
try {
|
|
// ... operation
|
|
} catch (error) {
|
|
logger.logError(error, "user_creation", {
|
|
userId: "user123",
|
|
email: "user@example.com",
|
|
});
|
|
}
|
|
```
|
|
|
|
## 🔍 **Request Correlation**
|
|
|
|
### **Automatic Correlation IDs**
|
|
|
|
```typescript
|
|
// Every request gets a unique correlation ID
|
|
// Headers: x-correlation-id: 1703123456789-abc123def
|
|
|
|
logger.info("Processing request", {
|
|
correlationId: req.headers["x-correlation-id"],
|
|
endpoint: req.url,
|
|
method: req.method,
|
|
});
|
|
```
|
|
|
|
### **Manual Correlation**
|
|
|
|
```typescript
|
|
// Set correlation context
|
|
logger.setCorrelationId("req-123");
|
|
logger.setUserId("user-456");
|
|
logger.setRequestId("req-789");
|
|
|
|
// All subsequent logs include this context
|
|
logger.info("User action completed");
|
|
```
|
|
|
|
## 📊 **Production Logging**
|
|
|
|
### **File Logging**
|
|
|
|
```typescript
|
|
// Automatic log rotation
|
|
// - Combined logs: logs/customer-portal-bff-combined.log
|
|
// - Error logs: logs/customer-portal-bff-error.log
|
|
// - Console output: stdout (for container logs)
|
|
```
|
|
|
|
### **Log Aggregation**
|
|
|
|
```typescript
|
|
// Structured JSON output for easy parsing
|
|
{
|
|
"timestamp": "2025-01-22T10:30:00.000Z",
|
|
"level": "info",
|
|
"service": "customer-portal-bff",
|
|
"environment": "production",
|
|
"message": "User authentication successful",
|
|
"correlationId": "req-123",
|
|
"userId": "user-456",
|
|
"data": {
|
|
"ipAddress": "192.168.1.1",
|
|
"userAgent": "Mozilla/5.0..."
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🚀 **Performance Benefits**
|
|
|
|
### **Benchmarks (Pino vs Winston)**
|
|
|
|
| Operation | Pino | Winston | Improvement |
|
|
| -------------------- | ---- | ------- | ------------- |
|
|
| JSON serialization | 1x | 5x | **5x faster** |
|
|
| Object serialization | 1x | 3x | **3x faster** |
|
|
| String interpolation | 1x | 2x | **2x faster** |
|
|
| Overall performance | 1x | 5x | **5x faster** |
|
|
|
|
### **Memory Usage**
|
|
|
|
- **Pino**: Minimal memory footprint
|
|
- **Winston**: Higher memory usage due to object retention
|
|
- **Console**: No memory overhead but unstructured
|
|
|
|
## 🔒 **Security Features**
|
|
|
|
### **Automatic Data Sanitization**
|
|
|
|
```typescript
|
|
// Sensitive data is automatically redacted
|
|
logger.info("User login", {
|
|
email: "user@example.com",
|
|
password: "[REDACTED]", // Automatically sanitized
|
|
token: "[REDACTED]", // Automatically sanitized
|
|
ipAddress: "192.168.1.1", // Safe to log
|
|
});
|
|
```
|
|
|
|
### **Sanitized Headers**
|
|
|
|
```typescript
|
|
// Request headers are automatically cleaned
|
|
{
|
|
"authorization": "[REDACTED]",
|
|
"cookie": "[REDACTED]",
|
|
"x-api-key": "[REDACTED]",
|
|
"user-agent": "Mozilla/5.0...", // Safe to log
|
|
"accept": "application/json" // Safe to log
|
|
}
|
|
```
|
|
|
|
## 🔄 **Migration Guide**
|
|
|
|
### **From @nestjs/common Logger**
|
|
|
|
```typescript
|
|
// ❌ OLD: @nestjs/common Logger
|
|
import { Logger } from "@nestjs/common";
|
|
private readonly logger = new Logger(ServiceName.name);
|
|
|
|
// ✅ NEW: nestjs-pino Logger
|
|
import { Logger } from "nestjs-pino";
|
|
constructor(@Inject(Logger) private readonly logger: Logger) {}
|
|
```
|
|
|
|
### **From Console Logging**
|
|
|
|
```typescript
|
|
// ❌ OLD: Console methods
|
|
console.log("Debug info");
|
|
console.error("Error occurred");
|
|
|
|
// ✅ NEW: Structured logger
|
|
logger.debug("Debug info");
|
|
logger.error("Error occurred");
|
|
```
|
|
|
|
### **From Winston**
|
|
|
|
```typescript
|
|
// ❌ OLD: Winston logger
|
|
import * as winston from 'winston';
|
|
const logger = winston.createLogger({...});
|
|
|
|
// ✅ NEW: Pino logger
|
|
import { Logger } from "nestjs-pino";
|
|
constructor(@Inject(Logger) private readonly logger: Logger) {}
|
|
```
|
|
|
|
## 📋 **Best Practices**
|
|
|
|
### **✅ Do's**
|
|
|
|
- Use structured logging with context
|
|
- Include correlation IDs in all logs
|
|
- Log at appropriate levels
|
|
- Sanitize sensitive data
|
|
- Use consistent message formats
|
|
|
|
### **❌ Don'ts**
|
|
|
|
- Don't mix logging systems
|
|
- Don't use console methods in production
|
|
- Don't log sensitive information
|
|
- Don't log large objects unnecessarily
|
|
- Don't use string interpolation for logging
|
|
|
|
## 🛠️ **Troubleshooting**
|
|
|
|
### **Common Issues**
|
|
|
|
1. **Multiple Logger Instances**: Ensure single logger per service
|
|
2. **Missing Correlation IDs**: Check middleware configuration
|
|
3. **Performance Issues**: Verify log level settings
|
|
4. **Missing Logs**: Check file permissions and disk space
|
|
|
|
### **Debug Mode**
|
|
|
|
```bash
|
|
# Enable debug logging
|
|
LOG_LEVEL=debug pnpm dev
|
|
|
|
# Check logger configuration
|
|
LOG_LEVEL=trace pnpm dev
|
|
```
|
|
|
|
## 📚 **Additional Resources**
|
|
|
|
- [Pino Documentation](https://getpino.io/)
|
|
- [NestJS Pino Module](https://github.com/iamolegga/nestjs-pino)
|
|
- [Structured Logging Best Practices](https://12factor.net/logs)
|
|
- [Log Correlation Patterns](https://microservices.io/patterns/observability/distributed-tracing.html)
|