f
This commit is contained in:
@@ -16,12 +16,28 @@ import (
|
|||||||
"tyapi-server/internal/shared/external_logger"
|
"tyapi-server/internal/shared/external_logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 错误/响应日志中单条响应内容的最大长度,避免过长内容打满日志
|
||||||
|
maxLogResponseBodyLen = 500
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrDatasource = errors.New("数据源异常")
|
ErrDatasource = errors.New("数据源异常")
|
||||||
ErrSystem = errors.New("系统异常")
|
ErrSystem = errors.New("系统异常")
|
||||||
ErrNotFound = errors.New("查询为空")
|
ErrNotFound = errors.New("查询为空")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// truncateForLog 将字符串截断到指定长度,用于日志中记录响应内容
|
||||||
|
func truncateForLog(s string, maxLen int) string {
|
||||||
|
if maxLen <= 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if len(s) <= maxLen {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return s[:maxLen] + fmt.Sprintf("...[truncated, total %d chars]", len(s))
|
||||||
|
}
|
||||||
|
|
||||||
// JiguangResponse 极光API响应结构
|
// JiguangResponse 极光API响应结构
|
||||||
type JiguangResponse struct {
|
type JiguangResponse struct {
|
||||||
Code int `json:"code"`
|
Code int `json:"code"`
|
||||||
@@ -207,17 +223,24 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
|
|||||||
if err := json.Unmarshal(bodyBytes, &jiguangResp); err != nil {
|
if err := json.Unmarshal(bodyBytes, &jiguangResp); err != nil {
|
||||||
err = errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err))
|
err = errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err))
|
||||||
if j.logger != nil {
|
if j.logger != nil {
|
||||||
j.logger.LogError(requestID, transactionID, apiCode, err, params)
|
// 解析失败时也记录响应原文(截断后)
|
||||||
|
j.logger.LogError(requestID, transactionID, apiCode, err, map[string]interface{}{
|
||||||
|
"params": params,
|
||||||
|
"response_body": truncateForLog(string(bodyBytes), maxLogResponseBodyLen),
|
||||||
|
"status_code": httpResp.StatusCode,
|
||||||
|
"response_ttlms": duration.Milliseconds(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录响应日志(不记录具体响应数据)
|
// 记录响应日志,同时记录截断后的响应内容
|
||||||
if j.logger != nil {
|
if j.logger != nil {
|
||||||
|
truncatedBody := truncateForLog(string(bodyBytes), maxLogResponseBodyLen)
|
||||||
if jiguangResp.OrderID != "" {
|
if jiguangResp.OrderID != "" {
|
||||||
j.logger.LogResponseWithID(requestID, transactionID, apiCode, httpResp.StatusCode, duration, jiguangResp.OrderID)
|
j.logger.LogResponseWithIDAndBody(requestID, transactionID, apiCode, httpResp.StatusCode, duration, jiguangResp.OrderID, truncatedBody)
|
||||||
} else {
|
} else {
|
||||||
j.logger.LogResponse(requestID, transactionID, apiCode, httpResp.StatusCode, duration)
|
j.logger.LogResponseWithBody(requestID, transactionID, apiCode, httpResp.StatusCode, duration, truncatedBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -345,6 +345,43 @@ func (e *ExternalServiceLogger) LogResponseWithID(requestID, transactionID, apiC
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogResponseWithBody 记录包含响应内容的响应日志
|
||||||
|
func (e *ExternalServiceLogger) LogResponseWithBody(requestID, transactionID, apiCode string, statusCode int, duration time.Duration, responseBody string) {
|
||||||
|
logger := e.responseLogger
|
||||||
|
if logger == nil {
|
||||||
|
logger = e.logger
|
||||||
|
}
|
||||||
|
logger.Info(fmt.Sprintf("%s API响应", e.serviceName),
|
||||||
|
zap.String("service", e.serviceName),
|
||||||
|
zap.String("request_id", requestID),
|
||||||
|
zap.String("transaction_id", transactionID),
|
||||||
|
zap.String("api_code", apiCode),
|
||||||
|
zap.Int("status_code", statusCode),
|
||||||
|
zap.Duration("duration", duration),
|
||||||
|
zap.String("response_body", responseBody),
|
||||||
|
zap.String("timestamp", time.Now().Format(time.RFC3339)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogResponseWithIDAndBody 记录包含响应ID和响应内容的响应日志
|
||||||
|
func (e *ExternalServiceLogger) LogResponseWithIDAndBody(requestID, transactionID, apiCode string, statusCode int, duration time.Duration, responseID string, responseBody string) {
|
||||||
|
logger := e.responseLogger
|
||||||
|
if logger == nil {
|
||||||
|
logger = e.logger
|
||||||
|
}
|
||||||
|
logger.Info(fmt.Sprintf("%s API响应", e.serviceName),
|
||||||
|
zap.String("service", e.serviceName),
|
||||||
|
zap.String("request_id", requestID),
|
||||||
|
zap.String("transaction_id", transactionID),
|
||||||
|
zap.String("api_code", apiCode),
|
||||||
|
zap.Int("status_code", statusCode),
|
||||||
|
zap.Duration("duration", duration),
|
||||||
|
zap.String("response_id", responseID),
|
||||||
|
zap.String("response_body", responseBody),
|
||||||
|
zap.String("timestamp", time.Now().Format(time.RFC3339)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// LogError 记录错误日志
|
// LogError 记录错误日志
|
||||||
func (e *ExternalServiceLogger) LogError(requestID, transactionID, apiCode string, err error, params interface{}) {
|
func (e *ExternalServiceLogger) LogError(requestID, transactionID, apiCode string, err error, params interface{}) {
|
||||||
e.logger.Error(fmt.Sprintf("%s API错误", e.serviceName),
|
e.logger.Error(fmt.Sprintf("%s API错误", e.serviceName),
|
||||||
|
|||||||
Reference in New Issue
Block a user