From 4d7ab1cfd67846ad45526052e7345bf44fe3e03a Mon Sep 17 00:00:00 2001 From: Timo Date: Wed, 16 Apr 2025 19:31:50 +0200 Subject: [PATCH 1/8] use methodFactory extensions from the rootLogger in child loggers. --- src/logger.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index da381b47b72..2db7e010328 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import loglevel from "loglevel"; +import loglevel, { LoggingMethod } from "loglevel"; /** Backwards-compatibility hack to expose `log` to applications that might still be relying on it. */ interface LoggerWithLogMethod extends Logger { @@ -135,7 +135,22 @@ function getPrefixedLogger(prefix?: string): LoggerWithLogMethod { if (prefixLogger.getChild === undefined) { // This is a new loglevel Logger which has not been turned into a PrefixedLogger yet. prefixLogger.prefix = prefix; - prefixLogger.getChild = (childPrefix): Logger => getPrefixedLogger((prefix ?? "") + childPrefix); + prefixLogger.getChild = (childPrefix): Logger => { + const childLogger = getPrefixedLogger((prefix ?? "") + childPrefix) as unknown as loglevel.Logger; + childLogger.methodFactory = (methodName, configLevel, loggerName): LoggingMethod => { + const method = (logger as unknown as loglevel.Logger).methodFactory( + methodName, + configLevel, + loggerName, + ); + return (...args): void => { + method.apply(childLogger, args); + }; + }; + childLogger.setLevel(childLogger.getLevel()); + + return childLogger as unknown as Logger; + }; prefixLogger.setLevel(loglevel.levels.DEBUG, false); } From 3a80fc829785ec38b258a7161fa4578a6e177a57 Mon Sep 17 00:00:00 2001 From: Timo Date: Thu, 17 Apr 2025 13:07:48 +0200 Subject: [PATCH 2/8] use simple method factory copy AND `childLogger.setLevel(childLogger.getLevel());` This is the important part that actually registers the new methods. --- src/logger.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index 2db7e010328..fcd854e4e7c 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import loglevel, { LoggingMethod } from "loglevel"; +import loglevel from "loglevel"; /** Backwards-compatibility hack to expose `log` to applications that might still be relying on it. */ interface LoggerWithLogMethod extends Logger { @@ -137,18 +137,8 @@ function getPrefixedLogger(prefix?: string): LoggerWithLogMethod { prefixLogger.prefix = prefix; prefixLogger.getChild = (childPrefix): Logger => { const childLogger = getPrefixedLogger((prefix ?? "") + childPrefix) as unknown as loglevel.Logger; - childLogger.methodFactory = (methodName, configLevel, loggerName): LoggingMethod => { - const method = (logger as unknown as loglevel.Logger).methodFactory( - methodName, - configLevel, - loggerName, - ); - return (...args): void => { - method.apply(childLogger, args); - }; - }; + childLogger.methodFactory = (logger as unknown as loglevel.Logger).methodFactory; childLogger.setLevel(childLogger.getLevel()); - return childLogger as unknown as Logger; }; prefixLogger.setLevel(loglevel.levels.DEBUG, false); From 7a025e4b198fedfa05532a101f88b66a85dd5379 Mon Sep 17 00:00:00 2001 From: Timo Date: Thu, 17 Apr 2025 20:30:24 +0200 Subject: [PATCH 3/8] add comments and find a way to make it clearer that the types are correct. --- src/logger.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index fcd854e4e7c..457de169332 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -128,18 +128,25 @@ interface PrefixedLogger extends loglevel.Logger, LoggerWithLogMethod { * * @param prefix Prefix to add to each logged line. If undefined, no prefix will be added. */ -function getPrefixedLogger(prefix?: string): LoggerWithLogMethod { +function getPrefixedLogger(prefix?: string): PrefixedLogger { const loggerName = DEFAULT_NAMESPACE + (prefix === undefined ? "" : `-${prefix}`); const prefixLogger = loglevel.getLogger(loggerName) as PrefixedLogger; - + // This is a save cast since export const logger is constructed with getPrefixedLogger + // It is downcastet to `Logger` to minimize the public/exported api. if (prefixLogger.getChild === undefined) { // This is a new loglevel Logger which has not been turned into a PrefixedLogger yet. prefixLogger.prefix = prefix; prefixLogger.getChild = (childPrefix): Logger => { - const childLogger = getPrefixedLogger((prefix ?? "") + childPrefix) as unknown as loglevel.Logger; - childLogger.methodFactory = (logger as unknown as loglevel.Logger).methodFactory; - childLogger.setLevel(childLogger.getLevel()); - return childLogger as unknown as Logger; + const rootLogger = logger as PrefixedLogger; + // create the new child logger + const childLogger = getPrefixedLogger((prefix ?? "") + childPrefix); + // assign the same methodFactory as the root logger. + // this is useful if we add extensions to the root logger that modify + // its methodFactory. (an example extension is: storing each log to a rageshake db) + childLogger.methodFactory = rootLogger.methodFactory; + // rebuild the child logger with the new methodFactory. + childLogger.rebuild(); + return childLogger as Logger; }; prefixLogger.setLevel(loglevel.levels.DEBUG, false); } @@ -151,7 +158,7 @@ function getPrefixedLogger(prefix?: string): LoggerWithLogMethod { * Drop-in replacement for `console` using {@link https://www.npmjs.com/package/loglevel|loglevel}. * Can be tailored down to specific use cases if needed. */ -export const logger = getPrefixedLogger(); +export const logger = getPrefixedLogger() as LoggerWithLogMethod; /** * A "span" for grouping related log lines together. From b9a0660a3b3e8e57854f4500aef3df3d59ec5f4e Mon Sep 17 00:00:00 2001 From: Timo Date: Fri, 18 Apr 2025 17:20:52 +0200 Subject: [PATCH 4/8] review --- src/logger.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index 457de169332..08e56a436b7 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -131,22 +131,20 @@ interface PrefixedLogger extends loglevel.Logger, LoggerWithLogMethod { function getPrefixedLogger(prefix?: string): PrefixedLogger { const loggerName = DEFAULT_NAMESPACE + (prefix === undefined ? "" : `-${prefix}`); const prefixLogger = loglevel.getLogger(loggerName) as PrefixedLogger; - // This is a save cast since export const logger is constructed with getPrefixedLogger - // It is downcastet to `Logger` to minimize the public/exported api. + if (prefixLogger.getChild === undefined) { // This is a new loglevel Logger which has not been turned into a PrefixedLogger yet. prefixLogger.prefix = prefix; prefixLogger.getChild = (childPrefix): Logger => { - const rootLogger = logger as PrefixedLogger; // create the new child logger const childLogger = getPrefixedLogger((prefix ?? "") + childPrefix); // assign the same methodFactory as the root logger. // this is useful if we add extensions to the root logger that modify // its methodFactory. (an example extension is: storing each log to a rageshake db) - childLogger.methodFactory = rootLogger.methodFactory; + childLogger.methodFactory = prefixLogger.methodFactory; // rebuild the child logger with the new methodFactory. childLogger.rebuild(); - return childLogger as Logger; + return childLogger; }; prefixLogger.setLevel(loglevel.levels.DEBUG, false); } From 361c636d5a2cd08326da8067c0a474c58826de23 Mon Sep 17 00:00:00 2001 From: Timo Date: Fri, 18 Apr 2025 17:36:10 +0200 Subject: [PATCH 5/8] additionally fix MatrixRTCSessionManager being initialized before the extension is in place. --- src/matrixrtc/MatrixRTCSessionManager.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/matrixrtc/MatrixRTCSessionManager.ts b/src/matrixrtc/MatrixRTCSessionManager.ts index d3db4accea2..02a3f20c436 100644 --- a/src/matrixrtc/MatrixRTCSessionManager.ts +++ b/src/matrixrtc/MatrixRTCSessionManager.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { logger as rootLogger } from "../logger.ts"; +import { logger as rootLogger, type Logger } from "../logger.ts"; import { type MatrixClient, ClientEvent } from "../client.ts"; import { TypedEventEmitter } from "../models/typed-event-emitter.ts"; import { type Room } from "../models/room.ts"; @@ -23,8 +23,6 @@ import { type MatrixEvent } from "../models/event.ts"; import { MatrixRTCSession } from "./MatrixRTCSession.ts"; import { EventType } from "../@types/event.ts"; -const logger = rootLogger.getChild("[MatrixRTCSessionManager]"); - export enum MatrixRTCSessionManagerEvents { // A member has joined the MatrixRTC session, creating an active session in a room where there wasn't previously SessionStarted = "session_started", @@ -50,8 +48,10 @@ export class MatrixRTCSessionManager extends TypedEventEmitter(); + private logger: Logger; public constructor(private client: MatrixClient) { super(); + this.logger = rootLogger.getChild("[MatrixRTCSessionManager]"); } public start(): void { @@ -105,7 +105,7 @@ export class MatrixRTCSessionManager extends TypedEventEmitter { const room = this.client.getRoom(event.getRoomId()); if (!room) { - logger.error(`Got room state event for unknown room ${event.getRoomId()}!`); + this.logger.error(`Got room state event for unknown room ${event.getRoomId()}!`); return; } @@ -129,10 +129,10 @@ export class MatrixRTCSessionManager extends TypedEventEmitter 0; if (wasActiveAndKnown && !nowActive) { - logger.trace(`Session ended for ${room.roomId} (${session.memberships.length} members)`); + this.logger.trace(`Session ended for ${room.roomId} (${session.memberships.length} members)`); this.emit(MatrixRTCSessionManagerEvents.SessionEnded, room.roomId, this.roomSessions.get(room.roomId)!); } else if (!wasActiveAndKnown && nowActive) { - logger.trace(`Session started for ${room.roomId} (${session.memberships.length} members)`); + this.logger.trace(`Session started for ${room.roomId} (${session.memberships.length} members)`); this.emit(MatrixRTCSessionManagerEvents.SessionStarted, room.roomId, this.roomSessions.get(room.roomId)!); } } From ec385ec1ff5d12b1742a23f64fc77e57fbf9205a Mon Sep 17 00:00:00 2001 From: Timo Date: Tue, 22 Apr 2025 12:31:42 +0200 Subject: [PATCH 6/8] Add comment to clarify order of log extensions and creating childs. --- src/logger.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/logger.ts b/src/logger.ts index 08e56a436b7..09ac55de0b4 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -33,6 +33,10 @@ interface LoggerWithLogMethod extends Logger { export interface Logger extends BaseLogger { /** * Create a child logger. + * This child will apply the methodFactory of the parent. So any log extensions applied to the parent + * at the time of calling `getChild` will be applied to the child as well. + * It will NOT apply changes to the parents methodFactory after the child was created. + * Those changes will not be applied manually to the child. * * @param namespace - name to add to the current logger to generate the child. Some implementations of `Logger` * use this as a prefix; others use a different mechanism. From 54ecd1f14f386b4eb0ba11b480455726860130c8 Mon Sep 17 00:00:00 2001 From: Timo Date: Tue, 22 Apr 2025 16:39:56 +0200 Subject: [PATCH 7/8] review --- src/logger.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index 09ac55de0b4..a3ab9d3bd53 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -33,10 +33,11 @@ interface LoggerWithLogMethod extends Logger { export interface Logger extends BaseLogger { /** * Create a child logger. - * This child will apply the methodFactory of the parent. So any log extensions applied to the parent + * + * This child will use the `methodFactory` of the parent, so any log extensions applied to the parent * at the time of calling `getChild` will be applied to the child as well. - * It will NOT apply changes to the parents methodFactory after the child was created. - * Those changes will not be applied manually to the child. + * It will NOT apply changes to the parent's `methodFactory` after the child was created. + * Those changes need to be applied to the child manually. * * @param namespace - name to add to the current logger to generate the child. Some implementations of `Logger` * use this as a prefix; others use a different mechanism. @@ -142,11 +143,11 @@ function getPrefixedLogger(prefix?: string): PrefixedLogger { prefixLogger.getChild = (childPrefix): Logger => { // create the new child logger const childLogger = getPrefixedLogger((prefix ?? "") + childPrefix); - // assign the same methodFactory as the root logger. - // this is useful if we add extensions to the root logger that modify - // its methodFactory. (an example extension is: storing each log to a rageshake db) + // Assign the methodFactory from the parent logger. + // This is useful if we add extensions to the parent logger that modifies + // its methodFactory. (An example extension is: storing each log to a rageshake db) childLogger.methodFactory = prefixLogger.methodFactory; - // rebuild the child logger with the new methodFactory. + // Rebuild the child logger with the new methodFactory. childLogger.rebuild(); return childLogger; }; From 4131970ae2188e749562288ad81f5e17721d892d Mon Sep 17 00:00:00 2001 From: Timo Date: Tue, 22 Apr 2025 17:41:36 +0200 Subject: [PATCH 8/8] Set "loglevel" min version to guarantee access to `logger.rebuild` --- package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c4d264e58e3..9b094f4f397 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "bs58": "^6.0.0", "content-type": "^1.0.4", "jwt-decode": "^4.0.0", - "loglevel": "^1.7.1", + "loglevel": "^1.9.2", "matrix-events-sdk": "0.0.1", "matrix-widget-api": "^1.10.0", "oidc-client-ts": "^3.0.1", diff --git a/yarn.lock b/yarn.lock index 1705d25db0d..45d5011bb62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5081,7 +5081,7 @@ log-update@^6.1.0: strip-ansi "^7.1.0" wrap-ansi "^9.0.0" -loglevel@^1.7.1: +loglevel@^1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.2.tgz#c2e028d6c757720107df4e64508530db6621ba08" integrity sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==