优化生产日志体积:访问降噪、压缩清理与退款告警节流

跳过轮询/封面等热路径成功请求,按日 gzip 并保留可配天数,退款 max-retry 汇总告警。
This commit is contained in:
yml2213
2026-07-13 22:02:20 +08:00
parent f51aed1f0f
commit 2efcede800
8 changed files with 361 additions and 41 deletions
+50 -21
View File
@@ -225,14 +225,25 @@ func (j *Job) warnMaxRetryRefunds(ctx context.Context, now time.Time) {
j.logger.Warn("refund retry max count scan failed", zap.Error(err))
return
}
if len(rows) == 0 {
return
}
// 汇总一条告警,避免每 2 分钟对同一批单刷屏;更新 last_retry_at 实现 24h 节流
ids := make([]uint64, 0, len(rows))
orderIDs := make([]uint64, 0, len(rows))
for _, row := range rows {
j.logger.Warn("refund retry reached max count, need manual check",
zap.Uint64("payment_id", row.ID),
zap.Uint64("order_id", row.OrderID),
zap.String("biz_type", row.BizType),
zap.String("status", row.Status),
zap.Int("retry_count", row.RetryCount),
)
ids = append(ids, row.ID)
orderIDs = append(orderIDs, row.OrderID)
}
j.logger.Warn("refund retry reached max count, need manual check",
zap.Int("count", len(rows)),
zap.Uint64s("payment_ids", ids),
zap.Uint64s("order_ids", orderIDs),
)
if err := j.db.WithContext(ctx).Model(&model.PaymentOrder{}).
Where("id IN ?", ids).
Update("last_retry_at", now).Error; err != nil {
j.logger.Warn("refund retry bump last_retry_at failed", zap.Error(err))
}
}
@@ -248,6 +259,8 @@ func (j *Job) warnMissingRefundOrders(ctx context.Context, now time.Time) (int,
}
missing := 0
rebuilt := 0
var missingOrderIDs []uint64
var rebuildFailOrderIDs []uint64
for _, row := range rows {
var count int64
if err := j.db.WithContext(ctx).Model(&model.PaymentOrder{}).
@@ -264,18 +277,11 @@ func (j *Job) warnMissingRefundOrders(ctx context.Context, now time.Time) (int,
// 非仲裁孤儿 biz_type 无法从订单状态可靠区分,维持只告警。
if row.SettlementStatus == "arbitrated" {
if j.payments == nil {
j.logger.Warn("auto rebuild arbitration refund skipped, payment repository unavailable",
zap.Uint64("order_id", row.ID),
zap.Int64("refund_amount_cent", row.RefundAmountCent),
)
rebuildFailOrderIDs = append(rebuildFailOrderIDs, row.ID)
continue
}
if _, err := j.payments.StartRefund(ctx, row.ID, row.RefundAmountCent, "arbitration_refund", "仲裁退款补偿补建"); err != nil {
j.logger.Warn("auto rebuild arbitration refund failed, need manual check",
zap.Uint64("order_id", row.ID),
zap.Int64("refund_amount_cent", row.RefundAmountCent),
zap.Error(err),
)
rebuildFailOrderIDs = append(rebuildFailOrderIDs, row.ID)
} else {
rebuilt++
j.logger.Info("auto rebuild arbitration refund submitted",
@@ -285,13 +291,36 @@ func (j *Job) warnMissingRefundOrders(ctx context.Context, now time.Time) (int,
}
continue
}
missingOrderIDs = append(missingOrderIDs, row.ID)
}
// 汇总告警 + Redis 24h 去重,避免每轮扫描刷屏
if len(missingOrderIDs) > 0 && j.shouldWarn(ctx, "missing_payment", 0) {
j.logger.Warn("refund order missing payment record, need manual check",
zap.Uint64("order_id", row.ID),
zap.String("order_no", row.OrderNo),
zap.String("refund_status", row.RefundStatus),
zap.String("settlement_status", row.SettlementStatus),
zap.Int64("refund_amount_cent", row.RefundAmountCent),
zap.Int("count", len(missingOrderIDs)),
zap.Uint64s("order_ids", missingOrderIDs),
)
}
if len(rebuildFailOrderIDs) > 0 && j.shouldWarn(ctx, "rebuild_fail", 0) {
j.logger.Warn("auto rebuild arbitration refund failed, need manual check",
zap.Int("count", len(rebuildFailOrderIDs)),
zap.Uint64s("order_ids", rebuildFailOrderIDs),
)
}
return missing, rebuilt, nil
}
// shouldWarn 用 Redis 做 24h 节流;无 Redis 时每个 job 周期最多打一次同类汇总(由调用方聚合)。
func (j *Job) shouldWarn(ctx context.Context, kind string, id uint64) bool {
if j.redis == nil {
return true
}
key := fmt.Sprintf("hfb:job:refundretry:warn:%s", kind)
if id > 0 {
key = fmt.Sprintf("%s:%d", key, id)
}
ok, err := j.redis.SetNX(ctx, key, "1", manualWarnThreshold).Result()
if err != nil {
return true
}
return ok
}