mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-03-03 05:55:03 +01:00
chore(connect): move logs to @trezor/utils
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
import { initLog, enableLog, enableLogByPrefix, getLog } from '../debug';
|
||||
|
||||
describe('utils/debug', () => {
|
||||
it('max entries', () => {
|
||||
const l = initLog('test');
|
||||
const l2 = initLog('test2');
|
||||
for (let i = 0; i < 110; i++) {
|
||||
l.log('entry');
|
||||
l2.error('entry');
|
||||
l.warn('entry');
|
||||
l2.debug('entry');
|
||||
}
|
||||
expect(l.messages.length).toEqual(100);
|
||||
expect(l2.messages.length).toEqual(100);
|
||||
expect(getLog().length).toEqual(200); // combined
|
||||
});
|
||||
|
||||
it('enable/disable', () => {
|
||||
const l = initLog('test', true);
|
||||
const l2 = initLog('test2');
|
||||
enableLogByPrefix('foobar', false);
|
||||
enableLogByPrefix('test2', true); // enable only one
|
||||
expect(l.enabled).toEqual(true);
|
||||
expect(l2.enabled).toEqual(true);
|
||||
enableLog(false); // disable all
|
||||
expect(l.enabled).toEqual(false);
|
||||
expect(l2.enabled).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
// origin: https://github.com/trezor/connect/blob/develop/src/js/utils/debug.js
|
||||
/* eslint-disable no-console */
|
||||
import { LogsManager } from '@trezor/utils';
|
||||
|
||||
const green = '#bada55';
|
||||
const blue = '#20abd8';
|
||||
@@ -24,144 +23,12 @@ const colors: Record<string, string> = {
|
||||
'@trezor/connect-popup': `color: ${yellow}; background: #000;`,
|
||||
};
|
||||
|
||||
export type LogMessage = {
|
||||
level: string;
|
||||
prefix: string;
|
||||
message: any[];
|
||||
timestamp: number;
|
||||
};
|
||||
const logsManager = new LogsManager({ colors });
|
||||
|
||||
export type LogWriter = {
|
||||
add: (message: LogMessage) => void;
|
||||
};
|
||||
export const initLog = logsManager.initLog.bind(logsManager);
|
||||
export const setLogWriter = logsManager.setLogWriter.bind(logsManager);
|
||||
export const enableLog = logsManager.enableLog.bind(logsManager);
|
||||
export const enableLogByPrefix = logsManager.enableLogByPrefix.bind(logsManager);
|
||||
export const getLog = logsManager.getLog.bind(logsManager);
|
||||
|
||||
const MAX_ENTRIES = 100;
|
||||
|
||||
export class Log {
|
||||
prefix: string;
|
||||
enabled: boolean;
|
||||
css: string;
|
||||
messages: LogMessage[];
|
||||
logWriter: LogWriter | undefined;
|
||||
|
||||
constructor(prefix: string, enabled: boolean, logWriter?: LogWriter) {
|
||||
this.prefix = prefix;
|
||||
this.enabled = enabled;
|
||||
this.messages = [];
|
||||
this.css = typeof window !== 'undefined' && colors[prefix] ? colors[prefix] : '';
|
||||
if (logWriter) {
|
||||
this.logWriter = logWriter;
|
||||
}
|
||||
}
|
||||
|
||||
addMessage(
|
||||
{ level, prefix, timestamp }: { level: string; prefix: string; timestamp?: number },
|
||||
...args: any[]
|
||||
) {
|
||||
const message = {
|
||||
level,
|
||||
prefix,
|
||||
css: this.css,
|
||||
message: args,
|
||||
timestamp: timestamp || Date.now(),
|
||||
};
|
||||
|
||||
this.messages.push(message);
|
||||
|
||||
if (this.logWriter) {
|
||||
try {
|
||||
this.logWriter.add(message);
|
||||
} catch (err) {
|
||||
// If this error happens it probably means that we are logging an object with a circular reference.
|
||||
// If there is any `device` logged, do it with `device.toMessageObject()` instead.
|
||||
console.error('There was an error adding log message', err, message);
|
||||
}
|
||||
}
|
||||
if (this.messages.length > MAX_ENTRIES) {
|
||||
this.messages.shift();
|
||||
}
|
||||
}
|
||||
|
||||
setWriter(logWriter: any) {
|
||||
this.logWriter = logWriter;
|
||||
}
|
||||
|
||||
log(...args: any[]) {
|
||||
this.addMessage({ level: 'log', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
console.log(`%c${this.prefix}`, this.css, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
error(...args: any[]) {
|
||||
this.addMessage({ level: 'error', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
console.error(`%c${this.prefix}`, this.css, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
warn(...args: any[]) {
|
||||
this.addMessage({ level: 'warn', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
console.warn(`%c${this.prefix}`, this.css, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
debug(...args: any[]) {
|
||||
this.addMessage({ level: 'debug', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
if (this.css) {
|
||||
console.log(`%c${this.prefix}`, this.css, ...args);
|
||||
} else {
|
||||
console.log(this.prefix, ...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const _logs: { [k: string]: Log } = {};
|
||||
let writer: LogWriter | undefined;
|
||||
|
||||
export const initLog = (prefix: string, enabled?: boolean, logWriter?: LogWriter) => {
|
||||
const instanceWriter = logWriter || writer;
|
||||
const instance = new Log(prefix, !!enabled, instanceWriter);
|
||||
_logs[prefix] = instance;
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const setLogWriter = (logWriterFactory: () => LogWriter | undefined) => {
|
||||
Object.keys(_logs).forEach(key => {
|
||||
writer = logWriterFactory();
|
||||
if (writer) {
|
||||
_logs[key].setWriter(writer);
|
||||
const { messages } = _logs[key];
|
||||
// If there are any messages in the log when init, add them to the writer.
|
||||
messages.forEach(message => {
|
||||
writer?.add(message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const enableLog = (enabled?: boolean) => {
|
||||
Object.keys(_logs).forEach(key => {
|
||||
_logs[key].enabled = !!enabled;
|
||||
});
|
||||
};
|
||||
|
||||
export const enableLogByPrefix = (prefix: string, enabled: boolean) => {
|
||||
if (_logs[prefix]) {
|
||||
_logs[prefix].enabled = enabled;
|
||||
}
|
||||
};
|
||||
|
||||
export const getLog = () => {
|
||||
let logs: LogMessage[] = [];
|
||||
Object.keys(_logs).forEach(key => {
|
||||
logs = logs.concat(_logs[key].messages);
|
||||
});
|
||||
logs.sort((a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
return logs;
|
||||
};
|
||||
export type { LogMessage, LogWriter, Log } from '@trezor/utils';
|
||||
|
||||
@@ -38,3 +38,5 @@ export * from './topologicalSort';
|
||||
export * from './truncateMiddle';
|
||||
export * from './typedEventEmitter';
|
||||
export * from './urlToOnion';
|
||||
export * from './logs';
|
||||
export * from './logsManager';
|
||||
|
||||
107
packages/utils/src/logs.ts
Normal file
107
packages/utils/src/logs.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
export type LogMessage = {
|
||||
level: string;
|
||||
prefix: string;
|
||||
message: any[];
|
||||
timestamp: number;
|
||||
};
|
||||
|
||||
export type LogWriter = {
|
||||
add: (message: LogMessage) => void;
|
||||
};
|
||||
|
||||
export class Log {
|
||||
prefix: string;
|
||||
enabled: boolean;
|
||||
css: string = '';
|
||||
messages: LogMessage[];
|
||||
logWriter: LogWriter | undefined;
|
||||
MAX_ENTRIES = 100;
|
||||
|
||||
constructor(prefix: string, enabled: boolean, logWriter?: LogWriter) {
|
||||
this.prefix = prefix;
|
||||
this.enabled = enabled;
|
||||
this.messages = [];
|
||||
if (logWriter) {
|
||||
this.logWriter = logWriter;
|
||||
}
|
||||
}
|
||||
|
||||
setColors(colors: Record<string, string>) {
|
||||
this.css = typeof window !== 'undefined' && colors[this.prefix] ? colors[this.prefix] : '';
|
||||
}
|
||||
|
||||
addMessage(
|
||||
{ level, prefix, timestamp }: { level: string; prefix: string; timestamp?: number },
|
||||
...args: any[]
|
||||
) {
|
||||
const message = {
|
||||
level,
|
||||
prefix,
|
||||
css: this.css,
|
||||
message: args,
|
||||
timestamp: timestamp || Date.now(),
|
||||
};
|
||||
|
||||
this.messages.push(message);
|
||||
|
||||
if (this.logWriter) {
|
||||
try {
|
||||
this.logWriter.add(message);
|
||||
} catch (err) {
|
||||
// If this error happens it probably means that we are logging an object with a circular reference.
|
||||
// If there is any `device` logged, do it with `device.toMessageObject()` instead.
|
||||
console.error('There was an error adding log message', err, message);
|
||||
}
|
||||
}
|
||||
if (this.messages.length > this.MAX_ENTRIES) {
|
||||
this.messages.shift();
|
||||
}
|
||||
}
|
||||
|
||||
setWriter(logWriter: any) {
|
||||
this.logWriter = logWriter;
|
||||
}
|
||||
|
||||
log(...args: any[]) {
|
||||
this.addMessage({ level: 'log', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
console.log(`%c${this.prefix}`, this.css, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
error(...args: any[]) {
|
||||
this.addMessage({ level: 'error', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
console.error(`%c${this.prefix}`, this.css, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
info(...args: any[]) {
|
||||
this.addMessage({ level: 'info', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
console.info(`%c${this.prefix}`, this.css, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
warn(...args: any[]) {
|
||||
this.addMessage({ level: 'warn', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
console.warn(`%c${this.prefix}`, this.css, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
debug(...args: any[]) {
|
||||
this.addMessage({ level: 'debug', prefix: this.prefix }, ...args);
|
||||
if (this.enabled) {
|
||||
if (this.css) {
|
||||
console.log(`%c${this.prefix}`, this.css, ...args);
|
||||
} else {
|
||||
console.log(this.prefix, ...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getLog() {
|
||||
return this.messages;
|
||||
}
|
||||
}
|
||||
57
packages/utils/src/logsManager.ts
Normal file
57
packages/utils/src/logsManager.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { LogWriter, Log, LogMessage } from './logs';
|
||||
|
||||
export class LogsManager {
|
||||
logs: { [k: string]: Log } = {};
|
||||
writer: LogWriter | undefined;
|
||||
colors?: Record<string, string> = {};
|
||||
constructor({ colors }: { colors?: Record<string, string> }) {
|
||||
this.colors = colors;
|
||||
}
|
||||
|
||||
initLog(prefix: string, enabled?: boolean, logWriter?: LogWriter) {
|
||||
const instanceWriter = logWriter || this.writer;
|
||||
const instance = new Log(prefix, !!enabled, instanceWriter);
|
||||
if (this.colors) {
|
||||
instance.setColors(this.colors);
|
||||
}
|
||||
this.logs[prefix] = instance;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
setLogWriter(logWriterFactory: () => LogWriter | undefined) {
|
||||
Object.keys(this.logs).forEach(key => {
|
||||
this.writer = logWriterFactory();
|
||||
if (this.writer) {
|
||||
this.logs[key].setWriter(this.writer);
|
||||
const { messages } = this.logs[key];
|
||||
// If there are any messages in the log when init, add them to the writer.
|
||||
messages.forEach(message => {
|
||||
this.writer?.add(message);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enableLog(enabled?: boolean) {
|
||||
Object.keys(this.logs).forEach(key => {
|
||||
this.logs[key].enabled = !!enabled;
|
||||
});
|
||||
}
|
||||
|
||||
enableLogByPrefix(prefix: string, enabled: boolean) {
|
||||
if (this.logs[prefix]) {
|
||||
this.logs[prefix].enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
getLog() {
|
||||
let logs: LogMessage[] = [];
|
||||
Object.keys(this.logs).forEach(key => {
|
||||
logs = logs.concat(this.logs[key].messages);
|
||||
});
|
||||
logs.sort((a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
return logs;
|
||||
}
|
||||
}
|
||||
33
packages/utils/tests/logs.test.ts
Normal file
33
packages/utils/tests/logs.test.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { LogsManager } from '../src/logsManager';
|
||||
|
||||
describe('utils/debug', () => {
|
||||
it('max entries', () => {
|
||||
const logsManager = new LogsManager({});
|
||||
|
||||
const l = logsManager.initLog('test');
|
||||
const l2 = logsManager.initLog('test2');
|
||||
for (let i = 0; i < 110; i++) {
|
||||
l.log('entry');
|
||||
l2.error('entry');
|
||||
l.warn('entry');
|
||||
l2.debug('entry');
|
||||
}
|
||||
expect(l.messages.length).toEqual(100);
|
||||
expect(l2.messages.length).toEqual(100);
|
||||
expect(logsManager.getLog().length).toEqual(200); // combined
|
||||
});
|
||||
|
||||
it('enable/disable', () => {
|
||||
const logsManager = new LogsManager({});
|
||||
|
||||
const l = logsManager.initLog('test', true);
|
||||
const l2 = logsManager.initLog('test2');
|
||||
logsManager.enableLogByPrefix('foobar', false);
|
||||
logsManager.enableLogByPrefix('test2', true); // enable only one
|
||||
expect(l.enabled).toEqual(true);
|
||||
expect(l2.enabled).toEqual(true);
|
||||
logsManager.enableLog(false); // disable all
|
||||
expect(l.enabled).toEqual(false);
|
||||
expect(l2.enabled).toEqual(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user