[Logger] Track origin of the call stack. Allow blacklisting of some periodic calls
This commit is contained in:
parent
3e565ddbfc
commit
0cbd62352e
@ -144,8 +144,71 @@ class Logger {
|
||||
this.temp_disable = false;
|
||||
}
|
||||
|
||||
canLog(component) {
|
||||
return this.conf.allowLogging && (this.canLogFile(component) || this.canLogConsole(component));
|
||||
parseStack() {
|
||||
const trace = (new Error()).stack;
|
||||
|
||||
const stackInfo = {};
|
||||
// we turn our stack into array and remove the "file::line" part of the trace,
|
||||
// since that is useless because minification/webpack
|
||||
stackInfo['stack'] = {trace: trace.split('\n').map(a => a.split('@')[0])};
|
||||
|
||||
// here's possible sources that led to this log entry
|
||||
stackInfo['periodicPlayerCheck'] = false;
|
||||
stackInfo['periodicVideoStyleChangeCheck'] = false;
|
||||
stackInfo['aard'] = false;
|
||||
stackInfo['keyboard'] = false;
|
||||
stackInfo['popup'] = false;
|
||||
|
||||
// here we check which source triggered the action. We know that only one of these
|
||||
// functions will appear in the trace at most once (and if more than one of these
|
||||
// appears — e.g. frameCheck triggered by user toggling autodetection in popup —
|
||||
// the most recent one will be the correct one 99% of the time)
|
||||
for (const line of stackInfo.stack.trace) {
|
||||
if (line.startsWith('doPeriodicPlayerElementChangeCheck')) {
|
||||
stackInfo['periodicPlayerCheck'] = true;
|
||||
break;
|
||||
} else if (line.startsWith('doPeriodicFallbackChangeDetectionCheck')) {
|
||||
stackInfo['periodicVideoStyleChangeCheck'] = true;
|
||||
break;
|
||||
} else if (line.startsWith('frameCheck')) {
|
||||
stackInfo['aard'] = true;
|
||||
break;
|
||||
} else if (line.startsWith('execAction')) {
|
||||
stackInfo['keyboard'] = true;
|
||||
break;
|
||||
} else if (line.startsWith('processReceivedMessage')) {
|
||||
stackInfo['popup'] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stackInfo;
|
||||
}
|
||||
|
||||
canLog(component, stackInfo) {
|
||||
if (!this.conf.allowLogging) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we call this function from outside of logger,
|
||||
// stackInfo may not be provided. Here's a fallback.
|
||||
if (stackInfo === undefined) {
|
||||
stackInfo = this.parseStack();
|
||||
}
|
||||
|
||||
// check if log belongs to a blacklisted origin. If yes, then only allow content to be logged if the
|
||||
// origin is explicitly whitelisted in the conf object
|
||||
if (stackInfo) {
|
||||
if (stackInfo.periodicPlayerCheck) {
|
||||
return this.conf.allowBlacklistedOrigins && this.conf.allowBlacklistedOrigins.periodicPlayerCheck;
|
||||
}
|
||||
if (stackInfo.periodicVideoStyleChangeCheck) {
|
||||
return this.conf.allowBlacklistedOrigins && this.conf.allowBlacklistedOrigins.periodicVideoStyleChangeCheck;
|
||||
}
|
||||
}
|
||||
|
||||
// if either of these two is true, we allow logging to happen (forbidden origins were checked above)
|
||||
return (this.canLogFile(component) || this.canLogConsole(component));
|
||||
}
|
||||
|
||||
canLogFile(component) {
|
||||
@ -193,9 +256,10 @@ class Logger {
|
||||
if (!this.conf) {
|
||||
return;
|
||||
}
|
||||
const error = new Error();
|
||||
const stackInfo = this.parseStack();
|
||||
|
||||
if (this.conf.fileOptions.enabled) {
|
||||
if (this.canLogFile(component)) {
|
||||
if (this.canLogFile(component, stackInfo)) {
|
||||
let ts = performance.now();
|
||||
if (ts <= this.history[this.history.length - 1]) {
|
||||
ts = this.history[this.history.length - 1] + 0.00001;
|
||||
@ -204,13 +268,13 @@ class Logger {
|
||||
this.history.push({
|
||||
ts: ts,
|
||||
message: JSON.stringify(message),
|
||||
stack: error.stack,
|
||||
stack: stackInfo,
|
||||
})
|
||||
}
|
||||
}
|
||||
if (this.conf.consoleOptions.enabled) {
|
||||
if (this.canLogConsole(component)) {
|
||||
console.log(...message, {stack: error});
|
||||
if (this.canLogConsole(component, stackInfo)) {
|
||||
console.log(...message, {stack: stackInfo});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,18 +127,21 @@ class PlayerData {
|
||||
while (!this.halted) {
|
||||
await this.sleep(1000);
|
||||
try {
|
||||
if (this.periodicallyRefreshPlayerElement) {
|
||||
this.forceRefreshPlayerElement();
|
||||
}
|
||||
if (this.checkPlayerSizeChange()) {
|
||||
this.videoData.resizer.restore();
|
||||
}
|
||||
this.doPeriodicPlayerElementChangeCheck();
|
||||
} catch (e) {
|
||||
console.error('[playerdata::legacycd] this message is pretty high on the list of messages you shouldnt see', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doPeriodicPlayerElementChangeCheck() {
|
||||
if (this.periodicallyRefreshPlayerElement) {
|
||||
if (this.forceDetectPlayerElementChange()) {
|
||||
this.videoData.resizer.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopChangeDetection(){
|
||||
this.observer.disconnect();
|
||||
}
|
||||
@ -232,6 +235,18 @@ class PlayerData {
|
||||
return;
|
||||
}
|
||||
|
||||
// log the entire hierarchy from <video> to root
|
||||
if (this.logger.canLog('playerDetect')) {
|
||||
const logObj = [];
|
||||
logObj.push(`window size: ${window.innerWidth} x ${window.innerHeight}`);
|
||||
let e = element;
|
||||
while (e) {
|
||||
logObj.push({offsetSize: {width: e.offsetWidth, height: e.offsetHeight}, clientSize: {width: e.clientWidth, height: e.clientHeight}, element: e});
|
||||
e = e.parentNode;
|
||||
}
|
||||
this.logger.log('info', 'playerDetect', "\n\n[PlayerDetect::getPlayer()] element hierarchy (video->root)", logObj);
|
||||
}
|
||||
|
||||
if (this.settings.active.sites[host]
|
||||
&& this.settings.active.sites[host].DOM
|
||||
&& this.settings.active.sites[host].DOM.player
|
||||
@ -275,6 +290,9 @@ class PlayerData {
|
||||
element = element.parentNode;
|
||||
}
|
||||
|
||||
// log player candidates
|
||||
this.logger.log('info', 'playerDetect', 'player detect via query selector: element queue and final element:', {queue: elementQ, bestCandidate: elementQ.length ? elementQ.sort( (a,b) => b.score - a.score)[0].element : 'n/a'});
|
||||
|
||||
if (elementQ.length) {
|
||||
// return element with biggest score
|
||||
// if video player has not been found, proceed to automatic detection
|
||||
@ -332,9 +350,13 @@ class PlayerData {
|
||||
element = element.parentNode;
|
||||
}
|
||||
|
||||
// log player candidates
|
||||
this.logger.log('info', 'playerDetect', 'player detect, auto/fallback: element queue and final element:', {queue: elementQ, bestCandidate: elementQ.length ? elementQ.sort( (a,b) => b.score - a.score)[0].element : 'n/a'});
|
||||
|
||||
if (elementQ.length) {
|
||||
// return element with biggest score
|
||||
const playerElement = elementQ.sort( (a,b) => b.score - a.score)[0].element;
|
||||
|
||||
this.updatePlayerDimensions(playerElement);
|
||||
return playerElement;
|
||||
}
|
||||
|
@ -71,10 +71,14 @@ class VideoData {
|
||||
async fallbackChangeDetection() {
|
||||
while (!this.destroyed && !this.invalid) {
|
||||
await this.sleep(500);
|
||||
this.validateVideoOffsets();
|
||||
this.doPeriodicFallbackChangeDetectionCheck();
|
||||
}
|
||||
}
|
||||
|
||||
doPeriodicFallbackChangeDetectionCheck() {
|
||||
this.validateVideoOffsets();
|
||||
}
|
||||
|
||||
async sleep(timeout) {
|
||||
return new Promise( (resolve, reject) => setTimeout(() => resolve(), timeout));
|
||||
}
|
||||
|
@ -55,9 +55,9 @@ class UW {
|
||||
'settings': true,
|
||||
'keyboard': true,
|
||||
'mousemove': false,
|
||||
'actionHandler': false,
|
||||
'comms': false,
|
||||
'playerDetect': false,
|
||||
'actionHandler': true,
|
||||
'comms': true,
|
||||
'playerDetect': true,
|
||||
'resizer': true,
|
||||
'scaler': true,
|
||||
'stretcher': true,
|
||||
@ -65,8 +65,16 @@ class UW {
|
||||
// 'playerRescan': true,
|
||||
'arDetect': true,
|
||||
'arDetect_verbose': true,
|
||||
},
|
||||
allowBlacklistedOrigins: {
|
||||
// logs that were called from functions named here will be excluded from both console logging
|
||||
// as well as logging to file. Exclusions happen because these functions — being periodic in
|
||||
// nature as well as doing a lot of work — usually clog console too fast without providing
|
||||
// any valuable info.
|
||||
'periodicPlayerCheck': true,
|
||||
'periodicVideoStyleChangeCheck': true,
|
||||
}
|
||||
};
|
||||
};
|
||||
this.logger = new Logger();
|
||||
await this.logger.init(loggingOptions);
|
||||
// await this.logger.init(); // not needed if logging options are provided at creation
|
||||
|
Loading…
Reference in New Issue
Block a user