Refactor customer domain structure and implement core entities, services, and handlers
- Introduced a flat structure for the customer domain, consolidating entities, aggregates, repositories, services, forms, and handlers into a single package. - Added core entities: Customer and CustomerAggregate. - Implemented request/response forms for customer authentication (Register, Login, Refresh Token, Change Password). - Created CustomerService to handle business logic and data access through the Repository interface. - Established CustomerHandler for HTTP request handling related to customer authentication. - Removed previous domain structure artifacts to streamline the codebase.
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# Logging System Upgrade: Logrus → Zap + Lumberjack
|
||||
|
||||
## Overview
|
||||
|
||||
The tender management system has been upgraded from Logrus to **Zap** with **Lumberjack** for high-performance structured logging with automatic log rotation.
|
||||
|
||||
## 🚀 **Improvements**
|
||||
|
||||
### **Performance**
|
||||
- **10x faster** logging performance with Zap
|
||||
- Zero-allocation logging in hot paths
|
||||
- Structured field processing optimized for speed
|
||||
|
||||
### **Log Rotation**
|
||||
- **Automatic log rotation** based on file size, age, and backup count
|
||||
- **Compression** of rotated log files to save disk space
|
||||
- **Configurable retention** policies
|
||||
|
||||
### **Flexibility**
|
||||
- **Multi-output** logging (file + stdout simultaneously)
|
||||
- **Multiple formats** (JSON, console, text)
|
||||
- **Environment-specific** configuration
|
||||
|
||||
## 📁 **Configuration**
|
||||
|
||||
### **YAML Configuration**
|
||||
```yaml
|
||||
logging:
|
||||
level: "info" # debug, info, warn, error, fatal
|
||||
format: "json" # json, console, text
|
||||
output: "file" # stdout, stderr, file
|
||||
file:
|
||||
path: "./logs/app.log" # Path to log file
|
||||
max_size: 100 # Max size in MB before rotation
|
||||
max_backups: 5 # Number of backup files to keep
|
||||
max_age: 30 # Max age in days to keep log files
|
||||
compress: true # Compress rotated files
|
||||
```
|
||||
|
||||
### **Environment Variables**
|
||||
```bash
|
||||
export TM_LOGGING_LEVEL="info"
|
||||
export TM_LOGGING_OUTPUT="file"
|
||||
export TM_LOGGING_FILE_PATH="./logs/app.log"
|
||||
export TM_LOGGING_FILE_MAX_SIZE=100
|
||||
export TM_LOGGING_FILE_MAX_BACKUPS=5
|
||||
export TM_LOGGING_FILE_MAX_AGE=30
|
||||
export TM_LOGGING_FILE_COMPRESS=true
|
||||
```
|
||||
|
||||
## 🔧 **Usage**
|
||||
|
||||
### **Same Interface**
|
||||
The logger interface remains the same - **no code changes required** in existing handlers and services:
|
||||
|
||||
```go
|
||||
// All existing code continues to work
|
||||
log.Info("User logged in", map[string]interface{}{
|
||||
"user_id": user.ID.String(),
|
||||
"email": user.Email,
|
||||
})
|
||||
|
||||
// Structured logging with fields
|
||||
logger := log.WithFields(map[string]interface{}{
|
||||
"component": "auth",
|
||||
"request_id": requestID,
|
||||
})
|
||||
logger.Error("Authentication failed", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
```
|
||||
|
||||
### **New Features**
|
||||
```go
|
||||
// Flush logs before shutdown
|
||||
logger.Sync()
|
||||
|
||||
// Or use the global function
|
||||
import "tm/pkg/logger"
|
||||
logger.Sync()
|
||||
```
|
||||
|
||||
## 📊 **Log Rotation Behavior**
|
||||
|
||||
### **File Naming Pattern**
|
||||
```
|
||||
logs/
|
||||
├── app.log # Current log file
|
||||
├── app.log.1 # Most recent backup
|
||||
├── app.log.2 # Older backup
|
||||
├── app.log.3.gz # Compressed older backup
|
||||
├── app.log.4.gz # Compressed older backup
|
||||
└── app.log.5.gz # Oldest backup (will be deleted on next rotation)
|
||||
```
|
||||
|
||||
### **Rotation Triggers**
|
||||
- **Size-based**: When `app.log` reaches 100MB
|
||||
- **Time-based**: Daily rotation (if configured)
|
||||
- **Manual**: Can be triggered programmatically
|
||||
|
||||
### **Cleanup**
|
||||
- Keeps maximum 5 backup files
|
||||
- Deletes files older than 30 days
|
||||
- Compresses old files to save space
|
||||
|
||||
## 🛠️ **Development Commands**
|
||||
|
||||
### **Log Management**
|
||||
```bash
|
||||
# View live logs
|
||||
make logs
|
||||
|
||||
# Follow logs in real-time
|
||||
make logs-live
|
||||
|
||||
# Clean all log files
|
||||
make logs-clean
|
||||
|
||||
# Clean everything including logs
|
||||
make clean-all
|
||||
```
|
||||
|
||||
### **Log File Locations**
|
||||
- **Development**: `./logs/app.log`
|
||||
- **Docker**: `/logs/app.log` (mounted volume)
|
||||
- **Production**: Configurable via environment variables
|
||||
|
||||
## 🐳 **Docker Integration**
|
||||
|
||||
### **Volume Mounting**
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
volumes:
|
||||
- ./logs:/logs # Host logs directory mounted to container
|
||||
```
|
||||
|
||||
### **Log Persistence**
|
||||
- Logs persist on the host machine
|
||||
- Rotation works across container restarts
|
||||
- Easy log analysis and monitoring
|
||||
|
||||
## 🔍 **Log Format Examples**
|
||||
|
||||
### **JSON Format (Default)**
|
||||
```json
|
||||
{
|
||||
"timestamp": "2024-01-15T10:30:45.123Z",
|
||||
"level": "info",
|
||||
"caller": "handler/auth_handler.go:45",
|
||||
"msg": "User logged in successfully",
|
||||
"user_id": "123e4567-e89b-12d3-a456-426614174000",
|
||||
"email": "user@example.com",
|
||||
"request_id": "req_abc123"
|
||||
}
|
||||
```
|
||||
|
||||
### **Console Format (Development)**
|
||||
```
|
||||
2024-01-15T10:30:45.123Z INFO handler/auth_handler.go:45 User logged in successfully
|
||||
user_id=123e4567-e89b-12d3-a456-426614174000
|
||||
email=user@example.com
|
||||
request_id=req_abc123
|
||||
```
|
||||
|
||||
## 🚨 **Migration Notes**
|
||||
|
||||
### **Breaking Changes**
|
||||
- **None** - The logger interface remains compatible
|
||||
|
||||
### **Dependencies Updated**
|
||||
```go
|
||||
// Removed
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
|
||||
// Added
|
||||
go.uber.org/zap v1.26.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
```
|
||||
|
||||
### **Configuration Changes**
|
||||
- Added `file` section to logging configuration
|
||||
- `output: "file"` now enables file logging with rotation
|
||||
|
||||
## 📈 **Performance Comparison**
|
||||
|
||||
| Metric | Logrus | Zap | Improvement |
|
||||
|--------|--------|-----|-------------|
|
||||
| **Throughput** | ~100k/sec | ~1M+/sec | **10x faster** |
|
||||
| **Allocations** | High | Zero (hot path) | **Much lower memory** |
|
||||
| **CPU Usage** | Higher | Lower | **Better efficiency** |
|
||||
| **Structured Fields** | Reflection-based | Type-safe | **Faster processing** |
|
||||
|
||||
## 🔧 **Advanced Configuration**
|
||||
|
||||
### **Custom Log Levels**
|
||||
```go
|
||||
// Set different levels for different components
|
||||
config := &infrastructure.LoggingConfig{
|
||||
Level: "debug", // Global level
|
||||
// Component-specific levels can be added later
|
||||
}
|
||||
```
|
||||
|
||||
### **Multiple Outputs**
|
||||
```go
|
||||
// Logs go to both file and stdout when output is "file"
|
||||
// Perfect for development - see logs in terminal AND save to file
|
||||
```
|
||||
|
||||
### **Programmatic Control**
|
||||
```go
|
||||
// Flush logs before application shutdown
|
||||
defer logger.Cleanup()
|
||||
|
||||
// Or manually sync
|
||||
if err := logger.Sync(); err != nil {
|
||||
// Handle sync error
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 **Best Practices**
|
||||
|
||||
1. **Use structured fields** for better log analysis
|
||||
2. **Set appropriate log levels** (info for production, debug for development)
|
||||
3. **Monitor log file sizes** in production
|
||||
4. **Use log aggregation** tools like ELK stack for production
|
||||
5. **Flush logs** before application shutdown
|
||||
|
||||
## 📚 **Resources**
|
||||
|
||||
- [Zap Documentation](https://pkg.go.dev/go.uber.org/zap)
|
||||
- [Lumberjack Documentation](https://pkg.go.dev/gopkg.in/natefinch/lumberjack.v2)
|
||||
- [Go Logging Best Practices](https://dave.cheney.net/2015/11/05/lets-talk-about-logging)
|
||||
Reference in New Issue
Block a user