From 7d3ca0c3cf9d731aab571a3c0c318ab8188d65e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 5 Oct 2024 00:46:35 +0200 Subject: [PATCH] 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: --- js/extensions/sharedInternals.js | 75 ++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/js/extensions/sharedInternals.js b/js/extensions/sharedInternals.js index 5c093c336..d066761b3 100644 --- a/js/extensions/sharedInternals.js +++ b/js/extensions/sharedInternals.js @@ -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(); + } +}