[release-12.3.1] Logs: Fixed prettify JSON behavior with unescaped content (#114407)

Logs: Fixed prettify JSON behavior with unescaped content (#114403)

* processing: move escaping to a later stage

* Regression test

(cherry picked from commit c42d6a53a6)

Co-authored-by: Matias Chomicki <matias.chomicki@grafana.com>
This commit is contained in:
grafana-delivery-bot[bot]
2025-11-25 13:59:36 +00:00
committed by GitHub
co-authored by Matias Chomicki
parent ffa5532266
commit 1d8cefb75f
2 changed files with 45 additions and 3 deletions
@@ -190,6 +190,45 @@ describe('preProcessLogs', () => {
expect(logListModel.body).not.toBe(entry);
});
test('Prettifies and escapes wrapped JSON', () => {
const entry = '{"key": "value", "otherKey": "other\\nValue"}';
const logListModel = createLogLine(
{ entry, hasUnescapedContent: true },
{
escape: true, // escape
order: LogsSortOrder.Descending,
timeZone: 'browser',
wrapLogMessage: true, // wrapped
prettifyJSON: true,
}
);
expect(logListModel.entry).toBe(entry);
expect(logListModel.body).toBe(`{
"key": "value",
"otherKey": "other
Value"
}`);
});
test('Prettifies JSON without escaping', () => {
const entry = '{"key": "value", "otherKey": "other\\nValue"}';
const logListModel = createLogLine(
{ entry, hasUnescapedContent: true },
{
escape: false, // escape = false
order: LogsSortOrder.Descending,
timeZone: 'browser',
wrapLogMessage: true, // wrapped
prettifyJSON: true,
}
);
expect(logListModel.entry).toBe(entry);
expect(logListModel.body).toBe(`{
"key": "value",
"otherKey": "other\\nValue"
}`);
});
test('Uses lossless parsing', () => {
const entry = '{"number": 90071992547409911}';
const logListModel = createLogLine(
@@ -62,6 +62,7 @@ export class LogListModel implements LogRowModel {
private _highlightedBody: string | undefined = undefined;
private _highlightedLogAttributesTokens: Array<string | Token> | undefined = undefined;
private _highlightTokens: Array<string | Token> | undefined = undefined;
private _escapeUnescapedString = false;
private _fields: FieldDef[] | undefined = undefined;
private _getFieldLinks: GetFieldLinksFn | undefined = undefined;
private _prettifyJSON: boolean;
@@ -111,11 +112,10 @@ export class LogListModel implements LogRowModel {
this._virtualization = virtualization;
this._wrapLogMessage = wrapLogMessage;
let raw = log.raw;
if (escape && log.hasUnescapedContent) {
raw = escapeUnescapedString(raw);
this._escapeUnescapedString = true;
}
this.raw = raw;
this.raw = log.raw;
if (config.featureToggles.otelLogsFormatting && this.otelLanguage) {
this.labels[OTEL_LOG_LINE_ATTRIBUTES_FIELD_NAME] = getOtelAttributesField(this, wrapLogMessage);
@@ -143,6 +143,9 @@ export class LogListModel implements LogRowModel {
if (reStringified) {
this.raw = reStringified;
}
if (this._escapeUnescapedString) {
this.raw = escapeUnescapedString(this.raw);
}
} catch (error) {}
const raw = this.raw;
this._body = this.collapsed