Move project files from uzdb/ subdirectory to root directory for cleaner project structure.
Changes:
- Move frontend/ to root
- Move internal/ to root
- Move build/ to root
- Move all config files (go.mod, wails.json, etc.) to root
- Remove redundant uzdb/ subdirectory nesting
Project structure is now:
├── frontend/ # React application
├── internal/ # Go backend
├── build/ # Wails build assets
├── doc/ # Design documentation
├── main.go # Entry point
└── ...
🤖 Generated with Qoder
99 lines
2.0 KiB
Go
99 lines
2.0 KiB
Go
package middleware
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
|
|
"uzdb/internal/config"
|
|
)
|
|
|
|
// LoggerMiddleware returns a logging middleware using Zap
|
|
func LoggerMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
logger := config.GetLogger()
|
|
|
|
// Start timer
|
|
start := time.Now()
|
|
|
|
// Process request
|
|
c.Next()
|
|
|
|
// Calculate duration
|
|
duration := time.Since(start)
|
|
|
|
// Get client IP
|
|
clientIP := c.ClientIP()
|
|
|
|
// Get method
|
|
method := c.Request.Method
|
|
|
|
// Get path
|
|
path := c.Request.URL.Path
|
|
|
|
// Get status code
|
|
statusCode := c.Writer.Status()
|
|
|
|
// Get body size
|
|
bodySize := c.Writer.Size()
|
|
|
|
// Determine log level based on status code
|
|
var level zapcore.Level
|
|
switch {
|
|
case statusCode >= 500:
|
|
level = zapcore.ErrorLevel
|
|
case statusCode >= 400:
|
|
level = zapcore.WarnLevel
|
|
default:
|
|
level = zapcore.InfoLevel
|
|
}
|
|
|
|
// Create fields
|
|
fields := []zap.Field{
|
|
zap.Int("status", statusCode),
|
|
zap.String("method", method),
|
|
zap.String("path", path),
|
|
zap.String("ip", clientIP),
|
|
zap.Duration("duration", duration),
|
|
zap.Int("body_size", bodySize),
|
|
}
|
|
|
|
// Add error message if any
|
|
if len(c.Errors) > 0 {
|
|
fields = append(fields, zap.String("error", c.Errors.String()))
|
|
}
|
|
|
|
// Log the request
|
|
logger.Log(level, "HTTP request", fields...)
|
|
}
|
|
}
|
|
|
|
// RequestIDMiddleware adds a request ID to each request
|
|
func RequestIDMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Try to get request ID from header
|
|
requestID := c.GetHeader("X-Request-ID")
|
|
|
|
// Generate if not present
|
|
if requestID == "" {
|
|
requestID = generateRequestID()
|
|
}
|
|
|
|
// Set request ID in context
|
|
c.Set("request_id", requestID)
|
|
|
|
// Add to response header
|
|
c.Header("X-Request-ID", requestID)
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// generateRequestID generates a simple request ID
|
|
func generateRequestID() string {
|
|
return time.Now().Format("20060102150405") + "-" +
|
|
time.Now().Format("000000.000000")[7:]
|
|
}
|