refactor(trace): 计息全路径埋点 + 关键日志常驻落盘
覆盖补全 CalcDailyCompoundInterest / CalcDailySimpleInterestByEod / CalcDailyCompoundInterestByEod / InitSwapDealInterest 分支与复利跨期直取 / orginPv 重映射 / preEod.id==0 播种 / ToRemainingClosePercent 语义翻转。 关键决策点改用 Critical() 无条件落盘(IYcLogger.Info, 类别 SwapCalc), 与开关解耦——出问题事后翻日志即可定位,不必事前开开关。 开关态(Header/Line/Day)仅作排障便利(?swaptrace=1 / 单测 Dump)。 纯增日志不改控制流;YLErpDAL 与 UnitTestProject 编译0错, PrepaidPrincipal trace 测试 2/2 通过(SKIP_INITIALIZATION)。
This commit is contained in:
@@ -1,21 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using YLErp.Helpers;
|
||||
|
||||
namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 计息计算过程追踪器。默认完全关闭,零运行时成本;开启后逐日记录:
|
||||
/// 计息起点、日终归档 ValueDate 地板、计息基数 dynomicPrincipal、当日利率、当日利息、累计利息。
|
||||
/// 便于定位"算出来一个数却不对"的根因,也便于把一次真实平仓的逐步过程打印出来与 Excel 对账。
|
||||
/// 计息计算过程追踪器。采用两层设计:
|
||||
///
|
||||
/// 两种开启方式(互不冲突):
|
||||
/// 1) 全局(单元测试):SwapCalcTrace.IsEnabled = true; SwapCalcTrace.Reset(); ...; SwapCalcTrace.Dump();
|
||||
/// 2) 请求(运行时排障,无需重启):经 SwapCalcTraceMiddleware,在 URL 追加 ?swaptrace=1
|
||||
/// 或请求头 X-SwapCalc-Trace: 1 即可,追踪文本会出现在响应头 X-SwapCalc-Trace(超长落 logs/ 并在头部给路径)。
|
||||
/// ① 常驻关键日志(Critical):记录"走了哪条分支 / orginPv 重映射 / preEod.id==0 播种 /
|
||||
/// closePercent 语义翻转(A→B) / 计息基数 dynomicPrincipal 分解 / ValueDate 地板 /
|
||||
/// 最终四舍五入输出 / 逐日累加明细"。这些信息**无条件**经 IYcLogger.Info 落盘,
|
||||
/// 与开关无关——出问题时事后翻日志即可定位,不必事前开开关(否则"出问题了已经晚了")。
|
||||
///
|
||||
/// ② 开关态明细(Header/Line/Day,经 IsEnabled 或请求开关):仅在主动排障时把上述信息
|
||||
/// 额外汇进内存 buffer,便于单元测试 Dump() 断言,或运行时在响应头 X-SwapCalc-Trace
|
||||
/// 一次性看全貌(URL 追加 ?swaptrace=1 / 请求头 X-SwapCalc-Trace:1 / 标记文件
|
||||
/// App_Data/swapcalctrace.on 三选一,无需重启)。开关态不影响日志落盘。
|
||||
///
|
||||
/// 关键日志常驻后,本类的"零成本"只针对开关态内存 buffer;Critical 的日志写入是常态成本,
|
||||
/// 但因交易笔数极少、单行极小,可忽略。
|
||||
/// </summary>
|
||||
public static class SwapCalcTrace
|
||||
{
|
||||
private static readonly IYcLogger _logger = LogFactory.GetLogger("SwapCalc");
|
||||
|
||||
// ---- 全局模式(单元测试,保持 ThreadStatic 兼容既有测试) ----
|
||||
public static bool IsEnabled { get; set; } = false;
|
||||
|
||||
@@ -38,12 +47,28 @@ namespace YLErp.Modules.SwapModule
|
||||
_reqBuf.Value = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 常驻关键日志:始终落盘(IYcLogger.Info);开关打开时额外进 buffer 供实时查看/单测断言。
|
||||
/// 这是事后定位根因的主通道,不应依赖开关。
|
||||
/// </summary>
|
||||
public static void Critical(string s)
|
||||
{
|
||||
_logger.Info(s);
|
||||
if (IsEnabled) GlobalLines.Add(s);
|
||||
if (_reqOn.Value)
|
||||
{
|
||||
_reqBuf.Value ??= new StringBuilder();
|
||||
_reqBuf.Value.AppendLine(s);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 以下为开关态(verbose)工具,仅用于单测 Dump 与 ?swaptrace=1 的逐日明细汇总 ----
|
||||
public static void Header(string title) => Record($"== {title} ==");
|
||||
public static void Line(string text) => Record(text);
|
||||
|
||||
/// <summary>记录某一计息日的明细。</summary>
|
||||
/// <summary>逐日明细。同样常驻落盘——这是"为何 accrued N 天而非 M 天"的直接证据,必须事后可查。</summary>
|
||||
public static void Day(int idx, DateTime date, decimal rate, decimal basePrincipal, decimal dayInterest, decimal accumulated)
|
||||
=> Record($" [{idx}] {date:yyyy-MM-dd} rate={rate:P6} base={basePrincipal:F4} day={dayInterest:F6} acc={accumulated:F6}");
|
||||
=> Critical($" [{idx}] {date:yyyy-MM-dd} rate={rate:P6} base={basePrincipal:F4} day={dayInterest:F6} acc={accumulated:F6}");
|
||||
|
||||
private static void Record(string s)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user