package logger import ( "cursor-api-proxy/internal/pool" "fmt" "os" "path/filepath" "strings" "time" ) const ( cReset = "\x1b[0m" cBold = "\x1b[1m" cDim = "\x1b[2m" cCyan = "\x1b[36m" cBCyan = "\x1b[1;96m" cGreen = "\x1b[32m" cBGreen = "\x1b[1;92m" cYellow = "\x1b[33m" cMagenta = "\x1b[35m" cBMagenta = "\x1b[1;95m" cRed = "\x1b[31m" cGray = "\x1b[90m" cWhite = "\x1b[97m" ) var roleStyle = map[string]string{ "system": cYellow, "user": cCyan, "assistant": cGreen, } var roleEmoji = map[string]string{ "system": "šŸ”§", "user": "šŸ‘¤", "assistant": "šŸ¤–", } func ts() string { return cGray + time.Now().UTC().Format(time.RFC3339Nano) + cReset } func truncate(s string, max int) string { if len(s) <= max { return s } head := int(float64(max) * 0.6) tail := max - head omitted := len(s) - head - tail return s[:head] + fmt.Sprintf("%s … (%d chars omitted) … ", cDim, omitted) + s[len(s)-tail:] + cReset } func hr(ch string, length int) string { return cGray + strings.Repeat(ch, length) + cReset } type TrafficMessage struct { Role string Content string } func LogIncoming(method, pathname, remoteAddress string) { fmt.Printf("[%s] Incoming: %s %s (from %s)\n", time.Now().UTC().Format(time.RFC3339), method, pathname, remoteAddress) } func LogAccountAssigned(configDir string) { if configDir == "" { return } name := filepath.Base(configDir) fmt.Printf("[%s] %s→ account%s %s%s%s\n", time.Now().UTC().Format(time.RFC3339), cBCyan, cReset, cBold, name, cReset) } func LogAccountStats(verbose bool, stats []pool.AccountStat) { if !verbose || len(stats) == 0 { return } now := time.Now().UnixMilli() fmt.Printf("%sā”Œā”€ Account Stats %s┐%s\n", cGray, strings.Repeat("─", 44), cReset) for _, s := range stats { name := fmt.Sprintf("%-20s", filepath.Base(s.ConfigDir)) active := fmt.Sprintf("%sdim%sactive:0%s", cDim, "", cReset) if s.ActiveRequests > 0 { active = fmt.Sprintf("%sactive:%d%s", cBCyan, s.ActiveRequests, cReset) } total := fmt.Sprintf("total:%s%d%s", cBold, s.TotalRequests, cReset) ok := fmt.Sprintf("%sok:%d%s", cGreen, s.TotalSuccess, cReset) errStr := fmt.Sprintf("%sdim%serr:0%s", cDim, "", cReset) if s.TotalErrors > 0 { errStr = fmt.Sprintf("%serr:%d%s", cRed, s.TotalErrors, cReset) } rl := fmt.Sprintf("%sdim%srl:0%s", cDim, "", cReset) if s.TotalRateLimits > 0 { rl = fmt.Sprintf("%srl:%d%s", cYellow, s.TotalRateLimits, cReset) } avg := "avg:-" if s.TotalRequests > 0 { avg = fmt.Sprintf("avg:%dms", s.TotalLatencyMs/int64(s.TotalRequests)) } status := fmt.Sprintf("%sāœ“%s", cGreen, cReset) if s.IsRateLimited { recovers := time.UnixMilli(s.RateLimitUntil).UTC().Format(time.RFC3339) _ = now status = fmt.Sprintf("%sā›” rate-limited (recovers %s)%s", cRed, recovers, cReset) } fmt.Printf(" %s%s%s %s %s %s %s %s %s%s%s %s\n", cBold, name, cReset, active, total, ok, errStr, rl, cDim, avg, cReset, status) } fmt.Printf("%sā””%sā”˜%s\n", cGray, strings.Repeat("─", 60), cReset) } func LogTrafficRequest(verbose bool, model string, messages []TrafficMessage, isStream bool) { if !verbose { return } modeTag := fmt.Sprintf("%sdim%ssync%s", cDim, "", cReset) if isStream { modeTag = fmt.Sprintf("%s⚔ stream%s", cBCyan, cReset) } modelStr := fmt.Sprintf("%s✦ %s%s", cBMagenta, model, cReset) fmt.Println(hr("─", 60)) fmt.Printf("%s šŸ“¤ %s%sREQUEST%s %s %s\n", ts(), cBCyan, cBold, cReset, modelStr, modeTag) for _, m := range messages { roleColor := cWhite if c, ok := roleStyle[m.Role]; ok { roleColor = c } emoji := "šŸ’¬" if e, ok := roleEmoji[m.Role]; ok { emoji = e } label := fmt.Sprintf("%s%s[%s]%s", roleColor, cBold, m.Role, cReset) charCount := fmt.Sprintf("%s(%d chars)%s", cDim, len(m.Content), cReset) preview := truncate(strings.ReplaceAll(m.Content, "\n", "↵ "), 280) fmt.Printf(" %s %s %s\n", emoji, label, charCount) fmt.Printf(" %s%s%s\n", cDim, preview, cReset) } } func LogTrafficResponse(verbose bool, model, text string, isStream bool) { if !verbose { return } modeTag := fmt.Sprintf("%sdim%ssync%s", cDim, "", cReset) if isStream { modeTag = fmt.Sprintf("%s⚔ stream%s", cBGreen, cReset) } modelStr := fmt.Sprintf("%s✦ %s%s", cBMagenta, model, cReset) charCount := fmt.Sprintf("%s%d%s%s chars%s", cBold, len(text), cReset, cDim, cReset) preview := truncate(strings.ReplaceAll(text, "\n", "↵ "), 480) fmt.Printf("%s šŸ“„ %s%sRESPONSE%s %s %s %s\n", ts(), cBGreen, cBold, cReset, modelStr, modeTag, charCount) fmt.Printf(" šŸ¤– %s%s%s\n", cGreen, preview, cReset) fmt.Println(hr("─", 60)) } func AppendSessionLine(logPath, method, pathname, remoteAddress string, statusCode int) { line := fmt.Sprintf("%s %s %s %s %d\n", time.Now().UTC().Format(time.RFC3339), method, pathname, remoteAddress, statusCode) dir := filepath.Dir(logPath) if err := os.MkdirAll(dir, 0755); err == nil { f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err == nil { _, _ = f.WriteString(line) f.Close() } } } func LogAgentError(logPath, method, pathname, remoteAddress string, exitCode int, stderr string) string { errMsg := fmt.Sprintf("Cursor CLI failed (exit %d): %s", exitCode, strings.TrimSpace(stderr)) fmt.Fprintf(os.Stderr, "[%s] Agent error: %s\n", time.Now().UTC().Format(time.RFC3339), errMsg) truncated := strings.TrimSpace(stderr) if len(truncated) > 200 { truncated = truncated[:200] } truncated = strings.ReplaceAll(truncated, "\n", " ") line := fmt.Sprintf("%s ERROR %s %s %s agent_exit_%d %s\n", time.Now().UTC().Format(time.RFC3339), method, pathname, remoteAddress, exitCode, truncated) if f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil { _, _ = f.WriteString(line) f.Close() } return errMsg }