diff --git a/index.html b/index.html index 3f077e04..55e7f0b2 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,7 @@ legacyBundle: "lib/olm/olm_legacy.js", wasmBundle: "lib/olm/olm.js", } - })); + }, null, {development: true})); diff --git a/src/logging/BaseLogger.js b/src/logging/BaseLogger.js index 1d231b90..584c763b 100644 --- a/src/logging/BaseLogger.js +++ b/src/logging/BaseLogger.js @@ -1,5 +1,6 @@ /* Copyright 2020 Bruno Windels +Copyright 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,7 +27,7 @@ export class BaseLogger { log(labelOrValues, logLevel = LogLevel.Info) { const item = new LogItem(labelOrValues, logLevel, null, this); item._end = item._start; - this._persistItem(item.serialize(null)); + this._persistItem(item, null, false); } /** if item is a log item, wrap the callback in a child of it, otherwise start a new root log item. */ @@ -79,12 +80,9 @@ export class BaseLogger { filter = filter.minLevel(logLevel); } try { - const serialized = item.serialize(filter); - if (serialized) { - this._persistItem(serialized); - } + this._persistItem(item, filter, false); } catch (err) { - console.error("Could not serialize log item", err); + console.error("Could not persist log item", err); } this._openItems.delete(item); }; @@ -120,11 +118,8 @@ export class BaseLogger { // for now, serialize with an all-permitting filter // as the createFilter function would get a distorted image anyway // about the duration of the item, etc ... - const serialized = openItem.serialize(new LogFilter(), 0); - if (serialized) { - serialized.f = true; //(f)orced - this._persistItem(serialized); - } + // true for force finish + this._persistItem(openItem, new LogFilter(), true); } catch (err) { console.error("Could not serialize log item", err); } diff --git a/src/logging/ConsoleLogger.js b/src/logging/ConsoleLogger.js new file mode 100644 index 00000000..cac128fb --- /dev/null +++ b/src/logging/ConsoleLogger.js @@ -0,0 +1,86 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import {BaseLogger} from "./BaseLogger.js"; + +export class ConsoleLogger extends BaseLogger { + _persistItem(item) { + printToConsole(item); + } +} + + +const excludedKeysFromTable = ["l", "id"]; +function filterValues(values) { + if (!values) { + return null; + } + return Object.entries(values) + .filter(([key]) => !excludedKeysFromTable.includes(key)) + .reduce((obj, [key, value]) => { + obj = obj || {}; + obj[key] = value; + return obj; + }, null); +} + +function printToConsole(item) { + const label = `${itemCaption(item)} (${item.duration}ms)`; + const filteredValues = filterValues(item._values); + const shouldGroup = item._children || filteredValues; + if (shouldGroup) { + if (item.error) { + console.group(label); + } else { + console.groupCollapsed(label); + } + if (item.error) { + console.error(item.error); + } + } else { + if (item.error) { + console.error(item.error); + } else { + console.log(label); + } + } + if (filteredValues) { + console.table(filteredValues); + } + if (item._children) { + for(const c of item._children) { + printToConsole(c); + } + } + if (shouldGroup) { + console.groupEnd(); + } +} + +function itemCaption(item) { + if (item._values?.t === "network") { + return `${item._values?.method} ${item._values?.url}`; + } else if (item._values.l && item._values?.id) { + return `${item._values.l} ${item._values.id}`; + } else if (item._values.l && item._values?.status) { + return `${item._values.l} (${item._values.status})`; + } else if (item._values.l && item.error) { + return `${item._values.l} failed`; + } else if (item._values.ref) { + return `ref ${item._values.ref}` + } else { + return item._values.l || item._values?.type; + } +} diff --git a/src/logging/IDBLogger.js b/src/logging/IDBLogger.js index b4c52edb..96578cd0 100644 --- a/src/logging/IDBLogger.js +++ b/src/logging/IDBLogger.js @@ -1,5 +1,6 @@ /* Copyright 2020 Bruno Windels +Copyright 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -100,7 +101,8 @@ export class IDBLogger extends BaseLogger { return openDatabase(this._name, db => db.createObjectStore("logs", {keyPath: "id", autoIncrement: true}), 1); } - _persistItem(serializedItem) { + _persistItem(logItem, filter, forced) { + const serializedItem = logItem.serialize(filter, forced); this._queuedItems.push({ json: JSON.stringify(serializedItem) }); diff --git a/src/logging/LogFilter.js b/src/logging/LogFilter.js index 76bebcf1..81bbb33c 100644 --- a/src/logging/LogFilter.js +++ b/src/logging/LogFilter.js @@ -1,5 +1,5 @@ /* -Copyright 2020 Bruno Windels +Copyright 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/logging/LogItem.js b/src/logging/LogItem.js index cddcfecf..28f02d8e 100644 --- a/src/logging/LogItem.js +++ b/src/logging/LogItem.js @@ -1,5 +1,6 @@ /* Copyright 2020 Bruno Windels +Copyright 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -100,7 +101,7 @@ export class LogItem { } } - serialize(filter, parentStartTime = null) { + serialize(filter, parentStartTime = null, forced) { if (this._filterCreator) { try { filter = this._filterCreator(new LogFilter(filter), this); @@ -111,7 +112,7 @@ export class LogItem { let children; if (this._children !== null) { children = this._children.reduce((array, c) => { - const s = c.serialize(filter, this._start); + const s = c.serialize(filter, this._start, false); if (s) { if (array === null) { array = []; @@ -142,11 +143,13 @@ export class LogItem { name: this.error.name }; } + if (forced) { + item.f = true; //(f)orced + } if (children) { // (c)hildren item.c = children; } - // (f)orced can also be set on an item by the logger return item; } diff --git a/src/logging/NullLogger.js b/src/logging/NullLogger.js index b9e5e72b..0842e4c0 100644 --- a/src/logging/NullLogger.js +++ b/src/logging/NullLogger.js @@ -1,5 +1,5 @@ /* -Copyright 2020 Bruno Windels +Copyright 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ limitations under the License. */ import {LogLevel} from "./LogFilter.js"; +// TODO: add missing methods export class NullLogger { constructor() { this._item = new NullLogItem(); diff --git a/src/platform/web/Platform.js b/src/platform/web/Platform.js index 7bd81471..b3b6bccf 100644 --- a/src/platform/web/Platform.js +++ b/src/platform/web/Platform.js @@ -22,6 +22,7 @@ import {SettingsStorage} from "./dom/SettingsStorage.js"; import {Encoding} from "./utils/Encoding.js"; import {OlmWorker} from "../../matrix/e2ee/OlmWorker.js"; import {IDBLogger} from "../../logging/IDBLogger.js"; +import {ConsoleLogger} from "../../logging/ConsoleLogger.js"; import {RootView} from "./ui/RootView.js"; import {Clock} from "./dom/Clock.js"; import {ServiceWorkerHandler} from "./dom/ServiceWorkerHandler.js"; @@ -82,14 +83,18 @@ async function loadOlmWorker(paths) { } export class Platform { - constructor(container, paths, cryptoExtras = null) { + constructor(container, paths, cryptoExtras = null, options = null) { this._paths = paths; this._container = container; this.settingsStorage = new SettingsStorage("hydrogen_setting_v1_"); this.clock = new Clock(); this.encoding = new Encoding(); this.random = Math.random; - this.logger = new IDBLogger({name: "hydrogen_logs", platform: this}); + if (options?.development) { + this.logger = new ConsoleLogger({platform: this}); + } else { + this.logger = new IDBLogger({name: "hydrogen_logs", platform: this}); + } this.history = new History(); this.onlineStatus = new OnlineStatus(); this._serviceWorkerHandler = null;