Web前端日志打印工具
目录
Web前端日志打印工具
游览器控制台日志打印工具(Typescript / JavaScript)
- 测试需要前端将程序执行过程中的各种数据分门别类的输出到控制台。直接用JavaScript的
console
系列函数并不能很好的满足要求,需要将他们封装一下。 ConsoleLog
是一个class类,使用前需要实例化,每个ConsoleLog
之间是相互独立的,打印日志时互不干扰。- 要将日志进行分组打印,需要先调用
startLog
,分组结束后在调用endLog
,之后整个分组内容就会作为一个整体被打印到调试控制台。当然如果因为throw Error
等导致了没有成功调用endLog
,内部也设置了延时计时器,当分组日志的内容不再增加后,会在500ms后自动将日志打印到控制台。 - 当然也可以不调用
startLog
,而直接使用info/warn/error
,那么此时就和console
上的方法没多大区别。
export type LogType = 'info' | 'warn' | 'error' | 'groupCollapsed';
export interface LogStyle {
fontColor?: string;
backgroundColor?: string;
fontSize?: string;
}
// 是否开启日志打印
const OPEN_LOG = true;
const { info, warn, error, groupCollapsed, groupEnd } = console;
const _console = { info, warn, error, groupCollapsed, groupEnd };
// group 标签的默认样式
const groupLabelStyle: LogStyle = {
fontColor: '#ff7f50',
backgroundColor: '#7bed9f',
fontSize: '2em',
};
// info 类型的log默认样式
const infoStyle: LogStyle = {
fontColor: '#ff7f50',
backgroundColor: '#7bed9f',
};
// warn 类型的log默认样式
const warnStyle: LogStyle = {};
// error 类型的log默认样式
const errorStyle: LogStyle = {};
export default class ConsoleLog {
// log日志队列
private _logQueue: { type: LogType; data: any[] }[] = [];
// 是否调用了startLog
private _isStart: boolean = false;
// 延时计时器
private _timeout: number | undefined = undefined;
startLog(label: string, style: LogStyle = groupLabelStyle): this {
if (!OPEN_LOG) {
return this;
}
if (this._isStart) {
this._print();
this._logQueue = [];
}
const data = getLogData(style, label);
this._logQueue.push({ type: 'groupCollapsed', data });
this._isStart = true;
this._refreshTimeOut(true);
return this;
}
endLog() {
if (!OPEN_LOG) {
return;
}
if (this._isStart) {
this._refreshTimeOut(false);
this._print();
this._logQueue = [];
this._isStart = false;
}
}
info(style: LogStyle = infoStyle, log: string, ...args: any[]): this {
if (!OPEN_LOG) {
return this;
}
const data = getLogData(style, log, ...args);
if (this._isStart) {
this._logQueue.push({ type: 'info', data });
this._refreshTimeOut(true);
} else {
_console.info(...data);
}
return this;
}
warn(style: LogStyle = warnStyle, log: string, ...args: any[]): this {
if (!OPEN_LOG) {
return this;
}
const data = getLogData(style, log, ...args);
if (this._isStart) {
this._logQueue.push({ type: 'warn', data });
this._refreshTimeOut(true);
} else {
_console.warn(...data);
}
return this;
}
error(style: LogStyle = errorStyle, log: string, ...args: any[]): this {
if (!OPEN_LOG) {
return this;
}
const data = getLogData(style, log, ...args);
if (this._isStart) {
this._logQueue.push({ type: 'error', data });
this._refreshTimeOut(true);
} else {
_console.error(...data);
}
return this;
}
// 将队列中的日志信息依次打印出来
private _print(): void {
if (this._logQueue.length > 0) {
for (const el of this._logQueue) {
_console[el.type](...el.data);
}
_console.groupEnd();
}
}
private _refreshTimeOut(open: boolean) {
if (this._timeout !== undefined) {
clearTimeout(this._timeout);
}
if (open) {
this._timeout = setTimeout(() => {
_console.warn('ConsoleLog Warn, endLog未在限定的时间内执行');
this.endLog();
this._timeout = undefined;
}, 500) as any as number;
} else {
this._timeout = undefined;
}
}
}
const logMap = new Map<string | number, ConsoleLog>();
export const ConsoleLogMap = {
get(logId: string | number): ConsoleLog {
let consoleLog = logMap.get(logId);
if (!consoleLog) {
logMap.set(logId, (consoleLog = new ConsoleLog()));
}
return consoleLog;
},
delete(logId: string | number) {
return logMap.delete(logId);
},
};
/* ******************** 工具函数 ******************** */
function getStyle(
fontColor?: string,
backgroundColor?: string,
fontSize?: string,
): string {
let style = '';
if (fontColor) {
style += `color:${fontColor};`;
}
if (backgroundColor) {
style += `background-color:${backgroundColor};`;
}
if (fontSize) {
style += `font-size:${fontSize};`;
}
return style;
}
function getLogData(style: LogStyle, label: string, ...args: any[]): any[] {
if (style) {
return [
`%c ${label} `,
getStyle(style.fontColor, style.backgroundColor, style.fontSize),
...args,
];
} else {
return [label, ...args];
}
}