extensions: Add convenience logging API

This allows extension to create a custom `console` object that
marks message to belonging to the extension.

Right now that means prefixing each message with the extension name,
but in the future it could also set custom journal fields if gjs
starts exposing that functionality.

See https://discourse.gnome.org/t/convenience-logging-api-for-extensions/24361
for the original discussion.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3586>
This commit is contained in:
Florian Müllner 2024-10-05 00:46:35 +02:00 committed by Marge Bot
parent 2c9e75252a
commit 7d3ca0c3cf

View File

@ -8,6 +8,7 @@ import * as Config from '../misc/config.js';
export class ExtensionBase {
#gettextDomain;
#console;
/**
* Look up an extension by URL (usually 'import.meta.url')
@ -110,6 +111,15 @@ export class ExtensionBase {
return new Gio.Settings({settings_schema: schemaObj});
}
/**
* @returns {Console}
*/
getLogger() {
if (!this.#console)
this.#console = new Console(this);
return this.#console;
}
/**
* Initialize Gettext to load translations from extensionsdir/locale. If
* domain is not provided, it will be taken from metadata['gettext-domain']
@ -271,3 +281,68 @@ export class GettextWrapper {
};
}
}
class Console {
#extension;
constructor(ext) {
this.#extension = ext;
}
#prefixArgs(first, ...args) {
return [`[${this.#extension.metadata.name}] ${first}`, ...args];
}
log(...args) {
globalThis.console.log(...this.#prefixArgs(...args));
}
warn(...args) {
globalThis.console.warn(...this.#prefixArgs(...args));
}
error(...args) {
globalThis.console.error(...this.#prefixArgs(...args));
}
info(...args) {
globalThis.console.info(...this.#prefixArgs(...args));
}
debug(...args) {
globalThis.console.debug(...this.#prefixArgs(...args));
}
assert(condition, ...args) {
if (condition)
return;
const message = 'Assertion failed';
if (args.length === 0)
args.push(message);
if (typeof args[0] !== 'string') {
args.unshift(message);
} else {
const first = args.shift();
args.unshift(`${message}: ${first}`);
}
globalThis.console.error(...this.#prefixArgs(...args));
}
trace(...args) {
if (args.length === 0)
args = ['Trace'];
globalThis.console.trace(...this.#prefixArgs(...args));
}
group(...args) {
globalThis.console.group(...this.#prefixArgs(...args));
}
groupEnd() {
globalThis.console.groupEnd();
}
}