Add webhook logging, pagination, middleware, migrations, and prod hardening
- Webhook event logging repo and subscription webhook idempotency - Pagination helper (echohelpers) with cursor/offset support - Request ID and structured logging middleware - Push client improvements (FCM HTTP v1, better error handling) - Task model version column, business constraint migrations, targeted indexes - Expanded categorization chain tests - Email service and config hardening - CI workflow updates, .gitignore additions, .env.example updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
53
internal/middleware/logger.go
Normal file
53
internal/middleware/logger.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
)
|
||||
|
||||
// StructuredLogger is zerolog-based request logging middleware that includes
|
||||
// correlation IDs, user IDs, and latency metrics.
|
||||
func StructuredLogger() echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
start := time.Now()
|
||||
|
||||
err := next(c)
|
||||
|
||||
latency := time.Since(start)
|
||||
|
||||
// Build structured log event
|
||||
event := log.Info()
|
||||
if c.Response().Status >= 500 {
|
||||
event = log.Error()
|
||||
} else if c.Response().Status >= 400 {
|
||||
event = log.Warn()
|
||||
}
|
||||
|
||||
// Request ID
|
||||
if reqID := GetRequestID(c); reqID != "" {
|
||||
event = event.Str("request_id", reqID)
|
||||
}
|
||||
|
||||
// User ID (from auth middleware)
|
||||
if user, ok := c.Get(AuthUserKey).(*models.User); ok && user != nil {
|
||||
event = event.Uint("user_id", user.ID)
|
||||
}
|
||||
|
||||
event.
|
||||
Str("method", c.Request().Method).
|
||||
Str("path", c.Path()).
|
||||
Str("uri", c.Request().RequestURI).
|
||||
Int("status", c.Response().Status).
|
||||
Int64("latency_ms", latency.Milliseconds()).
|
||||
Str("remote_ip", c.RealIP()).
|
||||
Msg("request")
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user