- Upgrade Go module dependencies to latest versions - Add new middleware packages for CORS, logging, rate limiting, and security - Update go.mod and go.sum with latest package versions - Integrate new middleware components into server configuration - Improve project dependency management and middleware infrastructure
98 lines
2.0 KiB
Go
98 lines
2.0 KiB
Go
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// LoggingMiddleware creates a custom logging middleware with detailed request information
|
|
func LoggingMiddleware() gin.HandlerFunc {
|
|
return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
|
|
// Custom log format with more details
|
|
return fmt.Sprintf("[%s] %s %s %s %d %s \"%s\" %s \"%s\" %s\n",
|
|
param.TimeStamp.Format("2006-01-02 15:04:05"),
|
|
param.ClientIP,
|
|
param.Method,
|
|
param.Path,
|
|
param.StatusCode,
|
|
param.Latency,
|
|
param.Request.UserAgent(),
|
|
param.ErrorMessage,
|
|
param.Request.Referer(),
|
|
formatBodySize(param.BodySize),
|
|
)
|
|
})
|
|
}
|
|
|
|
// StructuredLoggingMiddleware creates a structured logging middleware for better log parsing
|
|
func StructuredLoggingMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Start timer
|
|
start := time.Now()
|
|
path := c.Request.URL.Path
|
|
raw := c.Request.URL.RawQuery
|
|
|
|
// Process request
|
|
c.Next()
|
|
|
|
// Calculate latency
|
|
latency := time.Since(start)
|
|
|
|
// Get client IP
|
|
clientIP := c.ClientIP()
|
|
|
|
// Get method
|
|
method := c.Request.Method
|
|
|
|
// Get status code
|
|
statusCode := c.Writer.Status()
|
|
|
|
// Get body size
|
|
bodySize := c.Writer.Size()
|
|
|
|
// Build full path with query string
|
|
if raw != "" {
|
|
path = path + "?" + raw
|
|
}
|
|
|
|
// Log structured information
|
|
log.Printf("REQUEST: method=%s path=%s status=%d latency=%v client_ip=%s body_size=%d user_agent=\"%s\"",
|
|
method,
|
|
path,
|
|
statusCode,
|
|
latency,
|
|
clientIP,
|
|
bodySize,
|
|
c.Request.UserAgent(),
|
|
)
|
|
|
|
// Log errors if any
|
|
if len(c.Errors) > 0 {
|
|
log.Printf("ERRORS: %v", c.Errors.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
// formatBodySize formats body size in human readable format
|
|
func formatBodySize(size int) string {
|
|
if size == 0 {
|
|
return "0B"
|
|
}
|
|
|
|
const unit = 1024
|
|
if size < unit {
|
|
return fmt.Sprintf("%dB", size)
|
|
}
|
|
|
|
div, exp := int64(unit), 0
|
|
for n := size / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
|
|
return fmt.Sprintf("%.1f%cB", float64(size)/float64(div), "KMGTPE"[exp])
|
|
}
|