Total rebrand across all Go API source files: - Go module path: casera-api -> honeydue-api - All imports updated (130+ files) - Docker: containers, images, networks renamed - Email templates: support email, noreply, icon URL - Domains: casera.app/mycrib.treytartt.com -> honeyDue.treytartt.com - Bundle IDs: com.tt.casera -> com.tt.honeyDue - IAP product IDs updated - Landing page, admin panel, config defaults - Seeds, CI workflows, Makefile, docs - Database table names preserved (no migration needed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
54 lines
1.2 KiB
Go
54 lines
1.2 KiB
Go
package middleware
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"github.com/treytartt/honeydue-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
|
|
}
|
|
}
|
|
}
|