162 lines
4.4 KiB
JavaScript
162 lines
4.4 KiB
JavaScript
// 定义日志级别
|
||
export const LogLevel = {
|
||
DEBUG: { value: 0, name: "DEBUG", color: "#6495ED" }, // 宝蓝色
|
||
INFO: { value: 1, name: "INFO", color: "#4CAF50" }, // 绿色
|
||
WARN: { value: 2, name: "WARN", color: "#FFC107" }, // 琥珀色
|
||
ERROR: { value: 3, name: "ERROR", color: "#F44336" }, // 红色
|
||
SILENT: { value: 4, name: "SILENT" }, // 特殊级别,用于关闭所有日志
|
||
};
|
||
|
||
function findLogLevelByValue(value) {
|
||
return Object.values(LogLevel).find((level) => level.value === value);
|
||
}
|
||
|
||
function findLogLevelByName(name) {
|
||
if (typeof name !== "string" || name.length === 0) return undefined;
|
||
const upperCaseName = name.toUpperCase();
|
||
return Object.values(LogLevel).find((level) => level.name === upperCaseName);
|
||
}
|
||
|
||
class Logger {
|
||
/**
|
||
* @param {object} [options={}] 配置选项
|
||
* @param {LogLevel} [options.level=LogLevel.INFO] 要显示的最低日志级别
|
||
* @param {string} [options.prefix='App'] 日志前缀,用于区分模块
|
||
*/
|
||
constructor(options = {}) {
|
||
this.config = {
|
||
level: options.level || LogLevel.INFO,
|
||
prefix: options.prefix || "KISS-Translator",
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 动态设置日志级别
|
||
* @param {LogLevel} level - 新的日志级别
|
||
*/
|
||
setLevel(level) {
|
||
let newLevelObject;
|
||
|
||
if (typeof level === "string") {
|
||
newLevelObject = findLogLevelByName(level);
|
||
if (!newLevelObject) {
|
||
this.warn(
|
||
`Invalid log level name provided: "${level}". Keeping current level.`
|
||
);
|
||
return;
|
||
}
|
||
} else if (typeof level === "number") {
|
||
newLevelObject = findLogLevelByValue(level);
|
||
if (!newLevelObject) {
|
||
this.warn(
|
||
`Invalid log level value provided: ${level}. Keeping current level.`
|
||
);
|
||
return;
|
||
}
|
||
} else if (level && typeof level.value === "number") {
|
||
newLevelObject = level;
|
||
} else {
|
||
this.warn(
|
||
"Invalid argument passed to setLevel. Must be a LogLevel object, number, or string."
|
||
);
|
||
return;
|
||
}
|
||
|
||
this.config.level = newLevelObject;
|
||
console.log(
|
||
`[${this.config.prefix}] Log level dynamically set to ${this.config.level.name}`
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 核心日志记录方法
|
||
* @private
|
||
* @param {LogLevel} level - 当前消息的日志级别
|
||
* @param {...any} args - 要记录的多个参数,可以是任何类型
|
||
*/
|
||
_log(level, ...args) {
|
||
// 如果当前级别低于配置的最低级别,则不打印
|
||
if (level.value < this.config.level.value) {
|
||
return;
|
||
}
|
||
|
||
const timestamp = new Date().toISOString();
|
||
const prefixStr = `[${this.config.prefix}]`;
|
||
const levelStr = `[${level.name}]`;
|
||
|
||
// 判断是否在浏览器环境并且浏览器支持 console 样式
|
||
const isBrowser =
|
||
typeof window !== "undefined" && typeof window.document !== "undefined";
|
||
|
||
if (isBrowser) {
|
||
// 在浏览器中使用颜色高亮
|
||
const consoleMethod = this._getConsoleMethod(level);
|
||
consoleMethod(
|
||
`%c${timestamp} %c${prefixStr} %c${levelStr}`,
|
||
"color: gray; font-weight: lighter;", // 时间戳样式
|
||
"color: #7c57e0; font-weight: bold;", // 前缀样式 (紫色)
|
||
`color: ${level.color}; font-weight: bold;`, // 日志级别样式
|
||
...args
|
||
);
|
||
} else {
|
||
// 在 Node.js 或不支持样式的环境中,输出纯文本
|
||
const consoleMethod = this._getConsoleMethod(level);
|
||
consoleMethod(timestamp, prefixStr, levelStr, ...args);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 根据日志级别获取对应的 console 方法
|
||
* @private
|
||
*/
|
||
_getConsoleMethod(level) {
|
||
switch (level) {
|
||
case LogLevel.ERROR:
|
||
return console.error;
|
||
case LogLevel.WARN:
|
||
return console.warn;
|
||
case LogLevel.INFO:
|
||
return console.info;
|
||
default:
|
||
return console.log;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 记录 DEBUG 级别的日志
|
||
* @param {...any} args
|
||
*/
|
||
debug(...args) {
|
||
this._log(LogLevel.DEBUG, ...args);
|
||
}
|
||
|
||
/**
|
||
* 记录 INFO 级别的日志
|
||
* @param {...any} args
|
||
*/
|
||
info(...args) {
|
||
this._log(LogLevel.INFO, ...args);
|
||
}
|
||
|
||
/**
|
||
* 记录 WARN 级别的日志
|
||
* @param {...any} args
|
||
*/
|
||
warn(...args) {
|
||
this._log(LogLevel.WARN, ...args);
|
||
}
|
||
|
||
/**
|
||
* 记录 ERROR 级别的日志
|
||
* @param {...any} args
|
||
*/
|
||
error(...args) {
|
||
this._log(LogLevel.ERROR, ...args);
|
||
}
|
||
}
|
||
|
||
export const logger = new Logger();
|
||
export const kissLog = logger.info.bind(logger);
|
||
|
||
// todo:debug日志埋点
|