From 578e68a76b5e242a5a163dd6c937e72a86bc4d6c Mon Sep 17 00:00:00 2001 From: Mrx <18278715334@163.com> Date: Thu, 5 Mar 2026 11:05:01 +0800 Subject: [PATCH] f --- .../processors/ivyz/ivyzocr2_processor.go | 4 +- .../external/shujubao/shujubao_service.go | 50 +++++++++++++-- .../external/shumai/shumai_service.go | 62 +++++++++++++++---- 3 files changed, 97 insertions(+), 19 deletions(-) diff --git a/internal/domains/api/services/processors/ivyz/ivyzocr2_processor.go b/internal/domains/api/services/processors/ivyz/ivyzocr2_processor.go index a421e76..250c2e1 100644 --- a/internal/domains/api/services/processors/ivyz/ivyzocr2_processor.go +++ b/internal/domains/api/services/processors/ivyz/ivyzocr2_processor.go @@ -10,7 +10,7 @@ import ( "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) { var paramsDto dto.IVYZOCR1Req if err := json.Unmarshal(params, ¶msDto); err != nil { @@ -20,7 +20,7 @@ func ProcessIVYZOCR2Request(ctx context.Context, params []byte, deps *processors if err := deps.Validator.ValidateStruct(paramsDto); err != nil { return nil, errors.Join(processors.ErrInvalidParam, err) } - + if paramsDto.PhotoData == "" && paramsDto.ImageUrl == "" { return nil, errors.Join(processors.ErrInvalidParam, errors.New("photo_data or image_url is required")) } diff --git a/internal/infrastructure/external/shujubao/shujubao_service.go b/internal/infrastructure/external/shujubao/shujubao_service.go index 1c900a8..86afebc 100644 --- a/internal/infrastructure/external/shujubao/shujubao_service.go +++ b/internal/infrastructure/external/shujubao/shujubao_service.go @@ -17,12 +17,50 @@ import ( "tyapi-server/internal/shared/external_logger" ) +const ( + // 错误日志中单条入参值的最大长度,避免 base64 等长内容打满日志 + maxLogParamValueLen = 300 +) + var ( ErrDatasource = errors.New("数据源异常") ErrSystem = 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 通用响应(按实际文档调整) type ShujubaoResp struct { Code string `json:"code"` @@ -187,7 +225,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma if err != nil { err = errors.Join(ErrSystem, err) if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiPath, err, params) + s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params)) } return nil, err } @@ -216,7 +254,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma err = errors.Join(ErrSystem, err) } if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiPath, err, params) + s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params)) } return nil, err } @@ -226,7 +264,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma if err != nil { err = errors.Join(ErrSystem, err) if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiPath, err, params) + s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params)) } return nil, err } @@ -239,7 +277,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma if response.StatusCode != http.StatusOK { err = errors.Join(ErrDatasource, fmt.Errorf("HTTP状态码 %d", response.StatusCode)) if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiPath, err, params) + s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params)) } 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 { err = errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err)) if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiPath, err, params) + s.logger.LogError(requestID, transactionID, apiPath, err, paramsForLog(params)) } return nil, err } @@ -261,7 +299,7 @@ func (s *ShujubaoService) CallAPI(ctx context.Context, apiPath string, params ma if code != "10000" { shujubaoErr := NewShujubaoErrorFromCode(code, shujubaoResp.Message) 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) } diff --git a/internal/infrastructure/external/shumai/shumai_service.go b/internal/infrastructure/external/shumai/shumai_service.go index 5adcdf4..7d2ed48 100644 --- a/internal/infrastructure/external/shumai/shumai_service.go +++ b/internal/infrastructure/external/shumai/shumai_service.go @@ -16,12 +16,52 @@ import ( "tyapi-server/internal/shared/external_logger" ) +const ( + // 错误日志中单条入参值的最大长度,避免 base64 等长内容打满日志 + maxLogParamValueLen = 300 + // 错误日志中 response_body 的最大长度 + maxLogResponseBodyLen = 500 +) + var ( ErrDatasource = errors.New("数据源异常") ErrSystem = 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 通用响应(占位,按实际文档调整) type ShumaiResponse struct { Code int `json:"code"` // 状态码 @@ -188,7 +228,7 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm if err != nil { err = errors.Join(ErrSystem, err) 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 } @@ -216,7 +256,7 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm err = errors.Join(ErrSystem, err) } 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 } @@ -227,7 +267,7 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm if err != nil { err = errors.Join(ErrSystem, err) 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 } @@ -236,8 +276,8 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm err = errors.Join(ErrDatasource, fmt.Errorf("HTTP %d", resp.StatusCode)) if s.logger != nil { errorPayload := map[string]interface{}{ - "request_params": reqFormData, - "response_body": string(raw), + "request_params": requestParamsForLog(reqFormData), + "response_body": truncateForLog(string(raw), maxLogResponseBodyLen), } 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)) if s.logger != nil { s.logger.LogError(requestID, transactionID, apiPath, parseErr, map[string]interface{}{ - "request_params": reqFormData, - "response_body": string(raw), + "request_params": requestParamsForLog(reqFormData), + "response_body": truncateForLog(string(raw), maxLogResponseBodyLen), }) } return nil, parseErr @@ -273,8 +313,8 @@ func (s *ShumaiService) CallAPIForm(ctx context.Context, apiPath string, reqForm } if s.logger != nil { s.logger.LogError(requestID, transactionID, apiPath, shumaiErr, map[string]interface{}{ - "request_params": reqFormData, - "response_body": string(raw), + "request_params": requestParamsForLog(reqFormData), + "response_body": truncateForLog(string(raw), maxLogResponseBodyLen), }) } 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)) if s.logger != nil { s.logger.LogError(requestID, transactionID, apiPath, marshalErr, map[string]interface{}{ - "request_params": reqFormData, - "response_body": string(raw), + "request_params": requestParamsForLog(reqFormData), + "response_body": truncateForLog(string(raw), maxLogResponseBodyLen), }) } return nil, marshalErr