diff --git a/airflow-core/src/airflow/ui/src/components/renderStructuredLog.tsx b/airflow-core/src/airflow/ui/src/components/renderStructuredLog.tsx index 2ad930cc9bbd1..f56c8072897fb 100644 --- a/airflow-core/src/airflow/ui/src/components/renderStructuredLog.tsx +++ b/airflow-core/src/airflow/ui/src/components/renderStructuredLog.tsx @@ -92,6 +92,8 @@ const addLinks = (line: string) => { return elements; }; +const sourceFields = ["logger", "chan"]; + export const renderStructuredLog = ({ index, logLevelFilters, @@ -182,16 +184,21 @@ export const renderStructuredLog = ({ , ); - if (showSource) { - for (const key in reStructured) { - if (Object.hasOwn(reStructured, key)) { - elements.push( - ": ", - - {key === "logger" ? "source" : key}={JSON.stringify(reStructured[key])} - , - ); + for (const key in reStructured) { + if (Object.hasOwn(reStructured, key)) { + if (!showSource && sourceFields.includes(key)) { + continue; // eslint-disable-line no-continue } + const val = reStructured[key] as boolean | number | object | string | null; + + elements.push( + " ", + + {key === "logger" ? "source" : key} + , + // Let strings, ints, etc through as is, but JSON stringify anything more complex + `=${val instanceof Object ? JSON.stringify(val) : val}`, + ); } } diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx index 4b608ca6bbbb1..b8c387485e25a 100644 --- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx +++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx @@ -64,7 +64,7 @@ describe("Task log grouping", () => { ); const summarySource = screen.getByTestId( - 'summary-Log message source details: sources=["/home/airflow/logs/dag_id=tutorial_dag/run_id=manual__2025-02-28T05:18:54.249762+00:00/task_id=load/attempt=1.log"]', + 'summary-Log message source details sources=["/home/airflow/logs/dag_id=tutorial_dag/run_id=manual__2025-02-28T05:18:54.249762+00:00/task_id=load/attempt=1.log"]', ); expect(summarySource).toBeVisible();