mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-21 15:12:29 +02:00
145 lines
3.7 KiB
Go
145 lines
3.7 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/j3ssie/osmedeus/v5/internal/logger"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// DebugRequestBody logs request bodies for POST/PUT/PATCH requests in debug mode
|
|
func DebugRequestBody() fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
log := logger.Get()
|
|
method := c.Method()
|
|
|
|
// Only log bodies for methods that typically have request bodies
|
|
if method == "POST" || method == "PUT" || method == "PATCH" {
|
|
body := c.Body()
|
|
if len(body) > 0 {
|
|
// Try to pretty-print JSON
|
|
var prettyJSON bytes.Buffer
|
|
if err := json.Indent(&prettyJSON, body, "", " "); err == nil {
|
|
log.Debug("Request body",
|
|
zap.String("method", method),
|
|
zap.String("path", c.Path()),
|
|
zap.String("body", prettyJSON.String()),
|
|
)
|
|
} else {
|
|
// Not JSON or invalid JSON, log as-is (truncated if too long)
|
|
bodyStr := string(body)
|
|
if len(bodyStr) > 2000 {
|
|
bodyStr = bodyStr[:2000] + "... (truncated)"
|
|
}
|
|
log.Debug("Request body",
|
|
zap.String("method", method),
|
|
zap.String("path", c.Path()),
|
|
zap.String("body", bodyStr),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Log query parameters for all requests
|
|
if c.Request().URI().QueryString() != nil && len(c.Request().URI().QueryString()) > 0 {
|
|
log.Debug("Request query params",
|
|
zap.String("method", method),
|
|
zap.String("path", c.Path()),
|
|
zap.String("query", string(c.Request().URI().QueryString())),
|
|
)
|
|
}
|
|
|
|
return c.Next()
|
|
}
|
|
}
|
|
|
|
// DebugErrorHandler wraps responses to log detailed error information
|
|
func DebugErrorHandler(c *fiber.Ctx, err error) error {
|
|
log := logger.Get()
|
|
|
|
code := fiber.StatusInternalServerError
|
|
if e, ok := err.(*fiber.Error); ok {
|
|
code = e.Code
|
|
}
|
|
|
|
// Log detailed error information
|
|
log.Error("Request error",
|
|
zap.String("method", c.Method()),
|
|
zap.String("path", c.Path()),
|
|
zap.Int("status", code),
|
|
zap.Error(err),
|
|
zap.String("ip", c.IP()),
|
|
zap.String("user_agent", c.Get("User-Agent")),
|
|
)
|
|
|
|
// Log request body for failed POST/PUT/PATCH requests
|
|
if c.Method() == "POST" || c.Method() == "PUT" || c.Method() == "PATCH" {
|
|
// Re-read the body since it might have been consumed
|
|
body := c.Body()
|
|
if len(body) > 0 {
|
|
var prettyJSON bytes.Buffer
|
|
if err := json.Indent(&prettyJSON, body, "", " "); err == nil {
|
|
log.Error("Failed request body",
|
|
zap.String("body", prettyJSON.String()),
|
|
)
|
|
} else {
|
|
bodyStr := string(body)
|
|
if len(bodyStr) > 2000 {
|
|
bodyStr = bodyStr[:2000] + "... (truncated)"
|
|
}
|
|
log.Error("Failed request body",
|
|
zap.String("body", bodyStr),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return detailed error response in debug mode
|
|
return c.Status(code).JSON(fiber.Map{
|
|
"error": true,
|
|
"message": err.Error(),
|
|
"code": code,
|
|
"path": c.Path(),
|
|
"method": c.Method(),
|
|
})
|
|
}
|
|
|
|
// DebugResponseLogger logs response status for debugging
|
|
func DebugResponseLogger() fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
err := c.Next()
|
|
|
|
log := logger.Get()
|
|
status := c.Response().StatusCode()
|
|
|
|
// Log non-2xx responses with more detail
|
|
if status >= 400 {
|
|
log.Debug("Response",
|
|
zap.String("method", c.Method()),
|
|
zap.String("path", c.Path()),
|
|
zap.Int("status", status),
|
|
zap.Int("body_size", len(c.Response().Body())),
|
|
)
|
|
}
|
|
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Ensure body can be re-read for logging (use before DebugRequestBody)
|
|
func BodyReusable() fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
// Store original body so it can be read multiple times
|
|
body := c.Body()
|
|
c.Request().SetBody(body)
|
|
|
|
// Also set body reader for handlers that use io.Reader
|
|
c.Request().SetBodyStream(io.NopCloser(bytes.NewReader(body)), len(body))
|
|
|
|
return c.Next()
|
|
}
|
|
}
|