diff --git a/src/component/internal/logger.ts b/src/component/internal/logger.ts new file mode 100644 index 00000000..0857ce06 --- /dev/null +++ b/src/component/internal/logger.ts @@ -0,0 +1,78 @@ +import { NekoWebSocket } from './websocket' +import * as EVENT from '../types/events' +import * as message from '../types/messages' +import { Logger } from '../utils/logger' + +const RETRY_INTERVAL = 2500 + +export class NekoLogger extends Logger { + private _ws: NekoWebSocket + private _logs: message.SystemLog[] = [] + private _interval: number | null = null + + constructor(websocket: NekoWebSocket, scope?: string) { + super(scope) + + this._ws = websocket + } + + protected _send(level: string, message: string, fields?: Record) { + if (!fields) { + fields = { scope: this._scope } + } else { + fields['scope'] = this._scope + } + + const payload = { level, message, fields } as message.SystemLog + if (!this._ws.connected) { + this._logs.push(payload) + + // postpone logs sending + if (this._interval == null) { + this._interval = window.setInterval(() => { + if (!this._ws.connected || !this._interval) { + return + } + + if (this._logs.length > 0) { + this._ws.send(EVENT.SYSTEM_LOGS, this._logs) + } + + window.clearInterval(this._interval) + this._interval = null + }, RETRY_INTERVAL) + } + + return + } + + // abort postponed logs sending + if (this._interval != null) { + window.clearInterval(this._interval) + this._interval = null + } + + this._ws.send(EVENT.SYSTEM_LOGS, [...this._logs, payload]) + this._logs = [] + } + + public error(message: string, fields?: Record) { + this._console('error', message, fields) + this._send('error', message, fields) + } + + public warn(message: string, fields?: Record) { + this._console('warn', message, fields) + this._send('warn', message, fields) + } + + public info(message: string, fields?: Record) { + this._console('info', message, fields) + this._send('info', message, fields) + } + + public debug(message: string, fields?: Record) { + this._console('debug', message, fields) + this._send('debug', message, fields) + } +} diff --git a/src/component/types/events.ts b/src/component/types/events.ts index f58cec73..3e81d305 100644 --- a/src/component/types/events.ts +++ b/src/component/types/events.ts @@ -1,5 +1,6 @@ export const SYSTEM_INIT = 'system/init' export const SYSTEM_ADMIN = 'system/admin' +export const SYSTEM_LOGS = 'system/logs' export const SYSTEM_DISCONNECT = 'system/disconnect' export const SIGNAL_REQUEST = 'signal/request' diff --git a/src/component/types/messages.ts b/src/component/types/messages.ts index 11940572..77630298 100644 --- a/src/component/types/messages.ts +++ b/src/component/types/messages.ts @@ -23,6 +23,14 @@ export interface SystemAdmin { broadcast_status: BroadcastStatus } +export type SystemLogs = SystemLog[] + +export interface SystemLog { + level: "debug" | "info" | "warn" | "error" + fields: Record + message: string +} + export interface SystemDisconnect { message: string }