Logs: Added multi-line display control to the "wrap lines" option (#88144)

* LogRowMessage: strip new lines when wrapping is disabled

* LogRowMessage: prevent conflicts between failed json parsing and unwrapping

* LogRowMessage: expand multi-line unwrapped logs when opening details

* Add unit test

* Prettier

* chore: update comment
This commit is contained in:
Matias Chomicki 2024-05-28 10:59:11 +02:00 committed by GitHub
parent 6f9527b4c2
commit 97cb92eb1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 5 deletions

View File

@ -308,6 +308,7 @@ class UnThemedLogRow extends PureComponent<Props, State> {
pinned={this.props.pinned}
mouseIsOver={this.state.mouseIsOver}
onBlur={this.onMouseLeave}
expanded={this.state.showDetails}
/>
)}
</tr>

View File

@ -160,4 +160,41 @@ describe('LogRowMessage', () => {
});
});
});
describe('For multi-line logs', () => {
const entry = `Line1
line2
line3`;
const singleLineEntry = entry.replace(/(\r\n|\n|\r)/g, '');
it('Displays the original log line when wrapping is enabled', () => {
setup({
row: createLogRow({ entry, logLevel: LogLevel.error, timeEpochMs: 1546297200000 }),
wrapLogMessage: true,
});
expect(screen.getByText(/Line1/)).toBeInTheDocument();
expect(screen.getByText(/line2/)).toBeInTheDocument();
expect(screen.getByText(/line3/)).toBeInTheDocument();
expect(screen.queryByText(singleLineEntry)).not.toBeInTheDocument();
});
it('Removes new lines from the original log line when wrapping is disabled', () => {
setup({
row: createLogRow({ entry, logLevel: LogLevel.error, timeEpochMs: 1546297200000 }),
wrapLogMessage: false,
});
expect(screen.getByText(singleLineEntry)).toBeInTheDocument();
});
it('Displays the original log line when the line is expanded', () => {
setup({
row: createLogRow({ entry, logLevel: LogLevel.error, timeEpochMs: 1546297200000 }),
wrapLogMessage: true,
expanded: true,
});
expect(screen.getByText(/Line1/)).toBeInTheDocument();
expect(screen.getByText(/line2/)).toBeInTheDocument();
expect(screen.getByText(/line3/)).toBeInTheDocument();
expect(screen.queryByText(singleLineEntry)).not.toBeInTheDocument();
});
});
});

View File

@ -29,6 +29,7 @@ interface Props {
styles: LogRowStyles;
mouseIsOver: boolean;
onBlur: () => void;
expanded?: boolean;
}
interface LogMessageProps {
@ -58,13 +59,20 @@ const LogMessage = ({ hasAnsi, entry, highlights, styles }: LogMessageProps) =>
return <>{entry}</>;
};
const restructureLog = (line: string, prettifyLogMessage: boolean): string => {
const restructureLog = (
line: string,
prettifyLogMessage: boolean,
wrapLogMessage: boolean,
expanded: boolean
): string => {
if (prettifyLogMessage) {
try {
return JSON.stringify(JSON.parse(line), undefined, 2);
} catch (error) {
return line;
}
} catch (error) {}
}
// With wrapping disabled, we want to turn it into a single-line log entry unless the line is expanded
if (!wrapLogMessage && !expanded) {
line = line.replace(/(\r\n|\n|\r)/g, '');
}
return line;
};
@ -84,9 +92,13 @@ export const LogRowMessage = React.memo((props: Props) => {
mouseIsOver,
onBlur,
getRowContextQuery,
expanded,
} = props;
const { hasAnsi, raw } = row;
const restructuredEntry = useMemo(() => restructureLog(raw, prettifyLogMessage), [raw, prettifyLogMessage]);
const restructuredEntry = useMemo(
() => restructureLog(raw, prettifyLogMessage, wrapLogMessage, Boolean(expanded)),
[raw, prettifyLogMessage, wrapLogMessage, expanded]
);
const shouldShowMenu = useMemo(() => mouseIsOver || pinned, [mouseIsOver, pinned]);
return (
<>