Client logger implemented
This commit is contained in:
parent
957a2ef02c
commit
bc3e068e2e
14
bigbluebutton-html5/client/main.jsx
Normal file → Executable file
14
bigbluebutton-html5/client/main.jsx
Normal file → Executable file
@ -2,15 +2,19 @@
|
||||
import React from 'react';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { render } from 'react-dom';
|
||||
import { log } from '/imports/ui/services/api';
|
||||
import renderRoutes from '/imports/startup/client/routes';
|
||||
import logger from '/imports/startup/client/logger';
|
||||
|
||||
Meteor.startup(() => {
|
||||
render(renderRoutes(), document.getElementById('app'));
|
||||
|
||||
// Log all uncaught exceptions to the server
|
||||
// TODO: There is no StackTrace on the ErrorEvent object
|
||||
// Logs all uncaught exceptions to the client logger
|
||||
window.addEventListener('error', (e) => {
|
||||
log('error', e);
|
||||
const stack = e.error.stack;
|
||||
let message = e.error.toString();
|
||||
|
||||
// Checks if stack includes the message, if not add the two together.
|
||||
(stack.includes(message)) ? message = stack : message += `\n${stack}`;
|
||||
logger.error(message);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -7,23 +7,19 @@ const logClient = function (type, log, ...args) {
|
||||
const logContents = { ...args };
|
||||
|
||||
if (User) {
|
||||
const {
|
||||
meetingId, name, intId, extId, authToken,
|
||||
} = User;
|
||||
const serverInfo = {
|
||||
meetingId,
|
||||
userName: name,
|
||||
userIntId: intId,
|
||||
userExtId: extId,
|
||||
authToken,
|
||||
};
|
||||
logContents.serverInfo = serverInfo;
|
||||
if (User.meetingId === args[0].meetingId) {
|
||||
args[0].validUser = 'vaild';
|
||||
} else {
|
||||
args[0].validUser = 'invaild';
|
||||
}
|
||||
} else {
|
||||
args[0].validUser = 'notFound';
|
||||
}
|
||||
|
||||
if (typeof log === 'string' || log instanceof String) {
|
||||
Logger.log(type, `CLIENT LOG: ${log}\n`, logContents);
|
||||
Logger.log(type, `CLIENT LOG: ${log}`, logContents);
|
||||
} else {
|
||||
Logger.log(type, `CLIENT LOG: ${JSON.stringify(log)}\n`, logContents);
|
||||
Logger.log(type, `CLIENT LOG: ${JSON.stringify(log)}`, logContents);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,7 @@ import SessionStorage from '/imports/ui/services/storage/session';
|
||||
import { setCustomLogoUrl } from '/imports/ui/components/user-list/service';
|
||||
import { log } from '/imports/ui/services/api';
|
||||
import deviceInfo from '/imports/utils/deviceInfo';
|
||||
import logger from '/imports/startup/client/logger';
|
||||
|
||||
// disconnected and trying to open a new connection
|
||||
const STATUS_CONNECTING = 'connecting';
|
||||
@ -15,6 +16,9 @@ export function joinRouteHandler(nextState, replace, callback) {
|
||||
replace({ pathname: '/error/404' });
|
||||
callback();
|
||||
}
|
||||
|
||||
// Old credentials stored in memory were being used when browsers was refreshed
|
||||
Auth.clearCredentials();
|
||||
|
||||
// use enter api to get params for the client
|
||||
const url = `/bigbluebutton/api/enter?sessionToken=${sessionToken}`;
|
||||
@ -24,6 +28,8 @@ export function joinRouteHandler(nextState, replace, callback) {
|
||||
.then(({ response }) => {
|
||||
const {
|
||||
returncode, meetingID, internalUserID, authToken, logoutUrl, customLogoURL, metadata,
|
||||
externUserID, fullname, confname,
|
||||
|
||||
} = response;
|
||||
|
||||
if (returncode === 'FAILED') {
|
||||
@ -55,13 +61,32 @@ export function joinRouteHandler(nextState, replace, callback) {
|
||||
}) : {};
|
||||
SessionStorage.setItem(METADATA_KEY, metakeys);
|
||||
|
||||
Auth.set(meetingID, internalUserID, authToken, logoutUrl, sessionToken);
|
||||
Auth.set(
|
||||
meetingID, internalUserID, authToken, logoutUrl,
|
||||
sessionToken, fullname, externUserID, confname,
|
||||
);
|
||||
|
||||
const path = deviceInfo.type().isPhone ? '/' : '/users';
|
||||
const userInfo = window.navigator;
|
||||
|
||||
// Browser information is sent once on startup
|
||||
// Sent here instead of Meteor.startup, as the
|
||||
// user might not be validiated by then, thus user's data
|
||||
// would not be sent with this information
|
||||
const clientInfo = {
|
||||
language: userInfo.language,
|
||||
userAgent: userInfo.userAgent,
|
||||
screenSize: { width: window.screen.width, height: window.screen.height },
|
||||
windowSize: { width: window.innerWidth, height: window.innerHeight },
|
||||
bbbVersion: Meteor.settings.public.app.bbbServerVersion,
|
||||
location: window.location.href,
|
||||
};
|
||||
|
||||
replace({ pathname: path });
|
||||
|
||||
callback();
|
||||
|
||||
logger.info(JSON.stringify(clientInfo));
|
||||
});
|
||||
}
|
||||
|
||||
|
74
bigbluebutton-html5/imports/startup/client/logger.js
Executable file
74
bigbluebutton-html5/imports/startup/client/logger.js
Executable file
@ -0,0 +1,74 @@
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { createLogger, stdSerializers } from 'browser-bunyan';
|
||||
import { ConsoleFormattedStream } from '@browser-bunyan/console-formatted-stream';
|
||||
import { ServerStream } from '@browser-bunyan/server-stream';
|
||||
import { nameFromLevel } from '@browser-bunyan/levels';
|
||||
|
||||
// The logger accepts "console","server", and "url" as targets
|
||||
// Multiple targets can be set as an array in the settings under public.log.target
|
||||
// Set the desired log levels to be sent under public.log.level
|
||||
// The accepted levels are "debug", "info", "warn", "error"
|
||||
// If sending to a url, provide the end-point on public.log.url
|
||||
// Call the logger by doing a function call with the level name, I.e, logger.warn('Hi on warn')
|
||||
|
||||
const LOG_CONFIG = Meteor.settings.public.log || {};
|
||||
const loggerStreams = []; // Stores the targets streams
|
||||
const { fullInfo } = Auth;
|
||||
|
||||
// create a custom stream that logs to an end-point
|
||||
class ServerLoggerStream extends ServerStream {
|
||||
write(rec) {
|
||||
if (fullInfo.meetingId != null) {
|
||||
rec.clientInfo = fullInfo;
|
||||
}
|
||||
return super.write(rec);
|
||||
}
|
||||
}
|
||||
|
||||
// Created a custom stream to log to the meteor server
|
||||
class MeteorStream {
|
||||
write(rec) {
|
||||
if (fullInfo.meetingId != null) {
|
||||
Meteor.call('logClient', nameFromLevel[rec.level], rec.msg, fullInfo);
|
||||
} else {
|
||||
Meteor.call('logClient', nameFromLevel[rec.level], rec.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks to see which targets have been chosen
|
||||
if (LOG_CONFIG.target.includes('console')) {
|
||||
loggerStreams.unshift({
|
||||
level: LOG_CONFIG.level, // sends logs that are this level and higher
|
||||
stream: new ConsoleFormattedStream(),
|
||||
});
|
||||
}
|
||||
|
||||
if (LOG_CONFIG.target.includes('server')) {
|
||||
loggerStreams.unshift({
|
||||
level: LOG_CONFIG.level,
|
||||
stream: new MeteorStream(),
|
||||
});
|
||||
}
|
||||
|
||||
if (LOG_CONFIG.target.includes('url')) {
|
||||
loggerStreams.unshift({
|
||||
level: LOG_CONFIG.level,
|
||||
stream: new ServerLoggerStream({
|
||||
url: LOG_CONFIG.url,
|
||||
method: 'PUT',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
// Creates the logger with the array of streams of the chosen targets
|
||||
const logger = createLogger({
|
||||
name: 'clientLogger',
|
||||
streams: loggerStreams,
|
||||
serializers: stdSerializers,
|
||||
src: true,
|
||||
});
|
||||
|
||||
|
||||
export default logger;
|
53
bigbluebutton-html5/imports/ui/services/auth/index.js
Normal file → Executable file
53
bigbluebutton-html5/imports/ui/services/auth/index.js
Normal file → Executable file
@ -15,6 +15,9 @@ class Auth {
|
||||
this._authToken = Storage.getItem('authToken');
|
||||
this._sessionToken = Storage.getItem('sessionToken');
|
||||
this._logoutURL = Storage.getItem('logoutURL');
|
||||
this._confname = Storage.getItem('confname');
|
||||
this._externUserID = Storage.getItem('externUserID');
|
||||
this._fullname = Storage.getItem('fullname');
|
||||
this._loggedIn = {
|
||||
value: false,
|
||||
tracker: new Tracker.Dependency(),
|
||||
@ -66,6 +69,33 @@ class Auth {
|
||||
return this._logoutURL;
|
||||
}
|
||||
|
||||
set confname(confname) {
|
||||
this._confname = confname;
|
||||
Storage.setItem('confname', this._confname);
|
||||
}
|
||||
|
||||
get confname() {
|
||||
return this._confname;
|
||||
}
|
||||
|
||||
set externUserID(externUserID) {
|
||||
this._externUserID = externUserID;
|
||||
Storage.setItem('externUserID', this._externUserID);
|
||||
}
|
||||
|
||||
get externUserID() {
|
||||
return this._externUserID;
|
||||
}
|
||||
|
||||
set fullname(fullname) {
|
||||
this._fullname = fullname;
|
||||
Storage.setItem('fullname', this._fullname);
|
||||
}
|
||||
|
||||
get fullname() {
|
||||
return this._fullname;
|
||||
}
|
||||
|
||||
get loggedIn() {
|
||||
this._loggedIn.tracker.depend();
|
||||
return this._loggedIn.value;
|
||||
@ -83,15 +113,32 @@ class Auth {
|
||||
requesterToken: this.token,
|
||||
logoutURL: this.logoutURL,
|
||||
sessionToken: this.sessionToken,
|
||||
fullname: this.fullname,
|
||||
externUserID: this.externUserID,
|
||||
confname: this.confname
|
||||
};
|
||||
}
|
||||
|
||||
set(meetingId, requesterUserId, requesterToken, logoutURL, sessionToken) {
|
||||
get fullInfo() {
|
||||
return {
|
||||
sessionToken: this.sessionToken,
|
||||
meetingId: this.meetingID,
|
||||
requesterUserId: this.userID,
|
||||
fullname: this.fullname,
|
||||
confname: this.confname,
|
||||
externUserID: this.externUserID,
|
||||
};
|
||||
}
|
||||
|
||||
set(meetingId, requesterUserId, requesterToken, logoutURL, sessionToken, fullname, externUserID, confname) {
|
||||
this.meetingID = meetingId;
|
||||
this.userID = requesterUserId;
|
||||
this.token = requesterToken;
|
||||
this.logoutURL = logoutURL;
|
||||
this.sessionToken = sessionToken;
|
||||
this.fullname = fullname;
|
||||
this.externUserID = externUserID;
|
||||
this.confname = confname;
|
||||
}
|
||||
|
||||
clearCredentials(...args) {
|
||||
@ -101,7 +148,9 @@ class Auth {
|
||||
this.loggedIn = false;
|
||||
this.logoutURL = null;
|
||||
this.sessionToken = null;
|
||||
|
||||
this.fullname = null;
|
||||
this.externUserID = null
|
||||
this.confname = null;
|
||||
return Promise.resolve(...args);
|
||||
}
|
||||
|
||||
|
39
bigbluebutton-html5/package-lock.json
generated
39
bigbluebutton-html5/package-lock.json
generated
@ -3,6 +3,32 @@
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@browser-bunyan/console-formatted-stream": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@browser-bunyan/console-formatted-stream/-/console-formatted-stream-1.3.0.tgz",
|
||||
"integrity": "sha1-PcBZqlwbKnofJuJwbiveuaCbvlc=",
|
||||
"requires": {
|
||||
"@browser-bunyan/levels": "1.3.0"
|
||||
}
|
||||
},
|
||||
"@browser-bunyan/console-raw-stream": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@browser-bunyan/console-raw-stream/-/console-raw-stream-1.3.0.tgz",
|
||||
"integrity": "sha1-zPJLVvImUFgpfGUX++zqhOu3gYw=",
|
||||
"requires": {
|
||||
"@browser-bunyan/levels": "1.3.0"
|
||||
}
|
||||
},
|
||||
"@browser-bunyan/levels": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@browser-bunyan/levels/-/levels-1.3.0.tgz",
|
||||
"integrity": "sha1-oFIwOuXRofm2Pus6lElaL0KfSDE="
|
||||
},
|
||||
"@browser-bunyan/server-stream": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@browser-bunyan/server-stream/-/server-stream-1.3.0.tgz",
|
||||
"integrity": "sha1-U7MlP6T8WA6GrZoWNqA6ISo0W1Y="
|
||||
},
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
@ -401,6 +427,19 @@
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
"browser-bunyan": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/browser-bunyan/-/browser-bunyan-1.3.0.tgz",
|
||||
"integrity": "sha1-JjeNxY16mAAsyb/Pui6l1xJEmZI=",
|
||||
"requires": {
|
||||
"@browser-bunyan/console-formatted-stream": "1.3.0",
|
||||
"@browser-bunyan/console-raw-stream": "1.3.0",
|
||||
"@browser-bunyan/levels": "1.3.0"
|
||||
}
|
||||
},
|
||||
>>>>>>> 33222e3... Client logger configured
|
||||
"browser-detect": {
|
||||
"version": "0.2.28",
|
||||
"resolved": "https://registry.npmjs.org/browser-detect/-/browser-detect-0.2.28.tgz",
|
||||
|
@ -28,7 +28,9 @@
|
||||
"but Meteor 1.6.0.1 doesn't see it there for some reason",
|
||||
"need to investigate"
|
||||
],
|
||||
"@browser-bunyan/server-stream": "^1.3.0",
|
||||
"babel-runtime": "~6.26.0",
|
||||
"browser-bunyan": "^1.3.0",
|
||||
"browser-detect": "^0.2.28",
|
||||
"classnames": "~2.2.5",
|
||||
"clipboard": "~1.7.1",
|
||||
|
@ -336,6 +336,12 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
},
|
||||
"log": {
|
||||
"level":"info",
|
||||
"target": ["server"],
|
||||
"url":""
|
||||
}
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user