Files
tyapi-server/internal/infrastructure/external/yuyuecha/debug_exchange.go
2026-07-25 14:18:14 +08:00

108 lines
2.4 KiB
Go

package yuyuecha
import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
const debugExchangeFileName = "dev_curl.log"
var debugExchangeMu sync.Mutex
type debugExchangeRecord struct {
RequestID string
TransactionID string
API string
Status int
Duration time.Duration
Curl string
ResponseBody []byte
Error string
}
// writeDebugExchange 开发环境写入单一排查文件:一次调用一条记录,含 curl + response
func writeDebugExchange(logDir string, rec debugExchangeRecord) {
if strings.TrimSpace(logDir) == "" || strings.TrimSpace(rec.Curl) == "" {
return
}
var b strings.Builder
b.WriteString(strings.Repeat("=", 72))
b.WriteByte('\n')
b.WriteString("time: ")
b.WriteString(time.Now().Format("2006-01-02 15:04:05.000"))
b.WriteByte('\n')
b.WriteString("request_id: ")
b.WriteString(rec.RequestID)
b.WriteByte('\n')
// 与上游签名头 nonce 一致,对外排查只提供 request_id 即可
b.WriteString("nonce: ")
b.WriteString(rec.RequestID)
b.WriteByte('\n')
if rec.TransactionID != "" {
b.WriteString("transaction_id: ")
b.WriteString(rec.TransactionID)
b.WriteByte('\n')
}
b.WriteString("api: ")
b.WriteString(rec.API)
b.WriteByte('\n')
if rec.Status > 0 {
b.WriteString(fmt.Sprintf("status: %d\n", rec.Status))
}
b.WriteString(fmt.Sprintf("duration: %s\n", rec.Duration.Round(time.Millisecond)))
if rec.Error != "" {
b.WriteString("error: ")
b.WriteString(rec.Error)
b.WriteByte('\n')
}
b.WriteByte('\n')
b.WriteString("[curl]\n")
b.WriteString(rec.Curl)
b.WriteByte('\n')
b.WriteByte('\n')
b.WriteString("[response]\n")
if len(rec.ResponseBody) == 0 {
b.WriteString("(empty)\n")
} else {
b.WriteString(prettyJSONForLog(rec.ResponseBody))
b.WriteByte('\n')
}
b.WriteString(strings.Repeat("=", 72))
b.WriteString("\n\n")
debugExchangeMu.Lock()
defer debugExchangeMu.Unlock()
if err := os.MkdirAll(logDir, 0755); err != nil {
return
}
path := filepath.Join(logDir, debugExchangeFileName)
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return
}
defer f.Close()
_, _ = f.WriteString(b.String())
}
func prettyJSONForLog(raw []byte) string {
trimmed := bytes.TrimSpace(raw)
if len(trimmed) == 0 {
return "(empty)"
}
var buf bytes.Buffer
if err := json.Indent(&buf, trimmed, "", " "); err != nil {
return string(raw)
}
return buf.String()
}