diff --git a/bigbluebutton-html5/imports/startup/client/logger/consoleStream.ts b/bigbluebutton-html5/imports/startup/client/logger/consoleStream.ts new file mode 100644 index 0000000000..2a0e0f2e61 --- /dev/null +++ b/bigbluebutton-html5/imports/startup/client/logger/consoleStream.ts @@ -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) { + 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); + } +} diff --git a/bigbluebutton-html5/imports/startup/client/logger/index.ts b/bigbluebutton-html5/imports/startup/client/logger/index.ts index 0487e27329..ae524d14f7 100644 --- a/bigbluebutton-html5/imports/startup/client/logger/index.ts +++ b/bigbluebutton-html5/imports/startup/client/logger/index.ts @@ -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); diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json index 2abcf858a8..d300e7e311 100644 --- a/bigbluebutton-html5/package-lock.json +++ b/bigbluebutton-html5/package-lock.json @@ -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", diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json index 4e594d4665..c067df2c9d 100644 --- a/bigbluebutton-html5/package.json +++ b/bigbluebutton-html5/package.json @@ -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", diff --git a/bigbluebutton-html5/webpack.config.js b/bigbluebutton-html5/webpack.config.js index 25ea53c48c..4ce74612fd 100644 --- a/bigbluebutton-html5/webpack.config.js +++ b/bigbluebutton-html5/webpack.config.js @@ -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: {