diff --git a/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx b/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx index 21b320e60e1e..fb588adf2a76 100644 --- a/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx +++ b/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx @@ -9,6 +9,7 @@ import {ANNOTATION_KEY_POD_NAME_VERSION} from '../../../shared/annotations'; import {ErrorNotice} from '../../../shared/components/error-notice'; import {InfoIcon, WarningIcon} from '../../../shared/components/fa-icons'; import {Links} from '../../../shared/components/links'; +import {ToggleButton} from '../../../shared/components/toggle-button'; import {getPodName, getTemplateNameFromNode} from '../../../shared/pod-name'; import {services} from '../../../shared/services'; import {FullHeightLogsViewer} from './full-height-logs-viewer'; @@ -32,13 +33,31 @@ export const WorkflowLogsViewer = ({workflow, nodeId, initialPodName, container, const [error, setError] = useState(); const [loaded, setLoaded] = useState(false); const [logsObservable, setLogsObservable] = useState>(); + const [showRawLog, setShowRawLog] = useState(false); useEffect(() => { setError(null); setLoaded(false); const source = services.workflows .getContainerLogs(workflow, podName, nodeId, selectedContainer, grep, archived) - .map(e => (!podName ? e.podName + ': ' : '') + e.content + '\n') + // extract message from LogEntry + .map(e => { + let message = e.content; + if (!showRawLog) { + try { + const json = JSON.parse(message); + if (json.message) { + message = typeof json.message === 'string' ? json.message : JSON.stringify(json.message); + } + if (json.msg) { + message = typeof json.msg === 'string' ? json.msg : JSON.stringify(json.msg); + } + } catch (e) { + // if not json, show content directly + } + } + return `${!podName ? e.podName + ': ' : ''}${message}\n`; + }) // this next line highlights the search term in bold with a yellow background, white text .map(x => { if (grep !== '') { @@ -55,7 +74,7 @@ export const WorkflowLogsViewer = ({workflow, nodeId, initialPodName, container, ); setLogsObservable(source); return () => subscription.unsubscribe(); - }, [workflow.metadata.namespace, workflow.metadata.name, podName, selectedContainer, grep, archived]); + }, [workflow.metadata.namespace, workflow.metadata.name, podName, selectedContainer, grep, archived, showRawLog]); // filter allows us to introduce a short delay, before we actually change grep const [filter, setFilter] = useState(''); @@ -102,7 +121,10 @@ export const WorkflowLogsViewer = ({workflow, nodeId, initialPodName, container,
{' '} x.value === podName) || {label: ''}).label} onSelect={(_, item) => setPodName(item.value)} /> /{' '} - + {' '} + setShowRawLog(!showRawLog)} title='Show raw logs'> + Show Raw Log + setFilter(v.target.value)} placeholder='Filter (regexp)...' />