This commit is contained in:
Mrx
2026-03-05 11:05:01 +08:00
parent 019e47896d
commit 578e68a76b
3 changed files with 97 additions and 19 deletions

View File

@@ -10,7 +10,7 @@ import (
"tyapi-server/internal/infrastructure/external/shumai" "tyapi-server/internal/infrastructure/external/shumai"
) )
// ProcessIVYZOCR2Request IVYZOCR2 OCR识别API处理方法 // ProcessIVYZOCR2Request IVYZOCR2 OCR识别API处理方法数卖
func ProcessIVYZOCR2Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { func ProcessIVYZOCR2Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZOCR1Req var paramsDto dto.IVYZOCR1Req
if err := json.Unmarshal(params, &paramsDto); err != nil { if err := json.Unmarshal(params, &paramsDto); err != nil {

View File

@@ -17,12 +17,50 @@ import (
"tyapi-server/internal/shared/external_logger" "tyapi-server/internal/shared/external_logger"
) )
const (
// 错误日志中单条入参值的最大长度,避免 base64 等长内容打满日志
maxLogParamValueLen = 300
)
var ( var (
ErrDatasource = errors.New("数据源异常") ErrDatasource = errors.New("数据源异常")
ErrSystem = errors.New("系统异常") ErrSystem = errors.New("系统异常")
ErrQueryEmpty = errors.New("查询为空") ErrQueryEmpty = errors.New("查询为空")
) )
// truncateForLog 将字符串截断到指定长度,用于错误日志,避免 base64 等过长内容
func truncateForLog(s string, maxLen int) string {
if maxLen <= 0 {
return s
}
if len(s) <= maxLen {
return s
}
return s[:maxLen] + "...[truncated, total " + strconv.Itoa(len(s)) + " chars]"
}
// paramsForLog 返回适合写入错误日志的入参副本(长字符串会被截断)
func paramsForLog(params map[string]interface{}) map[string]interface{} {
if params == nil {
return nil
}
out := make(map[string]interface{}, len(params))
for k, v := range params {
if v == nil {
out[k] = nil
continue
}
switch val := v.(type) {
case string:
out[k] = truncateForLog(val, maxLogParamValueLen)
default:
s := fmt.Sprint(v)
out[k] = truncateForLog(s, maxLogParamValueLen)
}
}
return out
}
// ShujubaoResp 数据宝 API 通用响应(按实际文档调整) // ShujubaoResp 数据宝 API 通用响应(按实际文档调整)
type ShujubaoResp struct { type ShujubaoResp struct {
Code string `json:"code"` Code string `json:"code"`
@@ -187,7 +225,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma
if err != nil { if err != nil {
err = errors.Join(ErrSystem, err) err = errors.Join(ErrSystem, err)
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, params) s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params))
} }
return nil, err return nil, err
} }
@@ -216,7 +254,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma
err = errors.Join(ErrSystem, err) err = errors.Join(ErrSystem, err)
} }
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, params) s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params))
} }
return nil, err return nil, err
} }
@@ -226,7 +264,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma
if err != nil { if err != nil {
err = errors.Join(ErrSystem, err) err = errors.Join(ErrSystem, err)
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, params) s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params))
} }
return nil, err return nil, err
} }
@@ -239,7 +277,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma
if response.StatusCode != http.StatusOK { if response.StatusCode != http.StatusOK {
err = errors.Join(ErrDatasource, fmt.Errorf("HTTP状态码 %d", response.StatusCode)) err = errors.Join(ErrDatasource, fmt.Errorf("HTTP状态码 %d", response.StatusCode))
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, params) s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params))
} }
return nil, err return nil, err
} }
@@ -248,7 +286,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma
if err := json.Unmarshal(respBody, &shujubaoResp); err != nil { if err := json.Unmarshal(respBody, &shujubaoResp); err != nil {
err = errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err)) err = errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err))
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, params) s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params))
} }
return nil, err return nil, err
} }
@@ -261,7 +299,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma
if code != "10000" { if code != "10000" {
shujubaoErr := NewShujubaoErrorFromCode(code, shujubaoResp.Message) shujubaoErr := NewShujubaoErrorFromCode(code, shujubaoResp.Message)
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, shujubaoErr, params) s.logger.LogError(requestID, transactionID, apiPath, shujubaoErr, paramsForLog(params))
} }
return nil, errors.Join(ErrDatasource, shujubaoErr) return nil, errors.Join(ErrDatasource, shujubaoErr)
} }

View File

@@ -16,12 +16,52 @@ import (
"tyapi-server/internal/shared/external_logger" "tyapi-server/internal/shared/external_logger"
) )
const (
// 错误日志中单条入参值的最大长度,避免 base64 等长内容打满日志
maxLogParamValueLen = 300
// 错误日志中 response_body 的最大长度
maxLogResponseBodyLen = 500
)
var ( var (
ErrDatasource = errors.New("数据源异常") ErrDatasource = errors.New("数据源异常")
ErrSystem = errors.New("系统异常") ErrSystem = errors.New("系统异常")
ErrNotFound = errors.New("查询为空") ErrNotFound = errors.New("查询为空")
) )
// truncateForLog 将字符串截断到指定长度,用于错误日志,避免 base64 等过长内容
func truncateForLog(s string, maxLen int) string {
if maxLen <= 0 {
return s
}
if len(s) <= maxLen {
return s
}
return s[:maxLen] + "...[truncated, total " + strconv.Itoa(len(s)) + " chars]"
}
// requestParamsForLog 返回适合写入错误日志的入参副本(长字符串会被截断)
func requestParamsForLog(reqFormData map[string]interface{}) map[string]interface{} {
if reqFormData == nil {
return nil
}
out := make(map[string]interface{}, len(reqFormData))
for k, v := range reqFormData {
if v == nil {
out[k] = nil
continue
}
switch val := v.(type) {
case string:
out[k] = truncateForLog(val, maxLogParamValueLen)
default:
s := fmt.Sprint(v)
out[k] = truncateForLog(s, maxLogParamValueLen)
}
}
return out
}
// ShumaiResponse 数脉 API 通用响应(占位,按实际文档调整) // ShumaiResponse 数脉 API 通用响应(占位,按实际文档调整)
type ShumaiResponse struct { type ShumaiResponse struct {
Code int `json:"code"` // 状态码 Code int `json:"code"` // 状态码
@@ -188,7 +228,7 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm
if err != nil { if err != nil {
err = errors.Join(ErrSystem, err) err = errors.Join(ErrSystem, err)
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, map[string]interface{}{"request_params": reqFormData}) s.logger.LogError(requestID, transactionID, apiPath, err, map[string]interface{}{"request_params": requestParamsForLog(reqFormData)})
} }
return nil, err return nil, err
} }
@@ -216,7 +256,7 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm
err = errors.Join(ErrSystem, err) err = errors.Join(ErrSystem, err)
} }
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, map[string]interface{}{"request_params": reqFormData}) s.logger.LogError(requestID, transactionID, apiPath, err, map[string]interface{}{"request_params": requestParamsForLog(reqFormData)})
} }
return nil, err return nil, err
} }
@@ -227,7 +267,7 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm
if err != nil { if err != nil {
err = errors.Join(ErrSystem, err) err = errors.Join(ErrSystem, err)
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, err, map[string]interface{}{"request_params": reqFormData}) s.logger.LogError(requestID, transactionID, apiPath, err, map[string]interface{}{"request_params": requestParamsForLog(reqFormData)})
} }
return nil, err return nil, err
} }
@@ -236,8 +276,8 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm
err = errors.Join(ErrDatasource, fmt.Errorf("HTTP %d", resp.StatusCode)) err = errors.Join(ErrDatasource, fmt.Errorf("HTTP %d", resp.StatusCode))
if s.logger != nil { if s.logger != nil {
errorPayload := map[string]interface{}{ errorPayload := map[string]interface{}{
"request_params": reqFormData, "request_params": requestParamsForLog(reqFormData),
"response_body": string(raw), "response_body": truncateForLog(string(raw), maxLogResponseBodyLen),
} }
s.logger.LogError(requestID, transactionID, apiPath, err, errorPayload) s.logger.LogError(requestID, transactionID, apiPath, err, errorPayload)
} }
@@ -253,8 +293,8 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm
parseErr := errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err)) parseErr := errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err))
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, parseErr, map[string]interface{}{ s.logger.LogError(requestID, transactionID, apiPath, parseErr, map[string]interface{}{
"request_params": reqFormData, "request_params": requestParamsForLog(reqFormData),
"response_body": string(raw), "response_body": truncateForLog(string(raw), maxLogResponseBodyLen),
}) })
} }
return nil, parseErr return nil, parseErr
@@ -273,8 +313,8 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm
} }
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, shumaiErr, map[string]interface{}{ s.logger.LogError(requestID, transactionID, apiPath, shumaiErr, map[string]interface{}{
"request_params": reqFormData, "request_params": requestParamsForLog(reqFormData),
"response_body": string(raw), "response_body": truncateForLog(string(raw), maxLogResponseBodyLen),
}) })
} }
if shumaiErr.IsNoRecord() { if shumaiErr.IsNoRecord() {
@@ -292,8 +332,8 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm
marshalErr := errors.Join(ErrSystem, fmt.Errorf("data 序列化失败: %w", err)) marshalErr := errors.Join(ErrSystem, fmt.Errorf("data 序列化失败: %w", err))
if s.logger != nil { if s.logger != nil {
s.logger.LogError(requestID, transactionID, apiPath, marshalErr, map[string]interface{}{ s.logger.LogError(requestID, transactionID, apiPath, marshalErr, map[string]interface{}{
"request_params": reqFormData, "request_params": requestParamsForLog(reqFormData),
"response_body": string(raw), "response_body": truncateForLog(string(raw), maxLogResponseBodyLen),
}) })
} }
return nil, marshalErr return nil, marshalErr