mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-17 06:16:59 +08:00
feat: debug logger with levels (#1165)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
|
||||
import assert from 'assert';
|
||||
|
||||
import { getLogger } from './logger';
|
||||
import { MessageCenter } from './message';
|
||||
import { AffineProvider } from './provider';
|
||||
import type {
|
||||
@@ -23,7 +23,7 @@ import { WorkspaceUnitCollection } from './workspace-unit-collection';
|
||||
|
||||
export class DataCenter {
|
||||
private readonly _workspaceUnitCollection = new WorkspaceUnitCollection();
|
||||
private readonly _logger = getLogger('dc');
|
||||
private readonly _logger = new DebugLogger('datacenter');
|
||||
private _workspaceInstances: Map<string, BlocksuiteWorkspace> = new Map();
|
||||
private _messageCenter = MessageCenter.getInstance();
|
||||
|
||||
@@ -33,19 +33,12 @@ export class DataCenter {
|
||||
private _mainProvider?: BaseProvider;
|
||||
providerMap: Map<string, BaseProvider> = new Map();
|
||||
|
||||
private constructor(debug: boolean) {
|
||||
this._logger.enabled = debug;
|
||||
}
|
||||
|
||||
static initEmpty() {
|
||||
return new DataCenter(false);
|
||||
return new DataCenter();
|
||||
}
|
||||
|
||||
static async init(
|
||||
debug: boolean,
|
||||
exclude: 'affine'[] = []
|
||||
): Promise<DataCenter> {
|
||||
const dc = new DataCenter(debug);
|
||||
static async init(exclude: 'affine'[] = []): Promise<DataCenter> {
|
||||
const dc = new DataCenter();
|
||||
const getInitParams = () => {
|
||||
return {
|
||||
logger: dc._logger,
|
||||
@@ -182,7 +175,10 @@ export class DataCenter {
|
||||
}
|
||||
const provider = this.providerMap.get(workspaceUnit.provider);
|
||||
assert(provider, `provide '${workspaceUnit.provider}' is not registered`);
|
||||
this._logger(`Loading ${workspaceUnit.provider} workspace: `, workspaceId);
|
||||
this._logger.debug(
|
||||
`Loading ${workspaceUnit.provider} workspace: `,
|
||||
workspaceId
|
||||
);
|
||||
|
||||
const workspace = this._getBlocksuiteWorkspace(workspaceId);
|
||||
this._workspaceInstances.set(workspaceId, workspace);
|
||||
@@ -350,7 +346,7 @@ export class DataCenter {
|
||||
providerId = 'affine'
|
||||
) {
|
||||
if (workspaceUnit.provider === providerId) {
|
||||
this._logger('Workspace provider is same');
|
||||
this._logger.error('Workspace provider is same');
|
||||
return;
|
||||
}
|
||||
const provider = this.providerMap.get(providerId);
|
||||
|
||||
@@ -3,9 +3,9 @@ import { DataCenter } from './datacenter';
|
||||
const _initializeDataCenter = () => {
|
||||
let _dataCenterInstance: Promise<DataCenter>;
|
||||
|
||||
return (debug = true) => {
|
||||
return () => {
|
||||
if (!_dataCenterInstance) {
|
||||
_dataCenterInstance = DataCenter.init(debug);
|
||||
_dataCenterInstance = DataCenter.init();
|
||||
}
|
||||
|
||||
return _dataCenterInstance;
|
||||
@@ -15,7 +15,6 @@ const _initializeDataCenter = () => {
|
||||
export const getDataCenter = _initializeDataCenter();
|
||||
|
||||
export { DataCenter };
|
||||
export { getLogger } from './logger';
|
||||
export * from './message';
|
||||
export { AffineProvider } from './provider/affine';
|
||||
export * from './provider/affine/apis';
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import debug from 'debug';
|
||||
|
||||
export function getLogger(namespace: string) {
|
||||
const logger = debug(namespace);
|
||||
logger.log = console.log.bind(console);
|
||||
return logger;
|
||||
}
|
||||
@@ -86,7 +86,6 @@ export class AffineProvider extends BaseProvider {
|
||||
`${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${
|
||||
window.location.host
|
||||
}/api/global/sync/`,
|
||||
this._logger,
|
||||
this._apis.auth,
|
||||
{
|
||||
params: {
|
||||
@@ -115,7 +114,7 @@ export class AffineProvider extends BaseProvider {
|
||||
ws_details,
|
||||
metadata,
|
||||
}: ChannelMessage) {
|
||||
this._logger('receive server message');
|
||||
this._logger.debug('receive server message');
|
||||
const newlyCreatedWorkspaces: WorkspaceUnit[] = [];
|
||||
const currentWorkspaceIds = this._workspaces.list().map(w => w.id);
|
||||
const newlyRemovedWorkspaceIds = currentWorkspaceIds;
|
||||
@@ -331,7 +330,7 @@ export class AffineProvider extends BaseProvider {
|
||||
await this.deleteWorkspace(w.id);
|
||||
this._workspaces.remove(w.id);
|
||||
} catch (e) {
|
||||
this._logger('has a problem of delete workspace ', e);
|
||||
this._logger.error('has a problem of delete workspace ', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { initializeApp } from 'firebase/app';
|
||||
import type { User } from 'firebase/auth';
|
||||
import {
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
import { decode } from 'js-base64';
|
||||
import { KyInstance } from 'ky/distribution/types/ky';
|
||||
|
||||
import { getLogger } from '../../../logger';
|
||||
import { storage } from '../storage';
|
||||
|
||||
export interface AccessTokenMessage {
|
||||
@@ -58,7 +58,7 @@ export class GoogleAuth {
|
||||
private readonly _doLogin: ReturnType<typeof createDoLogin>;
|
||||
|
||||
constructor(bareClient: KyInstance) {
|
||||
this._logger = getLogger('token');
|
||||
this._logger = new DebugLogger('token');
|
||||
this._logger.enabled = true;
|
||||
this._doLogin = createDoLogin(bareClient);
|
||||
|
||||
@@ -93,7 +93,7 @@ export class GoogleAuth {
|
||||
const login: LoginResponse = JSON.parse(loginStr);
|
||||
this.setLogin(login);
|
||||
} catch (err) {
|
||||
this._logger('Failed to parse login info', err);
|
||||
this._logger.warn('Failed to parse login info', err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ export class GoogleAuth {
|
||||
}
|
||||
return true;
|
||||
} catch {
|
||||
this._logger('Failed to refresh token');
|
||||
this._logger.warn('Failed to refresh token');
|
||||
} finally {
|
||||
// clear on settled
|
||||
this._padding = undefined;
|
||||
@@ -191,7 +191,7 @@ export function createGoogleAuth(bareAuth: KyInstance): GoogleAuth {
|
||||
|
||||
export const getAuthorizer = (googleAuth: GoogleAuth) => {
|
||||
let _firebaseAuth: FirebaseAuth | null = null;
|
||||
const logger = getLogger('authorizer');
|
||||
const logger = new DebugLogger('authorizer');
|
||||
|
||||
// getAuth will send requests on calling thus we can lazy init it
|
||||
const getAuth = () => {
|
||||
@@ -211,7 +211,7 @@ export const getAuthorizer = (googleAuth: GoogleAuth) => {
|
||||
}
|
||||
return _firebaseAuth;
|
||||
} catch (error) {
|
||||
logger(error);
|
||||
logger.error('Failed to initialize firebase', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import * as url from 'lib0/url';
|
||||
import * as websocket from 'lib0/websocket';
|
||||
|
||||
import { Logger } from '../../types';
|
||||
import { GoogleAuth } from './apis/google';
|
||||
|
||||
const RECONNECT_INTERVAL_TIME = 500;
|
||||
@@ -9,12 +9,11 @@ const MAX_RECONNECT_TIMES = 50;
|
||||
|
||||
export class WebsocketClient extends websocket.WebsocketClient {
|
||||
public shouldReconnect = false;
|
||||
private _logger: Logger;
|
||||
private _retryTimes = 0;
|
||||
private _auth: GoogleAuth;
|
||||
private _logger = new DebugLogger('affine:channel');
|
||||
constructor(
|
||||
serverUrl: string,
|
||||
logger: Logger,
|
||||
auth: GoogleAuth,
|
||||
options?: ConstructorParameters<typeof websocket.WebsocketClient>[1] & {
|
||||
params: Record<string, string>;
|
||||
@@ -30,13 +29,12 @@ export class WebsocketClient extends websocket.WebsocketClient {
|
||||
serverUrl + '/' + (encodedParams.length === 0 ? '' : '?' + encodedParams);
|
||||
super(newUrl, options);
|
||||
this._auth = auth;
|
||||
this._logger = logger;
|
||||
this._setupChannel();
|
||||
}
|
||||
|
||||
private _setupChannel() {
|
||||
this.on('connect', () => {
|
||||
this._logger('Affine channel connected');
|
||||
this._logger.debug('Affine channel connected');
|
||||
this.shouldReconnect = true;
|
||||
this._retryTimes = 0;
|
||||
});
|
||||
@@ -49,15 +47,17 @@ export class WebsocketClient extends websocket.WebsocketClient {
|
||||
setTimeout(() => {
|
||||
if (this._retryTimes <= MAX_RECONNECT_TIMES) {
|
||||
this.connect();
|
||||
this._logger(
|
||||
this._logger.info(
|
||||
`try reconnect channel ${++this._retryTimes} times`
|
||||
);
|
||||
} else {
|
||||
this._logger('reconnect failed, max reconnect times reached');
|
||||
this._logger.error(
|
||||
'reconnect failed, max reconnect times reached'
|
||||
);
|
||||
}
|
||||
}, RECONNECT_INTERVAL_TIME);
|
||||
} catch (e) {
|
||||
this._logger('reconnect failed', e);
|
||||
this._logger.error('reconnect failed', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
|
||||
|
||||
import { MessageCenter } from '../message';
|
||||
import { Logger, User } from '../types';
|
||||
import { User } from '../types';
|
||||
import type { WorkspaceUnit, WorkspaceUnitCtorParams } from '../workspace-unit';
|
||||
import type { WorkspaceUnitCollectionScope } from '../workspace-unit-collection';
|
||||
import { Member } from './affine/apis';
|
||||
import { Permission } from './affine/apis/workspace';
|
||||
|
||||
const defaultLogger = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
export interface ProviderConstructorParams {
|
||||
logger?: Logger;
|
||||
workspaces: WorkspaceUnitCollectionScope;
|
||||
messageCenter: MessageCenter;
|
||||
}
|
||||
@@ -23,25 +19,21 @@ export type UpdateWorkspaceMetaParams = Partial<
|
||||
Pick<WorkspaceUnitCtorParams, 'name' | 'avatar'>
|
||||
>;
|
||||
|
||||
export class BaseProvider {
|
||||
export abstract class BaseProvider {
|
||||
/** provider id */
|
||||
public readonly id: string = 'base';
|
||||
/** workspace unit collection */
|
||||
protected _workspaces!: WorkspaceUnitCollectionScope;
|
||||
protected _logger!: Logger;
|
||||
protected _logger: DebugLogger;
|
||||
/** send message with message center */
|
||||
protected _sendMessage!: ReturnType<
|
||||
InstanceType<typeof MessageCenter>['getMessageSender']
|
||||
>;
|
||||
|
||||
public constructor({
|
||||
logger,
|
||||
workspaces,
|
||||
messageCenter,
|
||||
}: ProviderConstructorParams) {
|
||||
this._logger = (logger || defaultLogger) as Logger;
|
||||
public constructor({ workspaces, messageCenter }: ProviderConstructorParams) {
|
||||
this._workspaces = workspaces;
|
||||
this._sendMessage = messageCenter.getMessageSender(this.id);
|
||||
this._logger = new DebugLogger(`provider:${this.id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,7 @@ export class LocalProvider extends BaseProvider {
|
||||
idb = new IndexedDBProvider(workspace.room, workspace.doc);
|
||||
}
|
||||
this._idbMap.set(workspace, idb);
|
||||
this._logger('Local data loaded');
|
||||
this._logger.debug('Local data loaded');
|
||||
return workspace;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export class LocalProvider extends BaseProvider {
|
||||
this._workspaces.add(workspaceUnits);
|
||||
return workspaceUnits;
|
||||
} catch (error) {
|
||||
this._logger(`Failed to parse workspaces from storage`);
|
||||
this._logger.error(`Failed to parse workspaces from storage`);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
@@ -84,7 +84,7 @@ export class LocalProvider extends BaseProvider {
|
||||
this._idbMap.delete(workspace.blocksuiteWorkspace);
|
||||
}
|
||||
} else {
|
||||
this._logger(`Failed to delete workspace ${id}`);
|
||||
this._logger.error(`Failed to delete workspace ${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import { createWorkspaceUnit } from './utils';
|
||||
export class TauriIPCProvider extends LocalProvider {
|
||||
public id = 'tauri-ipc';
|
||||
static defaultUserEmail = 'xxx@xx.xx';
|
||||
|
||||
/**
|
||||
* // TODO: We only have one user in this version of app client. But may support switch user later.
|
||||
*/
|
||||
@@ -79,7 +80,7 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
workspaceID: string,
|
||||
blocksuiteWorkspace: BlocksuiteWorkspace
|
||||
) {
|
||||
this._logger(`Loading ${workspaceID}...`);
|
||||
this._logger.debug(`Loading ${workspaceID}...`);
|
||||
const result = await this.#ipc?.getYDocument({ id: workspaceID });
|
||||
if (result) {
|
||||
const updates = result.updates.map(
|
||||
@@ -88,7 +89,7 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
|
||||
const mergedUpdate = Y.mergeUpdates(updates);
|
||||
await applyUpdate(blocksuiteWorkspace, mergedUpdate);
|
||||
this._logger(`Loaded: ${workspaceID}`);
|
||||
this._logger.debug(`Loaded: ${workspaceID}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +97,7 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
workspaceID: string,
|
||||
blocksuiteWorkspace: BlocksuiteWorkspace
|
||||
) {
|
||||
this._logger(`Connecting yDoc for ${workspaceID}...`);
|
||||
this._logger.debug(`Connecting yDoc for ${workspaceID}...`);
|
||||
blocksuiteWorkspace.doc.on('update', async (update: Uint8Array) => {
|
||||
try {
|
||||
const binary = Y.encodeStateAsUpdate(blocksuiteWorkspace.doc);
|
||||
@@ -109,7 +110,7 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO: write error log to disk, and add button to open them in settings panel
|
||||
console.error("#yDocument.on('update'", error);
|
||||
this._logger.error("#yDocument.on('update'", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -134,7 +135,7 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
public override async createWorkspace(
|
||||
meta: CreateWorkspaceInfoParams
|
||||
): Promise<WorkspaceUnit | undefined> {
|
||||
this._logger('Creating client app workspace');
|
||||
this._logger.debug('Creating client app workspace');
|
||||
assert(this.#ipc);
|
||||
assert(this.#userID);
|
||||
const { id } = await this.#ipc.createWorkspace({
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { getLogger } from '../logger';
|
||||
|
||||
// export type WorkspaceInfo = {
|
||||
// name: string;
|
||||
// id: string;
|
||||
@@ -27,7 +25,7 @@ export type User = {
|
||||
|
||||
// export type WorkspaceMeta = Pick<WorkspaceInfo, 'name' | 'avatar'>;
|
||||
|
||||
export type Logger = ReturnType<typeof getLogger>;
|
||||
export type Logger = typeof import('@affine/debug').DebugLogger;
|
||||
|
||||
export type Message = {
|
||||
code: number;
|
||||
|
||||
Reference in New Issue
Block a user