Supervisor S-0a/b: Entscheidungsjournal, Order-Events, SignalId, JSONL-Logs
Datenfundament fuer die KI-Analyse (docs/konzepte/KONZEPT-Modul-Supervisor.md, Phase S-0). Sofortnutzen auch ohne KI: abfragbare Rejects, rekonstruierbare Order-Ketten. - core_decision_journal (DecisionRecord): JEDE Handelsentscheidung strukturiert - Decision (Executed/Rejected/Skipped/Failed) + ReasonCode-Enum (als String, erweiterbar) + Kontext-JSON (kulturinvariant) + MarketSlug/EndDate (counterfactual-ready). - core_order_events (OrderEventRecord): Order-Lifecycle als Daten (Placed/PlaceFailed/ LadderStart/LadderStep/FloorReplaced/DustAbort ...) inkl. CLOB-Response. - SignalId (GUID) auf CopySignal, durchgereicht bis ClosedTrade + Core-TradeRecord (Dual-Write) und in die Leiter (ExitLadderState.SignalId) -> Dossier-Korrelation. - CopyTradingEngine: ~20 Entscheidungs-Sites journalisieren zusaetzlich zum Freitext-Log (Mode/SellOnly/H3/MaxBuyPrice/PerMaster/TimeLimit/Budget/Balance/Minimum/SpamBlock/ Leiter/Ownership/NotFound/Teilverkauf/Inkonsistenz/Grace/Demo-Fill/-Close/Live-BUY). - SellLadderService: Order-Events fuer Start/Step/Floor-Replace/Dust; IOrderEventLog injiziert. - TerminalLogger: JSONL-Sink (eine Datei/Tag, LogJson pur) + CorrelationId-Support. Dual-Sink. - Journal-Writes fehlertolerant (brechen den Geld-Pfad nie). - Migrationen offline generiert UND angewendet (rein additiv): Core (Widen F1 + Journal), CopyTrading (SignalId), RF (Initial) - DB war bis AddMarketTakerFeeBps migriert, verifiziert. - Launcher-Designer: Account-Spalten-Instanziierung wiederhergestellt (war bei Designer- Reserialisierung verloren gegangen -> NullReference im Smoke). Tests: +5 (LogJson, Journal-Roundtrips, SignalId) + Journal-Assertions in Engine-Tests. Build 0 Fehler, 336 Tests gruen, --smoke-ui komplett gruen (alle Views inkl. RF gegen echte Tabellen). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
eac47369f0
commit
bf3e012f8b
@@ -13,11 +13,39 @@ namespace PolyTraderSharp.Services
|
||||
public LogLevel Level { get; }
|
||||
public DateTime Timestamp { get; }
|
||||
|
||||
public LogMessageEventArgs(string message, LogLevel level)
|
||||
/// <summary>Korrelations-ID (z. B. SignalId) für die Log-Forensik; leer wenn ohne Kontext.</summary>
|
||||
public string CorrelationId { get; }
|
||||
|
||||
public LogMessageEventArgs(string message, LogLevel level, string correlationId = "")
|
||||
{
|
||||
Message = message;
|
||||
Level = level;
|
||||
Timestamp = DateTime.Now;
|
||||
CorrelationId = correlationId ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reiner JSONL-Formatter für Log-Events (S-0, Supervisor-Konzept): eine JSON-Zeile je Event –
|
||||
/// append-fähig, streambar, maschinen-/KI-lesbar. Statisch und seiteneffektfrei → unit-getestet.
|
||||
/// </summary>
|
||||
public static class LogJson
|
||||
{
|
||||
public static string Format(LogMessageEventArgs e)
|
||||
{
|
||||
var obj = new
|
||||
{
|
||||
ts = e.Timestamp.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz"),
|
||||
level = e.Level.ToString(),
|
||||
cid = string.IsNullOrEmpty(e.CorrelationId) ? null : e.CorrelationId,
|
||||
msg = e.Message
|
||||
};
|
||||
return System.Text.Json.JsonSerializer.Serialize(obj,
|
||||
new System.Text.Json.JsonSerializerOptions
|
||||
{
|
||||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +90,11 @@ namespace PolyTraderSharp.Services
|
||||
string logLine = $"[{e.Timestamp:HH:mm:ss}] {safeMsg}{Environment.NewLine}";
|
||||
|
||||
await File.AppendAllTextAsync(fullPath, logLine);
|
||||
|
||||
// S-0: zusätzlich JSONL (eine Datei je Tag, alle Level) – maschinen-/KI-lesbar,
|
||||
// Grundlage für den Log Viewer. Dual-Sink; Text-Sink später abschaltbar.
|
||||
string jsonlPath = Path.Combine(_logsDirectory, $"{e.Timestamp:yyyy-MM-dd}.jsonl");
|
||||
await File.AppendAllTextAsync(jsonlPath, LogJson.Format(e) + Environment.NewLine);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -70,9 +103,9 @@ namespace PolyTraderSharp.Services
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(string message, LogLevel level = LogLevel.Info)
|
||||
public void Log(string message, LogLevel level = LogLevel.Info, string correlationId = "")
|
||||
{
|
||||
var e = new LogMessageEventArgs(message, level);
|
||||
var e = new LogMessageEventArgs(message, level, correlationId);
|
||||
lock (_lock)
|
||||
{
|
||||
_history.Add(e);
|
||||
|
||||
Reference in New Issue
Block a user