feat(web): add lineage_events.jsonl structured audit logging for collection runs
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 22s
Validators (Pushes and Pull Requests) / validate-core (push) Has been cancelled
Prepare Release / Build & Create Release (push) Successful in 1m14s
Prepare Release / Release Notification (push) Successful in 1s

This commit is contained in:
2026-07-12 13:18:50 +09:00
parent 4eb23a41ca
commit 87949f42b5
@@ -168,6 +168,7 @@ public class KisDataCollectionOrchestrator : ICollectionOrchestrator
}
};
File.WriteAllText(outputPath, JsonSerializer.Serialize(outputData, new JsonSerializerOptions { WriteIndented = true }));
LogLineageEvent(runId, result.Status, result.SuccessCount, result.ErrorCount);
_logger.LogInformation("Collection run {RunId} finished with status {Status}: {Success} ok, {Errors} errors",
runId, result.Status, result.SuccessCount, result.ErrorCount);
@@ -220,6 +221,46 @@ public class KisDataCollectionOrchestrator : ICollectionOrchestrator
return false;
}
private static void LogLineageEvent(string runId, string status, int successCount, int errorCount)
{
try
{
var baseDir = AppContext.BaseDirectory;
var current = new DirectoryInfo(baseDir);
string? repoRoot = null;
while (current != null)
{
if (Directory.Exists(Path.Combine(current.FullName, ".git")))
{
repoRoot = current.FullName;
break;
}
current = current.Parent;
}
if (repoRoot != null)
{
var runtimeDir = Path.Combine(repoRoot, "runtime");
Directory.CreateDirectory(runtimeDir);
var lineagePath = Path.Combine(runtimeDir, "lineage_events.jsonl");
var ev = new
{
@event = "collection_run_completed",
run_id = runId,
status = status,
success_count = successCount,
error_count = errorCount,
timestamp = DataNormalizationHelper.KstNowIso()
};
File.AppendAllText(lineagePath, JsonSerializer.Serialize(ev) + "\n");
}
}
catch { /* Robust fallback */ }
}
}