refactor: разделение кода на пакеты и улучшение архитектуры
- Создана новая структура проекта с разделением на пакеты - Добавлены интерфейсы для всех сервисов (Git, Quartz, Files, Build) - Реализован Dependency Injection для сервисов - Добавлены middleware для логирования, Request ID и Response Time - Создан пакет конфигурации с валидацией - Улучшено логирование через интерфейс - Добавлены обработчики HTTP в отдельных пакетах - Создана структура для тестирования - Добавлены конфигурационные файлы и документация
This commit is contained in:
67
internal/middleware/logging.go
Normal file
67
internal/middleware/logging.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go-webhook-server/pkg/logger"
|
||||
)
|
||||
|
||||
// LoggingMiddleware создает middleware для логирования HTTP запросов
|
||||
func LoggingMiddleware(log logger.Logger) gin.HandlerFunc {
|
||||
return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
|
||||
// Логируем детали запроса
|
||||
log.WithFields(map[string]interface{}{
|
||||
"status": param.StatusCode,
|
||||
"latency": param.Latency,
|
||||
"client_ip": param.ClientIP,
|
||||
"method": param.Method,
|
||||
"path": param.Path,
|
||||
"user_agent": param.Request.UserAgent(),
|
||||
}).Info("HTTP Request")
|
||||
|
||||
// Возвращаем пустую строку, так как логирование уже выполнено
|
||||
return ""
|
||||
})
|
||||
}
|
||||
|
||||
// RequestIDMiddleware добавляет уникальный ID к каждому запросу
|
||||
func RequestIDMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = generateRequestID()
|
||||
}
|
||||
|
||||
c.Set("request_id", requestID)
|
||||
c.Header("X-Request-ID", requestID)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// ResponseTimeMiddleware добавляет время ответа в заголовки
|
||||
func ResponseTimeMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
|
||||
c.Next()
|
||||
|
||||
duration := time.Since(start)
|
||||
c.Header("X-Response-Time", duration.String())
|
||||
}
|
||||
}
|
||||
|
||||
// generateRequestID генерирует простой ID запроса
|
||||
func generateRequestID() string {
|
||||
return time.Now().Format("20060102150405") + "-" + randomString(6)
|
||||
}
|
||||
|
||||
// randomString генерирует случайную строку указанной длины
|
||||
func randomString(length int) string {
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, length)
|
||||
for i := range b {
|
||||
b[i] = charset[time.Now().UnixNano()%int64(len(charset))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
Reference in New Issue
Block a user