This commit is contained in:
Mrx
2026-06-04 15:01:15 +08:00
parent f08a940807
commit 4b78edc071

View File

@@ -3,7 +3,6 @@ package jiguang
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/md5"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@@ -88,20 +87,12 @@ func NewJiguangService(url, appID, appSecret string, signMethod SignMethod, time
} }
} }
// generateRequestID 生成请求ID
func (j *JiguangService) generateRequestID() string {
timestamp := time.Now().UnixNano()
hash := md5.Sum([]byte(fmt.Sprintf("%d_%s", timestamp, j.config.AppID)))
return fmt.Sprintf("jiguang_%x", hash[:8])
}
// CallAPI 调用极光API // CallAPI 调用极光API
// apiCode: API服务编码如 marriage-single-v2用于请求头 // apiCode: API服务编码如 marriage-single-v2用于请求头
// apiPath: API路径如 marriage/single-v2用于URL路径 // apiPath: API路径如 marriage/single-v2用于URL路径
// params: 请求参数会作为JSON body发送 // params: 请求参数会作为JSON body发送
func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath string, params map[string]interface{}) (resp []byte, err error) { func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath string, params map[string]interface{}) (resp []byte, err error) {
startTime := time.Now() startTime := time.Now()
requestID := j.generateRequestID()
// 生成时间戳(毫秒) // 生成时间戳(毫秒)
timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10) timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
@@ -117,7 +108,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
if signErr != nil { if signErr != nil {
err = errors.Join(ErrSystem, fmt.Errorf("生成签名失败: %w", signErr)) err = errors.Join(ErrSystem, fmt.Errorf("生成签名失败: %w", signErr))
if j.logger != nil { if j.logger != nil {
j.logger.LogError(requestID, transactionID, apiCode, err, params) j.logger.LogError("", transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }
@@ -125,17 +116,12 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
// 构建完整的请求URL使用apiPath作为路径 // 构建完整的请求URL使用apiPath作为路径
requestURL := strings.TrimSuffix(j.config.URL, "/") + "/" + strings.TrimPrefix(apiPath, "/") requestURL := strings.TrimSuffix(j.config.URL, "/") + "/" + strings.TrimPrefix(apiPath, "/")
// 记录请求日志
if j.logger != nil {
j.logger.LogRequest(requestID, transactionID, apiCode, requestURL)
}
// 将请求参数转换为JSON // 将请求参数转换为JSON
jsonData, marshalErr := json.Marshal(params) jsonData, marshalErr := json.Marshal(params)
if marshalErr != nil { if marshalErr != nil {
err = errors.Join(ErrSystem, marshalErr) err = errors.Join(ErrSystem, marshalErr)
if j.logger != nil { if j.logger != nil {
j.logger.LogError(requestID, transactionID, apiCode, err, params) j.logger.LogError("", transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }
@@ -145,7 +131,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
if newRequestErr != nil { if newRequestErr != nil {
err = errors.Join(ErrSystem, newRequestErr) err = errors.Join(ErrSystem, newRequestErr)
if j.logger != nil { if j.logger != nil {
j.logger.LogError(requestID, transactionID, apiCode, err, params) j.logger.LogError("", transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }
@@ -185,7 +171,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
err = errors.Join(ErrSystem, clientDoErr) err = errors.Join(ErrSystem, clientDoErr)
} }
if j.logger != nil { if j.logger != nil {
j.logger.LogError(requestID, transactionID, apiCode, err, params) j.logger.LogError("", transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }
@@ -194,7 +180,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
if closeErr != nil { if closeErr != nil {
// 记录关闭错误 // 记录关闭错误
if j.logger != nil { if j.logger != nil {
j.logger.LogError(requestID, transactionID, apiCode, errors.Join(ErrSystem, fmt.Errorf("关闭响应体失败: %w", closeErr)), params) j.logger.LogError("", transactionID, apiCode, errors.Join(ErrSystem, fmt.Errorf("关闭响应体失败: %w", closeErr)), params)
} }
} }
}(httpResp.Body) }(httpResp.Body)
@@ -207,7 +193,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
if readErr != nil { if readErr != nil {
err = errors.Join(ErrSystem, readErr) err = errors.Join(ErrSystem, readErr)
if j.logger != nil { if j.logger != nil {
j.logger.LogError(requestID, transactionID, apiCode, err, params) j.logger.LogError("", transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }
@@ -216,7 +202,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
if httpResp.StatusCode != http.StatusOK { if httpResp.StatusCode != http.StatusOK {
err = errors.Join(ErrSystem, fmt.Errorf("极光请求失败,状态码: %d", httpResp.StatusCode)) err = errors.Join(ErrSystem, fmt.Errorf("极光请求失败,状态码: %d", httpResp.StatusCode))
if j.logger != nil { if j.logger != nil {
j.logger.LogError(requestID, transactionID, apiCode, err, params) j.logger.LogError("", transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }
@@ -226,20 +212,20 @@ 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("", transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }
jiguangResp.normalize() jiguangResp.normalize()
// 记录响应日志(不记录具体响应数据) // order_id 为极光侧请求唯一标识,作为日志 request_id
requestID := jiguangResp.OrderID
// 记录请求/响应日志(不记录具体响应数据)
if j.logger != nil { if j.logger != nil {
if jiguangResp.OrderID != "" { j.logger.LogRequest(requestID, transactionID, apiCode, requestURL)
j.logger.LogResponseWithID(requestID, transactionID, apiCode, httpResp.StatusCode, duration, jiguangResp.OrderID)
} else {
j.logger.LogResponse(requestID, transactionID, apiCode, httpResp.StatusCode, duration) j.logger.LogResponse(requestID, transactionID, apiCode, httpResp.StatusCode, duration)
} }
}
// 检查业务状态码 // 检查业务状态码
if jiguangResp.Code != 0 && jiguangResp.Code != 200 { if jiguangResp.Code != 0 && jiguangResp.Code != 200 {
@@ -272,13 +258,13 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
} }
// 记录错误日志 // 记录错误日志
if j.logger != nil { if j.logger != nil {
j.logger.LogErrorWithResponseID(requestID, transactionID, apiCode, jiguangErr, params, jiguangResp.OrderID) j.logger.LogError(requestID, transactionID, apiCode, jiguangErr, params)
} }
return nil, errors.Join(ErrNotFound, jiguangErr) return nil, errors.Join(ErrNotFound, jiguangErr)
} }
// 记录错误日志(查无记录的情况不记录错误日志) // 记录错误日志(查无记录的情况不记录错误日志)
if j.logger != nil { if j.logger != nil {
j.logger.LogErrorWithResponseID(requestID, transactionID, apiCode, jiguangErr, params, jiguangResp.OrderID) j.logger.LogError(requestID, transactionID, apiCode, jiguangErr, params)
} }
if jiguangErr.IsQueryFailed() { if jiguangErr.IsQueryFailed() {
return nil, errors.Join(ErrDatasource, jiguangErr) return nil, errors.Join(ErrDatasource, jiguangErr)
@@ -302,7 +288,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath st
if err != nil { if 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.LogErrorWithResponseID(requestID, transactionID, apiCode, err, params, jiguangResp.OrderID) j.logger.LogError(requestID, transactionID, apiCode, err, params)
} }
return nil, err return nil, err
} }