fix(client): Add a new console class that allow us show extra info passed to log (#21170)

* Change: Add a new console class that allow us show extra info passed to log

* detailed logs: use env var + enable by default on development

* remove duplicated code

* Prevent negative array length when padding level name + Simplify condition using optional chaining

---------

Co-authored-by: Ramón Souza <contato@ramonsouza.com>
This commit is contained in:
Tainan Felipe 2024-10-04 11:09:41 -03:00 committed by GitHub
parent 2483433d6c
commit fce005da3e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 114 additions and 6 deletions

View File

@ -0,0 +1,105 @@
import {
TRACE,
DEBUG,
INFO,
WARN,
ERROR,
FATAL,
} from '@browser-bunyan/levels';
const css = {
levels: {
trace: 'color: DeepPink',
debug: 'color: GoldenRod',
info: 'color: DarkTurquoise',
warn: 'color: Purple',
error: 'color: Crimson',
fatal: 'color: Black',
},
def: 'color: DimGray',
msg: 'color: SteelBlue',
src: 'color: DimGray; font-style: italic; font-size: 0.9em',
};
export default class ConsoleFormattedStream {
/* eslint-disable */
write({
childName,
err,
level,
levelName,
v,
msg,
name,
src,
time,
...extraFields
}: Record<string, any>) {
let levelCss, consoleMethod;
const defaultCss = css.def;
const msgCss = css.msg;
const srcCss = css.src;
const loggerName = childName ? name + '/' + childName : name;
//get level name and pad start with spacs
const formattedLevelName = (
Array(Math.max(0, 6 - levelName.length)).join(' ') + levelName
).toUpperCase();
if (level === TRACE) {
levelName = 'debug';
} else if (level === FATAL) {
levelName = 'error';
}
consoleMethod =
typeof console[levelName as 'log' | 'error' | 'warn' | 'info'] ===
'function'
? console[levelName as 'log' | 'error' | 'warn' | 'info']
: console.log;
if (level < DEBUG) {
levelCss = css.levels.trace;
} else if (level < INFO) {
levelCss = css.levels.debug;
} else if (level < WARN) {
levelCss = css.levels.info;
} else if (level < ERROR) {
levelCss = css.levels.warn;
} else if (level < FATAL) {
levelCss = css.levels.error;
} else {
levelCss = css.levels.fatal;
}
const padZeros = (number: number, len: number) =>
Array(len + 1 - (number + '').length).join('0') + number;
const logArgs = [];
// [time] level: loggerName: msg src?
logArgs.push(`[%s:%s:%s:%s] %c%s%c: %s: %c%s ${src ? '%c%s' : ''}`);
logArgs.push(padZeros(time.getHours(), 2));
logArgs.push(padZeros(time.getMinutes(), 2));
logArgs.push(padZeros(time.getSeconds(), 2));
logArgs.push(padZeros(time.getMilliseconds(), 4));
logArgs.push(levelCss);
logArgs.push(formattedLevelName);
logArgs.push(defaultCss);
logArgs.push(loggerName);
logArgs.push(msgCss);
logArgs.push(msg);
if (src) {
logArgs.push(srcCss);
logArgs.push(src);
}
if (Object.keys(extraFields).length) {
logArgs.push('\n');
logArgs.push(extraFields);
}
if (err?.stack) {
logArgs.push('\n');
logArgs.push(err.stack);
}
consoleMethod.apply(console, logArgs);
}
}

View File

@ -5,6 +5,7 @@ import { ConsoleFormattedStream } from '@browser-bunyan/console-formatted-stream
import { ConsoleRawStream } from '@browser-bunyan/console-raw-stream';
import { ClientLog } from '/imports/ui/Types/meetingClientSettings';
import ServerLoggerStream from './ServerStream';
import ConsoleStream from './consoleStream';
import meetingClientSettingsInitialValues from '/imports/ui/core/initial-values/meetingClientSettings';
// The logger accepts "console","server", and "external" as targets
@ -31,17 +32,14 @@ export function createStreamForTarget(
) {
const TARGET_EXTERNAL = 'external';
const TARGET_CONSOLE = 'console';
let Stream;
switch (target) {
case TARGET_EXTERNAL:
Stream = ServerLoggerStream;
break;
case TARGET_CONSOLE:
Stream = ConsoleFormattedStream;
break;
default:
Stream = ConsoleFormattedStream;
Stream = process.env.DETAILED_LOGS ? ConsoleStream : ConsoleFormattedStream;
}
return new Stream(options);

View File

@ -12,6 +12,7 @@
"@bigbluebutton/tldraw": "^2.0.0-alpha.25",
"@browser-bunyan/console-formatted-stream": "^1.8.0",
"@browser-bunyan/console-raw-stream": "^1.8.0",
"@browser-bunyan/levels": "^1.8.0",
"@browser-bunyan/server-stream": "^1.8.0",
"@emoji-mart/data": "^1.1.2",
"@emoji-mart/react": "^1.1.1",
@ -2120,7 +2121,8 @@
"node_modules/@browser-bunyan/levels": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@browser-bunyan/levels/-/levels-1.8.0.tgz",
"integrity": "sha512-f9oSDik8kAl+4rhVyHqIr012P1boHFUKc7D9nzA5+lDsFoP90UQnDwpseqBdF2mTaWYju10E7h+GdH8u+7MHOQ=="
"integrity": "sha512-f9oSDik8kAl+4rhVyHqIr012P1boHFUKc7D9nzA5+lDsFoP90UQnDwpseqBdF2mTaWYju10E7h+GdH8u+7MHOQ==",
"license": "MIT"
},
"node_modules/@browser-bunyan/server-stream": {
"version": "1.8.0",

View File

@ -3,7 +3,7 @@
"description": "BigBlueButton HTML5 Client",
"license": "LGPL-3.0",
"scripts": {
"start": "NODE_ENV=development webpack serve --open --config webpack.config.js",
"start": "NODE_ENV=development DETAILED_LOGS=true webpack serve --open --config webpack.config.js",
"build": "NODE_ENV=production webpack --config webpack.config.js --mode production",
"tscheck": "tsc",
"lint": "eslint .",
@ -41,6 +41,7 @@
"@bigbluebutton/tldraw": "^2.0.0-alpha.25",
"@browser-bunyan/console-formatted-stream": "^1.8.0",
"@browser-bunyan/console-raw-stream": "^1.8.0",
"@browser-bunyan/levels": "^1.8.0",
"@browser-bunyan/server-stream": "^1.8.0",
"@emoji-mart/data": "^1.1.2",
"@emoji-mart/react": "^1.1.1",

View File

@ -6,6 +6,7 @@ const CopyPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const env = process.env.NODE_ENV || 'development';
const detailedLogs = process.env.DETAILED_LOGS || false;
const prodEnv = 'production';
const devEnv = 'development';
@ -38,6 +39,7 @@ const config = {
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env),
'process.env.DETAILED_LOGS': detailedLogs,
}),
],
resolve: {