9.4 KiB
天元API调用记录功能 - 实施总结
功能概述
本功能实现了天元API调用的成本记录,包括:
- 在
feature表添加cost_price字段,存储每个接口的成本价 - 创建
tianyuanapi_call_log表,记录每次API调用的详细信息 - 无论成功失败都记录,但只有成功调用才计算成本
- 提供统计功能,可查询时间段内的调用次数和总成本
已完成的工作
1. 数据库层面 ✅
文件: ycc-proxy-server/deploy/sql/tianyuanapi_cost_migration.sql
修改内容:
- 在
feature表添加cost_price字段(decimal(10, 2),默认0.00) - 创建
tianyuanapi_call_log表,包含以下字段:feature_id: 关联feature表api_id: 天元API标识(如:YYSYBE08)order_id: 关联订单(可选)query_id: 关联查询(可选)call_status: 调用状态(0=失败,1=成功)call_time: 调用时间response_time: 响应耗时(毫秒)cost_price: 本次调用成本(成功时有值,失败为0)error_code: 错误码(失败时)error_message: 错误信息(失败时)request_params: 请求参数(JSON)response_data: 响应数据(JSON,截取前1000字符)transaction_id: 天元API流水号
索引设计:
idx_feature_id: 按feature_id查询idx_api_id: 按api_id查询idx_order_id: 按order_id查询idx_query_id: 按query_id查询idx_call_status: 按调用状态查询idx_call_time: 按调用时间查询idx_feature_time: 复合索引(feature_id + call_time)
2. Service层面 ✅
文件: ycc-proxy-server/app/main/api/internal/service/tianyuanapiCallLogService.go
新增方法:
-
RecordCall(ctx context.Context, opts CallLogOptions) error- 记录API调用
- 自动获取feature的成本价
- 成功时记录成本,失败时成本为0
- 异步记录,不影响主流程
-
GetStatistics(ctx context.Context, filter StatisticsFilter) (*Statistics, error)- 获取统计信息
- 支持按feature_id、api_id、时间范围过滤
- 返回:总调用次数、成功次数、失败次数、总成本
3. ApiRequestService修改 ✅
文件: ycc-proxy-server/app/main/api/internal/service/apirequestService.go
新增字段:
tianyuanapiCallLogService *TianyuanapiCallLogServiceapiFeatureMapCache map[string]string- apiID到featureID的缓存apiFeatureMapMutex sync.RWMutex- 缓存读写锁
新增方法:
-
callTianyuanApiWithLog(ctx context.Context, featureID, apiID string, params map[string]interface{}) (*tianyuanapi.Response, error)- 调用天元API
- 记录调用开始时间
- 计算响应耗时
- 异步记录调用日志
- 返回响应和错误
-
在
ProcessRequests方法中构建apiID -> featureID映射缓存
修改的方法(示例):
ProcessYYSYBE08Request- 已修改ProcessFLXG0V4BRequest- 已修改
待修改的方法(30个):
剩余30个方法需要将 a.callTianyuanApiWithLog(ctx, "", "API名称", ...)
替换为 a.callTianyuanApiWithLog(ctx, "", "API名称", ...)
详细列表见:批量替换API调用说明.md
4. ServiceContext修改 ✅
文件: ycc-proxy-server/app/main/api/internal/svc/servicecontext.go
新增模型:
TianyuanapiCallLogModel model.TianyuanapiCallLogModel
TianyuanapiCallLogService *service.TianyuanapiCallLogService
新增初始化:
tianyuanapiCallLogModel := model.NewTianyuanapiCallLogModel(db, cacheConf)
tianyuanapiCallLogService := service.NewTianyuanapiCallLogService(tianyuanapiCallLogModel, featureModel)
修改ApiRequestService初始化:
apiRequestService := service.NewApiRequestService(
c,
featureModel,
productFeatureModel,
userFeatureWhitelistModel,
tianyuanapi,
tianyuanapiCallLogService, // 新增参数
)
5. Model生成脚本 ✅
文件: ycc-proxy-server/deploy/sql/generate_tianyuanapi_models.sh
功能:
- 生成
feature表的Model(已更新,包含cost_price字段) - 生成
tianyuanapi_call_log表的Model
6. 文档 ✅
已创建的文档:
天元API调用记录修改说明.md- 详细的修改步骤和示例批量替换API调用说明.md- 批量修改API调用方法的指南
待完成的工作
1. 执行SQL脚本 ⏳
# 在数据库中执行迁移脚本
mysql -u root -p ycc < ycc-proxy-server/deploy/sql/tianyuanapi_cost_migration.sql
2. 生成Model代码 ⏳
cd ycc-proxy-server/deploy/sql
bash generate_tianyuanapi_models.sh
这将生成以下文件:
app/main/model/featureModel_gen.go(已更新,包含cost_price字段)app/main/model/featureModel.go(已更新)app/main/model/tianyuanapiCallLogModel_gen.go(新建)app/main/model/tianyuanapiCallLogModel.go(新建)
3. 批量修改API调用方法 ⏳
需要修改30个方法,将:
resp, err := a.callTianyuanApiWithLog(ctx, "", "API名称", map[string]interface{}{
替换为:
ctx := context.Background()
resp, err := a.callTianyuanApiWithLog(ctx, "", "API名称", map[string]interface{}{
参考文档: 批量替换API调用说明.md
建议使用IDE批量替换功能:
- 打开
apirequestService.go - 按
Ctrl+H打开查找替换 - 查找:
a.callTianyuanApiWithLog(ctx, "", " - 替换:
a.callTianyuanApiWithLog(ctx, "", " - 全部替换
然后手动在每个方法开头添加:
ctx := context.Background()
4. 编译验证 ⏳
cd ycc-proxy-server
go build ./...
检查是否有编译错误。
5. 测试验证 ⏳
- 运行项目
- 发起几个API请求(成功和失败各几次)
- 检查
tianyuanapi_call_log表,验证:- 记录是否正确插入
- 成功调用有正确的成本价
- 失败调用成本为0
- 响应耗时是否记录
- 错误信息是否正确
6. 后台配置 ⏳
在后台"功能管理"页面,为每个feature配置成本价:
- 进入"功能管理"
- 编辑某个功能
- 设置"天元API调用成本价"字段
- 保存
统计功能使用示例
// 获取某个功能在某个时间段的调用统计
filter := StatisticsFilter{
FeatureID: "feature-id-123",
StartDate: time.Now().AddDate(0, 0, -30), // 30天前
EndDate: time.Now(),
}
stats, err := ctx.TianyuanapiCallLogService.GetStatistics(context.Background(), filter)
if err == nil {
fmt.Printf("总调用次数: %d\n", stats.TotalCalls)
fmt.Printf("成功次数: %d\n", stats.SuccessCalls)
fmt.Printf("失败次数: %d\n", stats.FailedCalls)
fmt.Printf("总成本: %.2f元\n", stats.TotalCost)
}
SQL查询示例
查询某个接口的调用记录
SELECT * FROM tianyuanapi_call_log
WHERE api_id = 'YYSYBE08'
ORDER BY call_time DESC
LIMIT 100;
统计某天所有接口的调用情况
SELECT
api_id,
COUNT(*) as total_calls,
SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) as success_calls,
SUM(CASE WHEN call_status = 0 THEN 1 ELSE 0 END) as failed_calls,
SUM(cost_price) as total_cost
FROM tianyuanapi_call_log
WHERE DATE(call_time) = CURDATE()
GROUP BY api_id;
查询成功率最低的接口
SELECT
api_id,
COUNT(*) as total_calls,
SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) as success_calls,
(SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) as success_rate
FROM tianyuanapi_call_log
WHERE call_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY api_id
ORDER BY success_rate ASC
LIMIT 10;
注意事项
- 成本价配置:需要在后台为每个feature配置成本价,否则所有调用的成本都是0
- 性能考虑:调用日志采用异步记录,不影响API响应速度
- 数据量控制:response_data只记录前1000字符,避免存储过大
- 缓存机制:apiID到featureID的映射在
ProcessRequests时构建,避免频繁查询数据库 - 失败不收费:根据需求,调用失败时天元API不收费,所以cost_price为0
后续优化建议
- 定时清理:可以添加定时任务,定期清理超过一定时间的日志数据(如90天)
- 成本预警:可以添加监控,当某个时间段的总成本超过阈值时发送告警
- 成功率监控:监控各接口的成功率,低于阈值时告警
- 性能分析:分析响应时间,找出性能瓶颈
- 数据归档:将历史日志归档到其他存储,避免主表过大
文件清单
新增文件
deploy/sql/tianyuanapi_cost_migration.sql- 数据库迁移脚本deploy/sql/generate_tianyuanapi_models.sh- Model生成脚本app/main/api/internal/service/tianyuanapiCallLogService.go- 调用记录服务deploy/sql/天元API调用记录修改说明.md- 详细修改说明deploy/sql/批量替换API调用说明.md- 批量替换指南deploy/sql/天元API调用记录功能完成总结.md- 本文档
修改文件
app/main/api/internal/service/apirequestService.go- 添加调用记录逻辑app/main/api/internal/svc/servicecontext.go- 添加新Model和Service初始化
待生成文件(执行脚本后)
app/main/model/featureModel_gen.go- 已更新app/main/model/featureModel.go- 已更新app/main/model/tianyuanapiCallLogModel_gen.go- 新建app/main/model/tianyuanapiCallLogModel.go- 新建