portainer/app/docker/helpers/logHelper/formatters.ts

162 lines
3.8 KiB
TypeScript

import { format } from 'date-fns';
import { takeRight } from 'lodash';
import { Span, Level, Colors, JSONStackTrace, FormattedLine } from './types';
const spaceSpan: Span = { text: ' ' };
function logLevelToSpan(level: Level): Span {
switch (level) {
case 'debug':
case 'DBG':
return {
fgColor: Colors.Grey,
text: 'DBG',
fontWeight: 'bold',
};
case 'info':
case 'INF':
return {
fgColor: Colors.Green,
text: 'INF',
fontWeight: 'bold',
};
case 'warn':
case 'WRN':
return {
fgColor: Colors.Yellow,
text: 'WRN',
fontWeight: 'bold',
};
case 'error':
case 'ERR':
return {
fgColor: Colors.Red,
text: 'ERR',
fontWeight: 'bold',
};
default:
return { text: level };
}
}
export function formatTime(
time: number | string | undefined,
spans: Span[],
line: string
) {
let nl = line;
if (time) {
let date = '';
if (typeof time === 'number') {
// time is a number, so it is the number of seconds OR milliseconds since Unix Epoch (1970-01-01T00:00:00.000Z)
// we need to know if time's unit is second or millisecond
// 253402214400 is the numer of seconds between Unix Epoch and 9999-12-31T00:00:00.000Z
// if time is greater than 253402214400, then time unit cannot be second, so it is millisecond
const timestampInMilliseconds = time > 253402214400 ? time : time * 1000;
date = format(new Date(timestampInMilliseconds), 'Y/MM/dd hh:mmaa');
} else {
date = time;
}
spans.push({ fgColor: Colors.Grey, text: date }, spaceSpan);
nl += `${date} `;
}
return nl;
}
export function formatLevel(
level: Level | undefined,
spans: Span[],
line: string
) {
let nl = line;
if (level) {
const levelSpan = logLevelToSpan(level);
spans.push(levelSpan, spaceSpan);
nl += `${levelSpan.text} `;
}
return nl;
}
export function formatCaller(
caller: string | undefined,
spans: Span[],
line: string
) {
let nl = line;
if (caller) {
const trim = takeRight(caller.split('/'), 2).join('/');
spans.push(
{ fgColor: Colors.Magenta, text: trim, fontWeight: 'bold' },
spaceSpan
);
spans.push({ fgColor: Colors.Blue, text: '>' }, spaceSpan);
nl += `${trim} > `;
}
return nl;
}
export function formatMessage(
message: string,
spans: Span[],
line: string,
hasKeys: boolean
) {
let nl = line;
if (message) {
spans.push({ fgColor: Colors.Magenta, text: `${message}` }, spaceSpan);
nl += `${message} `;
if (hasKeys) {
spans.push({ fgColor: Colors.Magenta, text: `|` }, spaceSpan);
nl += '| ';
}
}
return nl;
}
export function formatKeyValuePair(
key: string,
value: unknown,
spans: Span[],
line: string,
isLastKey: boolean
) {
let nl = line;
const strValue = typeof value !== 'string' ? JSON.stringify(value) : value;
spans.push(
{ fgColor: Colors.Blue, text: `${key}=` },
{
fgColor: key === 'error' || key === 'ERR' ? Colors.Red : Colors.Magenta,
text: strValue,
}
);
if (!isLastKey) spans.push(spaceSpan);
nl += `${key}=${strValue}${!isLastKey ? ' ' : ''}`;
return nl;
}
export function formatStackTrace(
stackTrace: JSONStackTrace | undefined,
lines: FormattedLine[]
) {
if (stackTrace) {
stackTrace.forEach(({ func, line: lineNumber, source }) => {
const line = ` at ${func} (${source}:${lineNumber})`;
const spans: Span[] = [
spaceSpan,
spaceSpan,
spaceSpan,
spaceSpan,
{ text: 'at ', fgColor: Colors.Grey },
{ text: func, fgColor: Colors.Red },
{ text: `(${source}:${lineNumber})`, fgColor: Colors.Grey },
];
lines.push({ line, spans });
});
}
}