diff --git a/ui/src/components/workflow/WorkflowRunDetail.tsx b/ui/src/components/workflow/WorkflowRunDetail.tsx index e104410a..18a2f40d 100644 --- a/ui/src/components/workflow/WorkflowRunDetail.tsx +++ b/ui/src/components/workflow/WorkflowRunDetail.tsx @@ -5,6 +5,7 @@ import { CheckOutlined as CheckOutlinedIcon, ClockCircleOutlined as ClockCircleOutlinedIcon, CloseCircleOutlined as CloseCircleOutlinedIcon, + DownloadOutlined as DownloadOutlinedIcon, RightOutlined as RightOutlinedIcon, SelectOutlined as SelectOutlinedIcon, SettingOutlined as SettingOutlinedIcon, @@ -188,6 +189,34 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin ); }; + const handleDownloadClick = () => { + const NEWLINE = "\n"; + const logstr = listData + .map((group) => { + return ( + group.name + + NEWLINE + + group.records + .map((record) => { + const datetime = dayjs(record.timestamp).format("YYYY-MM-DDTHH:mm:ss.SSSZ"); + const level = record.level; + const message = record.message.trim().replaceAll("\r", "\\r").replaceAll("\n", "\\n"); + return `[${datetime}] [${level}] ${message}`; + }) + .join(NEWLINE) + ); + }) + .join(NEWLINE + NEWLINE); + const blob = new Blob([logstr], { type: "text/plain" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = `certimate_workflow_run_#${runId}_logs.txt`; + a.click(); + URL.revokeObjectURL(url); + a.remove(); + }; + return ( <> {t("workflow_run.logs")} @@ -210,6 +239,15 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin icon: , onClick: () => setShowWhitespace(!showWhitespace), }, + { + type: "divider", + }, + { + key: "download-logs", + label: t("workflow_run.logs.menu.download_logs"), + icon: , + onClick: handleDownloadClick, + }, ], }} trigger={["click"]} diff --git a/ui/src/i18n/locales/en/nls.workflow.runs.json b/ui/src/i18n/locales/en/nls.workflow.runs.json index e177dcb3..c48e54b7 100644 --- a/ui/src/i18n/locales/en/nls.workflow.runs.json +++ b/ui/src/i18n/locales/en/nls.workflow.runs.json @@ -21,6 +21,7 @@ "workflow_run.logs": "Logs", "workflow_run.logs.menu.show_timestamps": "Show timestamps", "workflow_run.logs.menu.show_whitespaces": "Show whitespaces", + "workflow_run.logs.menu.download_logs": "Download logs", "workflow_run.artifacts": "Artifacts", "workflow_run_artifact.props.type": "Type", diff --git a/ui/src/i18n/locales/zh/nls.workflow.runs.json b/ui/src/i18n/locales/zh/nls.workflow.runs.json index 79d46abe..ce3ac15d 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.runs.json +++ b/ui/src/i18n/locales/zh/nls.workflow.runs.json @@ -21,6 +21,7 @@ "workflow_run.logs": "日志", "workflow_run.logs.menu.show_timestamps": "显示日期时间", "workflow_run.logs.menu.show_whitespaces": "显示转义换行符", + "workflow_run.logs.menu.download_logs": "下载日志", "workflow_run.artifacts": "输出产物", "workflow_run_artifact.props.type": "类型",