diff --git a/app/docker/helpers/logHelper/formatJSONLogs.ts b/app/docker/helpers/logHelper/formatJSONLogs.ts index 5a08cc360..7d0d74c6b 100644 --- a/app/docker/helpers/logHelper/formatJSONLogs.ts +++ b/app/docker/helpers/logHelper/formatJSONLogs.ts @@ -31,7 +31,7 @@ export function formatJSONLine( if (withTimestamps) { const timestamp = rawText.substring(0, TIMESTAMP_LENGTH); spans.push({ text: timestamp }); - line += `${timestamp}`; + line += `${timestamp} `; } line += formatTime(time, spans, line); line += formatLevel(level, spans, line); diff --git a/app/docker/helpers/logHelper/formatLogs.ts b/app/docker/helpers/logHelper/formatLogs.ts index e0af64375..3b1c4dc4f 100644 --- a/app/docker/helpers/logHelper/formatLogs.ts +++ b/app/docker/helpers/logHelper/formatLogs.ts @@ -33,8 +33,14 @@ export function formatLogs( if (stripHeaders) { logs = stripHeadersFunc(logs); } - if (logs.includes('\\n')) { - logs = JSON.parse(logs); + // if JSON logs come serialized 2 times, parse them once to unwrap them + // for example when retrieving Edge Agent logs on Nomad + if (logs.startsWith('"')) { + try { + logs = JSON.parse(logs); + } catch (error) { + // noop, throw error away if logs cannot be parsed + } } const tokens: Token[][] = tokenize(logs); @@ -83,16 +89,26 @@ export function formatLogs( } const text = stripEscapeCodes(tokenLine); - if ( - (!withTimestamps && text.startsWith('{')) || - (withTimestamps && text.substring(TIMESTAMP_LENGTH).startsWith('{')) - ) { - const lines = formatJSONLine(text, withTimestamps); - formattedLogs.push(...lines); - } else if (ZerologRegex.test(text)) { - const lines = formatZerologLogs(text, withTimestamps); - formattedLogs.push(...lines); - } else { + try { + if ( + (!withTimestamps && text.startsWith('{')) || + (withTimestamps && text.substring(TIMESTAMP_LENGTH).startsWith('{')) + ) { + const lines = formatJSONLine(text, withTimestamps); + formattedLogs.push(...lines); + } else if ( + (!withTimestamps && ZerologRegex.test(text)) || + (withTimestamps && + ZerologRegex.test(text.substring(TIMESTAMP_LENGTH))) + ) { + const lines = formatZerologLogs(text, withTimestamps); + formattedLogs.push(...lines); + } else { + spans.push({ fgColor, bgColor, text, fontWeight }); + line += text; + } + } catch (error) { + // in case parsing fails for whatever reason, push the raw logs and continue spans.push({ fgColor, bgColor, text, fontWeight }); line += text; } diff --git a/app/docker/helpers/logHelper/formatZerologLogs.ts b/app/docker/helpers/logHelper/formatZerologLogs.ts index e983e3141..f43aeb3b3 100644 --- a/app/docker/helpers/logHelper/formatZerologLogs.ts +++ b/app/docker/helpers/logHelper/formatZerologLogs.ts @@ -55,6 +55,12 @@ export function formatZerologLogs(rawText: string, withTimestamps?: boolean) { const text = withTimestamps ? rawText.substring(TIMESTAMP_LENGTH) : rawText; + if (withTimestamps) { + const timestamp = rawText.substring(0, TIMESTAMP_LENGTH); + spans.push({ text: timestamp }); + line += `${timestamp} `; + } + const [, date, level, caller, messageAndPairs] = text.match(ZerologRegex) || [];