diff --git a/IntelliTrader.Web/Controllers/HomeController.cs b/IntelliTrader.Web/Controllers/HomeController.cs
index 27edbbc..ed81afb 100644
--- a/IntelliTrader.Web/Controllers/HomeController.cs
+++ b/IntelliTrader.Web/Controllers/HomeController.cs
@@ -538,6 +538,29 @@ public IActionResult Help(string lang = "en")
return View(model);
}
+ [HttpGet]
+ public IActionResult DownloadLog(string type = "general")
+ {
+ try
+ {
+ string pattern = "general".Equals(type, StringComparison.OrdinalIgnoreCase) ? "*-general.txt" : "*-trades.txt";
+ string filePath = GetLatestLogFilePath(pattern);
+
+ if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
+ {
+ return NotFound("No log file found.");
+ }
+
+ string fileName = Path.GetFileName(filePath);
+ var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ return File(fileStream, "text/plain", fileName);
+ }
+ catch (Exception ex)
+ {
+ return BadRequest($"Error downloading log file: {ex.Message}");
+ }
+ }
+
[HttpGet]
public IActionResult PollLogs(string type = "general", int maxLines = 100)
{
diff --git a/IntelliTrader.Web/Static/Scripts/Views/dashboard.js b/IntelliTrader.Web/Static/Scripts/Views/dashboard.js
index 1a2d24f..63acb65 100644
--- a/IntelliTrader.Web/Static/Scripts/Views/dashboard.js
+++ b/IntelliTrader.Web/Static/Scripts/Views/dashboard.js
@@ -205,6 +205,7 @@ function setLogType(type) {
$("#logTypeGeneralBtn").removeClass("active");
}
+ $("#downloadLogTopBtn").attr("href", "/Home/DownloadLog?type=" + type);
$("#logTerminal").html('
Loading logs...
');
pollLiveLogs();
}
diff --git a/IntelliTrader.Web/Views/Home/Dashboard.cshtml b/IntelliTrader.Web/Views/Home/Dashboard.cshtml
index 29406e5..c96c8c1 100644
--- a/IntelliTrader.Web/Views/Home/Dashboard.cshtml
+++ b/IntelliTrader.Web/Views/Home/Dashboard.cshtml
@@ -457,9 +457,14 @@
@@ -636,6 +644,11 @@
logTypeSelect.addEventListener("change", function() {
lastLogContent = "";
logTerminal.innerHTML = '
Loading logs...
';
+ const logType = logTypeSelect.value;
+ const downloadBtn = document.getElementById("downloadLogTerminalBtn");
+ if (downloadBtn) {
+ downloadBtn.href = `/Home/DownloadLog?type=${logType}`;
+ }
fetchLogs();
});
diff --git a/magda_agent_system/agent_tasks.json b/magda_agent_system/agent_tasks.json
index 42a30c7..3210c87 100644
--- a/magda_agent_system/agent_tasks.json
+++ b/magda_agent_system/agent_tasks.json
@@ -476,7 +476,7 @@
},
{
"id": "web-dashboard-log-download",
- "status": "todo",
+ "status": "done",
"area": "web",
"risk": "low",
"title": "Add log file download button on Web Dashboard",
@@ -505,6 +505,23 @@
"acceptance": [
"Users can click export on the Stats page to download summary statistics."
]
+ },
+ {
+ "id": "web-dashboard-log-filtering",
+ "status": "todo",
+ "area": "web",
+ "risk": "low",
+ "title": "Add search and log level filter controls for Live Log Monitor",
+ "description": "Implement search filter input and log level filter buttons (All, Info, Warning, Error) for the live log monitor card.",
+ "allowed_paths": [
+ "IntelliTrader.Web/Views/**",
+ "IntelliTrader.Web/Controllers/**",
+ "IntelliTrader.Web/Static/**",
+ "magda_agent_system/agent_tasks.json"
+ ],
+ "acceptance": [
+ "Live log monitor terminal supports real-time text filter and log level filtering."
+ ]
}
]
}