|
|
package middleware |
|
|
|
|
|
import ( |
|
|
"bytes" |
|
|
"io" |
|
|
"strings" |
|
|
|
|
|
"github.com/gin-gonic/gin" |
|
|
log "github.com/sirupsen/logrus" |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
func LogAnthropicRequest() gin.HandlerFunc { |
|
|
return func(c *gin.Context) { |
|
|
path := c.Request.URL.Path |
|
|
method := c.Request.Method |
|
|
userAgent := c.GetHeader("User-Agent") |
|
|
|
|
|
|
|
|
isClaudeCode := strings.Contains(userAgent, "claude-code") || strings.Contains(userAgent, "claude-cli") |
|
|
|
|
|
fields := log.Fields{ |
|
|
"prefix": "CLAUDE_CODE_AUTH_DEBUG", |
|
|
"method": method, |
|
|
"path": path, |
|
|
"user_agent": userAgent, |
|
|
"is_claude_code": isClaudeCode, |
|
|
} |
|
|
|
|
|
|
|
|
headers := make(map[string]string) |
|
|
for k, v := range c.Request.Header { |
|
|
if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "x-api-key") { |
|
|
headers[k] = "[MASKED]" |
|
|
} else { |
|
|
headers[k] = strings.Join(v, ";") |
|
|
} |
|
|
} |
|
|
fields["headers"] = headers |
|
|
|
|
|
|
|
|
var bodyBytes []byte |
|
|
if c.Request.Body != nil { |
|
|
bodyBytes, _ = io.ReadAll(c.Request.Body) |
|
|
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) |
|
|
|
|
|
previewLen := 200 |
|
|
if len(bodyBytes) < previewLen { |
|
|
previewLen = len(bodyBytes) |
|
|
} |
|
|
fields["body_preview"] = string(bodyBytes[:previewLen]) |
|
|
} |
|
|
|
|
|
log.WithFields(fields).Debug("Incoming Anthropic Request") |
|
|
|
|
|
c.Next() |
|
|
} |
|
|
} |
|
|
|