[jsscripting] Fix console logger name & timer identifier missing for UI scripts (#17171)

* [jsscripting] Fix console logger name is missing for UI scripts
* [jsscripting] Fix timer identifier "missing" for setTimeout/setInterval for UI scripts

Fixes #17165.
Caused by https://github.com/openhab/openhab-core/pull/4289.

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
This commit is contained in:
Florian Hotze 2024-07-29 17:07:29 +02:00 committed by GitHub
parent 4376b9db73
commit 20251feb09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,21 +1,37 @@
// ThreadsafeTimers is injected into the JS runtime
// The default identifier of the script has to be computed on script executon, as it is not available at the time of script compilation
(function (global) {
'use strict';
// Append the script file name OR rule UID depending on which is available
const defaultIdentifier = 'org.openhab.automation.script' + (globalThis['javax.script.filename'] ? '.file.' + globalThis['javax.script.filename'].replace(/^.*[\\\/]/, '') : globalThis.ruleUID ? '.ui.' + globalThis.ruleUID : '');
const System = Java.type('java.lang.System');
const formatRegExp = /%[sdj%]/g;
// Pass the defaultIdentifier to ThreadsafeTimers to enable naming of scheduled jobs
ThreadsafeTimers.setIdentifier(defaultIdentifier);
function createLogger (name = defaultIdentifier) {
return Java.type('org.slf4j.LoggerFactory').getLogger(name);
/**
* Gets the default identifier of the script.
* @returns {string}
*/
function getDefaultIdentifier () {
return 'org.openhab.automation.script' + (globalThis['javax.script.filename'] ? '.file.' + globalThis['javax.script.filename'].replace(/^.*[\\\/]/, '') : globalThis.ruleUID ? '.ui.' + globalThis.ruleUID : '');
}
// User configurable
let log = createLogger();
/**
* Gets a logger instance for given name.
* @param {string} [name] optional logger name, defaults to the default identifier of the script (see {@link getDefaultIdentifier})
* @returns {*} logger instance
*/
function getLogger (name) {
if (typeof name === 'string') {
log = Java.type('org.slf4j.LoggerFactory').getLogger(name);
}
if (log === null) {
log = Java.type('org.slf4j.LoggerFactory').getLogger(getDefaultIdentifier());
}
return log;
}
let log = null;
function stringify (value) {
try {
@ -86,7 +102,7 @@
const console = {
assert: function (expression, message) {
if (!expression) {
log.error(message);
getLogger().error(message);
}
},
@ -102,32 +118,32 @@
// update
counters[label] = ++counter;
log.debug(format.apply(null, [label + ':', counter]));
getLogger().debug(format.apply(null, [label + ':', counter]));
}
},
debug: function () {
log.debug(format.apply(null, arguments));
getLogger().debug(format.apply(null, arguments));
},
info: function () {
log.info(format.apply(null, arguments));
getLogger().info(format.apply(null, arguments));
},
log: function () {
log.info(format.apply(null, arguments));
getLogger().info(format.apply(null, arguments));
},
warn: function () {
log.warn(format.apply(null, arguments));
getLogger().warn(format.apply(null, arguments));
},
error: function () {
log.error(format.apply(null, arguments));
getLogger().error(format.apply(null, arguments));
},
trace: function () {
log.trace(new Error(format.apply(null, arguments)).stack.replace(/^Error: /, ''));
getLogger().trace(new Error(format.apply(null, arguments)).stack.replace(/^Error: /, ''));
},
time: function (label) {
@ -140,10 +156,10 @@
if (label) {
const now = System.currentTimeMillis();
if (timers.hasOwnProperty(label)) {
log.info(format.apply(null, [label + ':', (now - timers[label]) + 'ms']));
getLogger().info(format.apply(null, [label + ':', (now - timers[label]) + 'ms']));
delete timers[label];
} else {
log.info(format.apply(null, [label + ':', '<no timer>']));
getLogger().info(format.apply(null, [label + ':', '<no timer>']));
}
}
},
@ -151,23 +167,25 @@
// Allow user customizable logging names
// Be aware that a log4j2 required a logger defined for the logger name, otherwise messages won't be logged!
set loggerName (name) {
log = createLogger(name);
getLogger(name);
this._loggerName = name;
ThreadsafeTimers.setIdentifier(name);
},
get loggerName () {
return this._loggerName || defaultIdentifier;
return this._loggerName || getDefaultIdentifier();
}
};
// Polyfill common NodeJS functions onto the global object
globalThis.console = console;
globalThis.setTimeout = function (functionRef, delay, ...args) {
ThreadsafeTimers.setIdentifier(console.loggerName);
return ThreadsafeTimers.setTimeout(() => functionRef(...args), delay);
};
globalThis.clearTimeout = ThreadsafeTimers.clearTimeout;
globalThis.setInterval = function (functionRef, delay, ...args) {
ThreadsafeTimers.setIdentifier(console.loggerName);
return ThreadsafeTimers.setInterval(() => functionRef(...args), delay);
};
globalThis.clearInterval = ThreadsafeTimers.clearInterval;