Merge pull request #1592 from vector-im/dbkr/use_loglevel

Use the loglevel library's extensions
This commit is contained in:
David Baker
2023-09-26 11:14:47 +01:00
committed by GitHub
15 changed files with 72 additions and 50 deletions

View File

@@ -33,6 +33,8 @@ module.exports = {
rules: { rules: {
// We're aiming to convert this code to strict mode // We're aiming to convert this code to strict mode
"@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-non-null-assertion": "off",
// We should use the js-sdk logger, never console directly.
"no-console": ["error"],
}, },
}, },
], ],

View File

@@ -19,6 +19,7 @@ import { useLocation } from "react-router-dom";
import classNames from "classnames"; import classNames from "classnames";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import * as Sentry from "@sentry/react"; import * as Sentry from "@sentry/react";
import { logger } from "matrix-js-sdk/src/logger";
import { Header, HeaderLogo, LeftNav, RightNav } from "./Header"; import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
import { LinkButton, Button } from "./button"; import { LinkButton, Button } from "./button";
@@ -57,7 +58,7 @@ export function ErrorView({ error }: ErrorViewProps) {
const { t } = useTranslation(); const { t } = useTranslation();
useEffect(() => { useEffect(() => {
console.error(error); logger.error(error);
Sentry.captureException(error); Sentry.captureException(error);
}, [error]); }, [error]);

View File

@@ -27,6 +27,7 @@ import { useHistory, useLocation } from "react-router-dom";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import { sleep } from "matrix-js-sdk/src/utils"; import { sleep } from "matrix-js-sdk/src/utils";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { logger } from "matrix-js-sdk/src/logger";
import { FieldRow, InputField, ErrorMessage } from "../input/Input"; import { FieldRow, InputField, ErrorMessage } from "../input/Input";
import { Button } from "../button"; import { Button } from "../button";
@@ -97,7 +98,7 @@ export const RegisterPage: FC = () => {
await newClient.joinRoom(roomId); await newClient.joinRoom(roomId);
} else { } else {
captureException(error); captureException(error);
console.error(`Couldn't join room ${roomId}`, error); logger.error(`Couldn't join room ${roomId}`, error);
} }
} }
} }

View File

@@ -17,6 +17,7 @@ limitations under the License.
import { useEffect, useCallback, useRef, useState } from "react"; import { useEffect, useCallback, useRef, useState } from "react";
import { randomString } from "matrix-js-sdk/src/randomstring"; import { randomString } from "matrix-js-sdk/src/randomstring";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { logger } from "matrix-js-sdk/src/logger";
import { translatedError } from "../TranslatedError"; import { translatedError } from "../TranslatedError";
@@ -74,7 +75,7 @@ export const useRecaptcha = (sitekey?: string) => {
} }
if (!window.grecaptcha) { if (!window.grecaptcha) {
console.log("Recaptcha not loaded"); logger.log("Recaptcha not loaded");
return Promise.reject(translatedError("Recaptcha not loaded", t)); return Promise.reject(translatedError("Recaptcha not loaded", t));
} }

View File

@@ -20,6 +20,7 @@ import { MatrixClient } from "matrix-js-sdk/src/client";
import { randomString } from "matrix-js-sdk/src/randomstring"; import { randomString } from "matrix-js-sdk/src/randomstring";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Heading } from "@vector-im/compound-web"; import { Heading } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/src/logger";
import { import {
createRoom, createRoom,
@@ -97,7 +98,7 @@ export function RegisteredView({ client }: Props) {
setError(undefined); setError(undefined);
setJoinExistingCallModalOpen(true); setJoinExistingCallModalOpen(true);
} else { } else {
console.error(error); logger.error(error);
setLoading(false); setLoading(false);
setError(error); setError(error);
} }

View File

@@ -19,6 +19,7 @@ import { useHistory } from "react-router-dom";
import { randomString } from "matrix-js-sdk/src/randomstring"; import { randomString } from "matrix-js-sdk/src/randomstring";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { Heading } from "@vector-im/compound-web"; import { Heading } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/src/logger";
import { useClient } from "../ClientContext"; import { useClient } from "../ClientContext";
import { Header, HeaderLogo, LeftNav, RightNav } from "../Header"; import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
@@ -130,7 +131,7 @@ export const UnauthenticatedView: FC = () => {
} }
submit().catch((error) => { submit().catch((error) => {
console.error(error); logger.error(error);
setLoading(false); setLoading(false);
setError(error); setError(error);
reset(); reset();

View File

@@ -23,15 +23,16 @@ import "matrix-js-sdk/src/browser-index";
import { StrictMode } from "react"; import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
import { createBrowserHistory } from "history"; import { createBrowserHistory } from "history";
import "./index.css"; import "./index.css";
import { logger } from "matrix-js-sdk/src/logger";
import App from "./App"; import App from "./App";
import { init as initRageshake } from "./settings/rageshake"; import { init as initRageshake } from "./settings/rageshake";
import { Initializer } from "./initializer"; import { Initializer } from "./initializer";
initRageshake(); initRageshake();
console.info(`Element Call ${import.meta.env.VITE_APP_VERSION || "dev"}`); logger.info(`Element Call ${import.meta.env.VITE_APP_VERSION || "dev"}`);
const root = createRoot(document.getElementById("root")!); const root = createRoot(document.getElementById("root")!);

View File

@@ -177,7 +177,7 @@ export async function initClient(
try { try {
await client.store.startup(); await client.store.startup();
} catch (error) { } catch (error) {
console.error( logger.error(
"Error starting matrix client store. Falling back to memory store.", "Error starting matrix client store. Falling back to memory store.",
error error
); );

View File

@@ -19,6 +19,7 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { User, UserEvent } from "matrix-js-sdk/src/models/user"; import { User, UserEvent } from "matrix-js-sdk/src/models/user";
import { FileType } from "matrix-js-sdk/src/http-api"; import { FileType } from "matrix-js-sdk/src/http-api";
import { useState, useCallback, useEffect } from "react"; import { useState, useCallback, useEffect } from "react";
import { logger } from "matrix-js-sdk/src/logger";
interface ProfileLoadState { interface ProfileLoadState {
success: boolean; success: boolean;
@@ -127,7 +128,7 @@ export function useProfile(client: MatrixClient | undefined) {
})); }));
} }
} else { } else {
console.error("Client not initialized before calling saveProfile"); logger.error("Client not initialized before calling saveProfile");
} }
}, },
[client] [client]

View File

@@ -17,6 +17,7 @@ limitations under the License.
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { logger } from "matrix-js-sdk/src/logger";
import styles from "./RoomAuthView.module.css"; import styles from "./RoomAuthView.module.css";
import { Button } from "../button"; import { Button } from "../button";
@@ -46,7 +47,7 @@ export function RoomAuthView() {
typeof dataForDisplayName === "string" ? dataForDisplayName : ""; typeof dataForDisplayName === "string" ? dataForDisplayName : "";
registerPasswordlessUser(displayName).catch((error) => { registerPasswordlessUser(displayName).catch((error) => {
console.error("Failed to register passwordless user", e); logger.error("Failed to register passwordless user", e);
setLoading(false); setLoading(false);
setError(error); setError(error);
}); });

View File

@@ -16,6 +16,7 @@ limitations under the License.
import { FC, useEffect, useState, useCallback, ReactNode } from "react"; import { FC, useEffect, useState, useCallback, ReactNode } from "react";
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession"; import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
import { logger } from "matrix-js-sdk/src/logger";
import { useClientLegacy } from "../ClientContext"; import { useClientLegacy } from "../ClientContext";
import { ErrorView, LoadingView } from "../FullScreenView"; import { ErrorView, LoadingView } from "../FullScreenView";
@@ -37,7 +38,7 @@ export const RoomPage: FC = () => {
const roomIdOrAlias = roomId ?? roomAlias; const roomIdOrAlias = roomId ?? roomAlias;
if (!roomIdOrAlias) { if (!roomIdOrAlias) {
console.error("No room specified"); logger.error("No room specified");
} }
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics(); const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();

View File

@@ -24,6 +24,7 @@ import {
Track, Track,
} from "livekit-client"; } from "livekit-client";
import classNames from "classnames"; import classNames from "classnames";
import { logger } from "matrix-js-sdk/src/logger";
import { Avatar } from "../Avatar"; import { Avatar } from "../Avatar";
import styles from "./VideoPreview.module.css"; import styles from "./VideoPreview.module.css";
@@ -80,7 +81,7 @@ export const VideoPreview: FC<Props> = ({
}, },
}, },
(error) => { (error) => {
console.error("Error while creating preview Tracks:", error); logger.error("Error while creating preview Tracks:", error);
} }
); );
const videoTrack = useMemo( const videoTrack = useMemo(

View File

@@ -54,11 +54,6 @@ enum ConsoleLoggerEvent {
Log = "log", Log = "log",
} }
type LogFunction = (
...args: (Error | DOMException | object | string)[]
) => void;
type LogFunctionName = "log" | "info" | "warn" | "error";
// A class which monkey-patches the global console and stores log lines. // A class which monkey-patches the global console and stores log lines.
interface LogEntry { interface LogEntry {
@@ -69,37 +64,11 @@ interface LogEntry {
class ConsoleLogger extends EventEmitter { class ConsoleLogger extends EventEmitter {
private logs = ""; private logs = "";
private originalFunctions: { [key in LogFunctionName]?: LogFunction } = {};
public monkeyPatch(consoleObj: Console): void { public log = (
// Monkey-patch console logging level: LogLevel,
const consoleFunctionsToLevels = {
log: "I",
info: "I",
warn: "W",
error: "E",
};
Object.entries(consoleFunctionsToLevels).forEach(([name, level]) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const originalFn = consoleObj[name].bind(consoleObj);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.originalFunctions[name] = originalFn;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
consoleObj[name] = (...args) => {
this.log(level, ...args);
originalFn(...args);
};
});
}
public log(
level: string,
...args: (Error | DOMException | object | string)[] ...args: (Error | DOMException | object | string)[]
): void { ): void => {
// We don't know what locale the user may be running so use ISO strings // We don't know what locale the user may be running so use ISO strings
const ts = new Date().toISOString(); const ts = new Date().toISOString();
@@ -129,7 +98,7 @@ class ConsoleLogger extends EventEmitter {
this.logs += line; this.logs += line;
this.emit(ConsoleLoggerEvent.Log); this.emit(ConsoleLoggerEvent.Log);
} };
/** /**
* Returns the log lines to flush to disk and empties the internal log buffer * Returns the log lines to flush to disk and empties the internal log buffer
@@ -510,7 +479,7 @@ declare global {
*/ */
export function init(): Promise<void> { export function init(): Promise<void> {
global.mx_rage_logger = new ConsoleLogger(); global.mx_rage_logger = new ConsoleLogger();
global.mx_rage_logger.monkeyPatch(window.console); setLogExtension(global.mx_rage_logger.log);
return tryInitStorage(); return tryInitStorage();
} }
@@ -591,3 +560,42 @@ const getCircularReplacer = (): StringifyReplacer => {
return value; return value;
}; };
}; };
enum LogLevel {
trace = 0,
debug = 1,
info = 2,
warn = 3,
error = 4,
silent = 5,
}
type LogExtensionFunc = (
level: LogLevel,
...rest: (Error | DOMException | object | string)[]
) => void;
type LogLevelString = keyof typeof LogLevel;
/**
* This method borrowed from livekit (who also use loglevel and in turn essentially
* took loglevel's example honouring log levels). Adds a loglevel logging extension
* in the recommended way.
*/
export function setLogExtension(extension: LogExtensionFunc) {
const originalFactory = logger.methodFactory;
logger.methodFactory = function (methodName, configLevel, loggerName) {
const rawMethod = originalFactory(methodName, configLevel, loggerName);
const logLevel = LogLevel[methodName as LogLevelString];
const needLog = logLevel >= configLevel && logLevel < LogLevel.silent;
return (...args) => {
rawMethod.apply(this, args);
if (needLog) {
extension(logLevel, ...args);
}
};
};
logger.setLevel(logger.getLevel()); // Be sure to call setLevel method in order to apply plugin
}

View File

@@ -26,6 +26,7 @@ import {
import pako from "pako"; import pako from "pako";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { ClientEvent } from "matrix-js-sdk/src/client"; import { ClientEvent } from "matrix-js-sdk/src/client";
import { logger } from "matrix-js-sdk/src/logger";
import { getLogsForReport } from "./rageshake"; import { getLogsForReport } from "./rageshake";
import { useClient } from "../ClientContext"; import { useClient } from "../ClientContext";
@@ -296,7 +297,7 @@ export function useSubmitRageshake(): {
setState({ sending: false, sent: true, error: undefined }); setState({ sending: false, sent: true, error: undefined });
} catch (error) { } catch (error) {
setState({ sending: false, sent: false, error: error as Error }); setState({ sending: false, sent: false, error: error as Error });
console.error(error); logger.error(error);
} }
}, },
[client, inspectorState, sending] [client, inspectorState, sending]

View File

@@ -38,6 +38,7 @@ import {
} from "@react-spring/web"; } from "@react-spring/web";
import useMeasure from "react-use-measure"; import useMeasure from "react-use-measure";
import { ResizeObserver as JuggleResizeObserver } from "@juggle/resize-observer"; import { ResizeObserver as JuggleResizeObserver } from "@juggle/resize-observer";
import { logger } from "matrix-js-sdk/src/logger";
import styles from "./VideoGrid.module.css"; import styles from "./VideoGrid.module.css";
import { Layout } from "../room/LayoutToggle"; import { Layout } from "../room/LayoutToggle";
@@ -298,7 +299,7 @@ function getFreedomLayoutTilePositions(
} }
if (tileCount > 12) { if (tileCount > 12) {
console.warn("Over 12 tiles is not currently supported"); logger.warn("Over 12 tiles is not currently supported");
} }
const { layoutDirection, itemGridRatio } = getGridLayout( const { layoutDirection, itemGridRatio } = getGridLayout(