支持集成第三方日志库 (#190)
* 更新 ILogger 签名 改为纯可变参数兼容主流日志库 * 拆分日志类型与实现 * 新增 setLoggerFactory 方法 * tweak * getLoggerName 返回类名,默认情况下子类无需重写 * 更新日志说明文档 * 增加测试 * 使用 getSystemInstanceTypeName,避免压缩导致获取类名不一致
This commit is contained in:
@@ -238,6 +238,50 @@ class HierarchicalLoggingExample {
|
||||
}
|
||||
```
|
||||
|
||||
### 集成第三方日志库
|
||||
|
||||
通过 `setLoggerFactory` 可以将业务代码中的日志器替换为第三方日志库(如 winston、pino、nestjs Logger 等)。
|
||||
|
||||
**说明**: 目前框架内部日志仍使用 ConsoleLogger,自定义日志器仅影响业务代码(如 EntitySystem)。
|
||||
|
||||
#### 基本用法
|
||||
|
||||
```typescript
|
||||
import { setLoggerFactory } from '@esengine/ecs-framework';
|
||||
|
||||
setLoggerFactory((name?: string) => {
|
||||
// 返回实现 ILogger 接口的日志器实例
|
||||
return yourLogger;
|
||||
});
|
||||
```
|
||||
|
||||
#### 使用示例
|
||||
|
||||
```typescript
|
||||
// 集成 Winston
|
||||
setLoggerFactory((name?: string) => winston.createLogger({ /* ... */ }));
|
||||
|
||||
// 集成 Pino
|
||||
setLoggerFactory((name?: string) => pino({ name }));
|
||||
|
||||
// 集成 NestJS Logger
|
||||
setLoggerFactory((name?: string) => new Logger(name));
|
||||
```
|
||||
|
||||
#### EntitySystem 中的使用
|
||||
|
||||
EntitySystem 会自动使用类名创建日志器:
|
||||
|
||||
```typescript
|
||||
class PlayerMovementSystem extends EntitySystem {
|
||||
// this.logger 自动使用 'PlayerMovementSystem' 作为名称
|
||||
|
||||
protected process(entities: readonly Entity[]): void {
|
||||
this.logger.info(`处理 ${entities.length} 个玩家实体`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义输出
|
||||
|
||||
```typescript
|
||||
@@ -547,4 +591,4 @@ class LoggingConfiguration {
|
||||
LoggingConfiguration.setupLogging();
|
||||
```
|
||||
|
||||
日志系统是调试和监控应用的重要工具,正确使用日志系统能大大提高开发效率和问题排查能力。
|
||||
日志系统是调试和监控应用的重要工具,正确使用日志系统能大大提高开发效率和问题排查能力。
|
||||
|
||||
@@ -847,10 +847,10 @@ export abstract class EntitySystem<
|
||||
|
||||
/**
|
||||
* 获取Logger名称
|
||||
* 子类可以重写此方法来自定义logger名称
|
||||
* 默认返回类的构造函数名称, 子类可以重写此方法来自定义logger名称
|
||||
*/
|
||||
protected getLoggerName(): string {
|
||||
return 'EntitySystem';
|
||||
return getSystemInstanceTypeName(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1093,4 +1093,4 @@ export abstract class EntitySystem<
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { createLogger } from '../../Utils/Logger';
|
||||
import type { IComponent } from '../../Types';
|
||||
import { PlatformManager } from '../../Platform/PlatformManager';
|
||||
import type { IPlatformAdapter, PlatformWorker } from '../../Platform/IPlatformAdapter';
|
||||
import { getSystemInstanceTypeName } from '../Decorators';
|
||||
|
||||
/**
|
||||
* Worker处理函数类型
|
||||
@@ -853,7 +854,7 @@ export abstract class WorkerEntitySystem<TEntityData = any> extends EntitySystem
|
||||
}
|
||||
|
||||
protected override getLoggerName(): string {
|
||||
return 'WorkerEntitySystem';
|
||||
return getSystemInstanceTypeName(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1007,4 +1008,4 @@ class PlatformWorkerPool {
|
||||
this.taskQueue.length = 0;
|
||||
this.busyWorkers.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,85 +1,6 @@
|
||||
/**
|
||||
* 日志级别
|
||||
*/
|
||||
export enum LogLevel {
|
||||
Debug = 0,
|
||||
Info = 1,
|
||||
Warn = 2,
|
||||
Error = 3,
|
||||
Fatal = 4,
|
||||
None = 5
|
||||
}
|
||||
import { Colors, LogLevel } from "./Constants";
|
||||
import { ILogger, LoggerColorConfig, LoggerConfig } from "./Types";
|
||||
|
||||
/**
|
||||
* 日志接口
|
||||
*/
|
||||
export interface ILogger {
|
||||
debug(message: string, ...args: unknown[]): void;
|
||||
info(message: string, ...args: unknown[]): void;
|
||||
warn(message: string, ...args: unknown[]): void;
|
||||
error(message: string, ...args: unknown[]): void;
|
||||
fatal(message: string, ...args: unknown[]): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志颜色配置接口
|
||||
*/
|
||||
export interface LoggerColorConfig {
|
||||
debug?: string;
|
||||
info?: string;
|
||||
warn?: string;
|
||||
error?: string;
|
||||
fatal?: string;
|
||||
reset?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预定义的颜色常量
|
||||
*/
|
||||
export const Colors = {
|
||||
// 基础颜色
|
||||
BLACK: '\x1b[30m',
|
||||
RED: '\x1b[31m',
|
||||
GREEN: '\x1b[32m',
|
||||
YELLOW: '\x1b[33m',
|
||||
BLUE: '\x1b[34m',
|
||||
MAGENTA: '\x1b[35m',
|
||||
CYAN: '\x1b[36m',
|
||||
WHITE: '\x1b[37m',
|
||||
|
||||
// 亮色版本
|
||||
BRIGHT_BLACK: '\x1b[90m',
|
||||
BRIGHT_RED: '\x1b[91m',
|
||||
BRIGHT_GREEN: '\x1b[92m',
|
||||
BRIGHT_YELLOW: '\x1b[93m',
|
||||
BRIGHT_BLUE: '\x1b[94m',
|
||||
BRIGHT_MAGENTA: '\x1b[95m',
|
||||
BRIGHT_CYAN: '\x1b[96m',
|
||||
BRIGHT_WHITE: '\x1b[97m',
|
||||
|
||||
// 特殊
|
||||
RESET: '\x1b[0m',
|
||||
BOLD: '\x1b[1m',
|
||||
UNDERLINE: '\x1b[4m'
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 日志配置
|
||||
*/
|
||||
export interface LoggerConfig {
|
||||
/** 日志级别 */
|
||||
level: LogLevel;
|
||||
/** 是否启用时间戳 */
|
||||
enableTimestamp: boolean;
|
||||
/** 是否启用颜色 */
|
||||
enableColors: boolean;
|
||||
/** 日志前缀 */
|
||||
prefix?: string;
|
||||
/** 自定义输出函数 */
|
||||
output?: (level: LogLevel, message: string) => void;
|
||||
/** 自定义颜色配置 */
|
||||
colors?: LoggerColorConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认控制台日志实现
|
||||
@@ -279,157 +200,3 @@ export class ConsoleLogger implements ILogger {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志管理器
|
||||
*/
|
||||
export class LoggerManager {
|
||||
private static _instance: LoggerManager;
|
||||
private _loggers = new Map<string, ILogger>();
|
||||
private _defaultLogger: ILogger;
|
||||
private _defaultLevel = LogLevel.Info;
|
||||
|
||||
private constructor() {
|
||||
this._defaultLogger = new ConsoleLogger({
|
||||
level: this._defaultLevel,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志管理器实例
|
||||
* @returns 日志管理器实例
|
||||
*/
|
||||
public static getInstance(): LoggerManager {
|
||||
if (!LoggerManager._instance) {
|
||||
LoggerManager._instance = new LoggerManager();
|
||||
}
|
||||
return LoggerManager._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建日志器
|
||||
* @param name 日志器名称
|
||||
* @returns 日志器实例
|
||||
*/
|
||||
public getLogger(name?: string): ILogger {
|
||||
if (!name) {
|
||||
return this._defaultLogger;
|
||||
}
|
||||
|
||||
if (!this._loggers.has(name)) {
|
||||
const logger = new ConsoleLogger({
|
||||
prefix: name,
|
||||
level: this._defaultLevel,
|
||||
});
|
||||
this._loggers.set(name, logger);
|
||||
}
|
||||
|
||||
return this._loggers.get(name)!;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置日志器
|
||||
* @param name 日志器名称
|
||||
* @param logger 日志器实例
|
||||
*/
|
||||
public setLogger(name: string, logger: ILogger): void {
|
||||
this._loggers.set(name, logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局日志级别
|
||||
* @param level 日志级别
|
||||
*/
|
||||
public setGlobalLevel(level: LogLevel): void {
|
||||
this._defaultLevel = level;
|
||||
|
||||
if (this._defaultLogger instanceof ConsoleLogger) {
|
||||
this._defaultLogger.setLevel(level);
|
||||
}
|
||||
|
||||
for (const logger of this._loggers.values()) {
|
||||
if (logger instanceof ConsoleLogger) {
|
||||
logger.setLevel(level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建子日志器
|
||||
* @param parentName 父日志器名称
|
||||
* @param childName 子日志器名称
|
||||
* @returns 子日志器实例
|
||||
*/
|
||||
public createChildLogger(parentName: string, childName: string): ILogger {
|
||||
const fullName = `${parentName}.${childName}`;
|
||||
return this.getLogger(fullName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局颜色配置
|
||||
* @param colors 颜色配置
|
||||
*/
|
||||
public setGlobalColors(colors: LoggerColorConfig): void {
|
||||
if (this._defaultLogger instanceof ConsoleLogger) {
|
||||
this._defaultLogger.setColors(colors);
|
||||
}
|
||||
|
||||
for (const logger of this._loggers.values()) {
|
||||
if (logger instanceof ConsoleLogger) {
|
||||
logger.setColors(colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置为默认颜色配置
|
||||
*/
|
||||
public resetColors(): void {
|
||||
if (this._defaultLogger instanceof ConsoleLogger) {
|
||||
this._defaultLogger.setColors({});
|
||||
}
|
||||
|
||||
for (const logger of this._loggers.values()) {
|
||||
if (logger instanceof ConsoleLogger) {
|
||||
logger.setColors({});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认日志器实例
|
||||
*/
|
||||
export const Logger = LoggerManager.getInstance().getLogger();
|
||||
|
||||
/**
|
||||
* 创建命名日志器
|
||||
* @param name 日志器名称
|
||||
* @returns 日志器实例
|
||||
*/
|
||||
export function createLogger(name: string): ILogger {
|
||||
return LoggerManager.getInstance().getLogger(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局日志颜色配置
|
||||
* @param colors 颜色配置
|
||||
*/
|
||||
export function setLoggerColors(colors: LoggerColorConfig): void {
|
||||
LoggerManager.getInstance().setGlobalColors(colors);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置日志颜色为默认配置
|
||||
*/
|
||||
export function resetLoggerColors(): void {
|
||||
LoggerManager.getInstance().resetColors();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局日志级别
|
||||
* @param level 日志级别
|
||||
*/
|
||||
export function setGlobalLogLevel(level: LogLevel): void {
|
||||
LoggerManager.getInstance().setGlobalLevel(level);
|
||||
}
|
||||
41
packages/core/src/Utils/Logger/Constants.ts
Normal file
41
packages/core/src/Utils/Logger/Constants.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 日志级别
|
||||
*/
|
||||
export enum LogLevel {
|
||||
Debug = 0,
|
||||
Info = 1,
|
||||
Warn = 2,
|
||||
Error = 3,
|
||||
Fatal = 4,
|
||||
None = 5
|
||||
}
|
||||
|
||||
/**
|
||||
* 预定义的颜色常量
|
||||
*/
|
||||
export const Colors = {
|
||||
// 基础颜色
|
||||
BLACK: '\x1b[30m',
|
||||
RED: '\x1b[31m',
|
||||
GREEN: '\x1b[32m',
|
||||
YELLOW: '\x1b[33m',
|
||||
BLUE: '\x1b[34m',
|
||||
MAGENTA: '\x1b[35m',
|
||||
CYAN: '\x1b[36m',
|
||||
WHITE: '\x1b[37m',
|
||||
|
||||
// 亮色版本
|
||||
BRIGHT_BLACK: '\x1b[90m',
|
||||
BRIGHT_RED: '\x1b[91m',
|
||||
BRIGHT_GREEN: '\x1b[92m',
|
||||
BRIGHT_YELLOW: '\x1b[93m',
|
||||
BRIGHT_BLUE: '\x1b[94m',
|
||||
BRIGHT_MAGENTA: '\x1b[95m',
|
||||
BRIGHT_CYAN: '\x1b[96m',
|
||||
BRIGHT_WHITE: '\x1b[97m',
|
||||
|
||||
// 特殊
|
||||
RESET: '\x1b[0m',
|
||||
BOLD: '\x1b[1m',
|
||||
UNDERLINE: '\x1b[4m'
|
||||
} as const;
|
||||
194
packages/core/src/Utils/Logger/LoggerManager.ts
Normal file
194
packages/core/src/Utils/Logger/LoggerManager.ts
Normal file
@@ -0,0 +1,194 @@
|
||||
import { ConsoleLogger } from "./ConsoleLogger";
|
||||
import { LogLevel } from "./Constants";
|
||||
import { ILogger, LoggerColorConfig } from "./Types";
|
||||
|
||||
/**
|
||||
* 日志管理器
|
||||
*/
|
||||
export class LoggerManager {
|
||||
private static _instance: LoggerManager;
|
||||
private _loggers = new Map<string, ILogger>();
|
||||
private _defaultLogger?: ILogger;
|
||||
private _defaultLevel = LogLevel.Info;
|
||||
private _loggerFactory?: (name?: string) => ILogger;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
private get defaultLogger(): ILogger {
|
||||
if (!this._defaultLogger) {
|
||||
this._defaultLogger = this.createDefaultLogger();
|
||||
}
|
||||
return this._defaultLogger;
|
||||
}
|
||||
|
||||
// 新增: 创建默认 logger 的逻辑
|
||||
private createDefaultLogger(): ILogger {
|
||||
if (this._loggerFactory) {
|
||||
return this._loggerFactory();
|
||||
}
|
||||
return new ConsoleLogger({ level: this._defaultLevel });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志管理器实例
|
||||
* @returns 日志管理器实例
|
||||
*/
|
||||
public static getInstance(): LoggerManager {
|
||||
if (!LoggerManager._instance) {
|
||||
LoggerManager._instance = new LoggerManager();
|
||||
}
|
||||
return LoggerManager._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建日志器
|
||||
* @param name 日志器名称
|
||||
* @returns 日志器实例
|
||||
*/
|
||||
public getLogger(name?: string): ILogger {
|
||||
if (!name) {
|
||||
return this.defaultLogger;
|
||||
}
|
||||
|
||||
if (!this._loggers.has(name)) {
|
||||
const logger = this._loggerFactory
|
||||
? this._loggerFactory(name)
|
||||
: new ConsoleLogger({ prefix: name, level: this._defaultLevel });
|
||||
this._loggers.set(name, logger);
|
||||
}
|
||||
|
||||
return this._loggers.get(name)!;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置日志器
|
||||
* @param name 日志器名称
|
||||
* @param logger 日志器实例
|
||||
*/
|
||||
public setLogger(name: string, logger: ILogger): void {
|
||||
this._loggers.set(name, logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局日志级别
|
||||
* @param level 日志级别
|
||||
*/
|
||||
public setGlobalLevel(level: LogLevel): void {
|
||||
this._defaultLevel = level;
|
||||
|
||||
if (this._defaultLogger instanceof ConsoleLogger) {
|
||||
this._defaultLogger.setLevel(level);
|
||||
}
|
||||
|
||||
for (const logger of this._loggers.values()) {
|
||||
if (logger instanceof ConsoleLogger) {
|
||||
logger.setLevel(level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建子日志器
|
||||
* @param parentName 父日志器名称
|
||||
* @param childName 子日志器名称
|
||||
* @returns 子日志器实例
|
||||
*/
|
||||
public createChildLogger(parentName: string, childName: string): ILogger {
|
||||
const fullName = `${parentName}.${childName}`;
|
||||
return this.getLogger(fullName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局颜色配置
|
||||
* @param colors 颜色配置
|
||||
*/
|
||||
public setGlobalColors(colors: LoggerColorConfig): void {
|
||||
if (this._defaultLogger instanceof ConsoleLogger) {
|
||||
this._defaultLogger.setColors(colors);
|
||||
}
|
||||
|
||||
for (const logger of this._loggers.values()) {
|
||||
if (logger instanceof ConsoleLogger) {
|
||||
logger.setColors(colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置为默认颜色配置
|
||||
*/
|
||||
public resetColors(): void {
|
||||
if (this._defaultLogger instanceof ConsoleLogger) {
|
||||
this._defaultLogger.setColors({});
|
||||
}
|
||||
|
||||
for (const logger of this._loggers.values()) {
|
||||
if (logger instanceof ConsoleLogger) {
|
||||
logger.setColors({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置日志器工厂方法
|
||||
* @param factory 日志器工厂方法
|
||||
*/
|
||||
public setLoggerFactory(factory: (name?: string) => ILogger): void {
|
||||
if (this._defaultLogger || this._loggers.size > 0) {
|
||||
console.warn(
|
||||
'[LoggerManager] setLoggerFactory 应该在导入 ECS 模块之前调用。' +
|
||||
'已创建的 logger 引用不会被更新。'
|
||||
);
|
||||
}
|
||||
|
||||
this._loggerFactory = factory;
|
||||
// 清空已创建的 logger, 下次获取时使用新工厂方法
|
||||
this._defaultLogger = undefined;
|
||||
this._loggers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认日志器实例
|
||||
*/
|
||||
export const Logger = LoggerManager.getInstance().getLogger();
|
||||
|
||||
/**
|
||||
* 创建命名日志器
|
||||
* @param name 日志器名称
|
||||
* @returns 日志器实例
|
||||
*/
|
||||
export function createLogger(name: string): ILogger {
|
||||
return LoggerManager.getInstance().getLogger(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局日志颜色配置
|
||||
* @param colors 颜色配置
|
||||
*/
|
||||
export function setLoggerColors(colors: LoggerColorConfig): void {
|
||||
LoggerManager.getInstance().setGlobalColors(colors);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置日志颜色为默认配置
|
||||
*/
|
||||
export function resetLoggerColors(): void {
|
||||
LoggerManager.getInstance().resetColors();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局日志级别
|
||||
* @param level 日志级别
|
||||
*/
|
||||
export function setGlobalLogLevel(level: LogLevel): void {
|
||||
LoggerManager.getInstance().setGlobalLevel(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置日志器工厂方法
|
||||
* @param factory 日志器工厂方法
|
||||
*/
|
||||
export function setLoggerFactory(factory: (name?: string) => ILogger): void {
|
||||
LoggerManager.getInstance().setLoggerFactory(factory);
|
||||
}
|
||||
42
packages/core/src/Utils/Logger/Types.ts
Normal file
42
packages/core/src/Utils/Logger/Types.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { LogLevel } from "./Constants";
|
||||
|
||||
/**
|
||||
* 日志接口
|
||||
*/
|
||||
export interface ILogger {
|
||||
debug(...args: unknown[]): void;
|
||||
info(...args: unknown[]): void;
|
||||
warn(...args: unknown[]): void;
|
||||
error(...args: unknown[]): void;
|
||||
fatal(...args: unknown[]): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志颜色配置接口
|
||||
*/
|
||||
export interface LoggerColorConfig {
|
||||
debug?: string;
|
||||
info?: string;
|
||||
warn?: string;
|
||||
error?: string;
|
||||
fatal?: string;
|
||||
reset?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志配置
|
||||
*/
|
||||
export interface LoggerConfig {
|
||||
/** 日志级别 */
|
||||
level: LogLevel;
|
||||
/** 是否启用时间戳 */
|
||||
enableTimestamp: boolean;
|
||||
/** 是否启用颜色 */
|
||||
enableColors: boolean;
|
||||
/** 日志前缀 */
|
||||
prefix?: string;
|
||||
/** 自定义输出函数 */
|
||||
output?: (level: LogLevel, message: string) => void;
|
||||
/** 自定义颜色配置 */
|
||||
colors?: LoggerColorConfig;
|
||||
}
|
||||
4
packages/core/src/Utils/Logger/index.ts
Normal file
4
packages/core/src/Utils/Logger/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './ConsoleLogger';
|
||||
export * from './Constants';
|
||||
export * from './LoggerManager';
|
||||
export * from './Types';
|
||||
@@ -5,4 +5,4 @@ export * from './GlobalManager';
|
||||
export * from './PerformanceMonitor';
|
||||
export { Time } from './Time';
|
||||
export * from './Debug';
|
||||
export * from './Logger';
|
||||
export * from './Logger';
|
||||
|
||||
@@ -214,4 +214,11 @@ describe('EntitySystem', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('日志器命名', () => {
|
||||
it('应该使用类名作为日志器名称', () => {
|
||||
const loggerName = (system as any).getLoggerName();
|
||||
expect(loggerName).toBe('ConcreteEntitySystem');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -153,24 +153,125 @@ describe('Logger', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('LoggerManager - 自定义工厂', () => {
|
||||
let manager: LoggerManager;
|
||||
|
||||
beforeEach(() => {
|
||||
manager = LoggerManager.getInstance();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// 重置工厂,恢复默认 ConsoleLogger
|
||||
(manager as any)._loggerFactory = undefined;
|
||||
(manager as any)._defaultLogger = undefined;
|
||||
(manager as any)._loggers.clear();
|
||||
});
|
||||
|
||||
it('应该支持设置自定义日志器工厂', () => {
|
||||
const mockLogger = {
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
fatal: jest.fn()
|
||||
};
|
||||
|
||||
manager.setLoggerFactory(() => mockLogger);
|
||||
const logger = manager.getLogger('CustomLogger');
|
||||
|
||||
expect(logger).toBe(mockLogger);
|
||||
});
|
||||
|
||||
it('应该将日志器名称传递给工厂方法', () => {
|
||||
const factorySpy = jest.fn(() => ({
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
fatal: jest.fn()
|
||||
}));
|
||||
|
||||
manager.setLoggerFactory(factorySpy);
|
||||
manager.getLogger('TestLogger');
|
||||
|
||||
expect(factorySpy).toHaveBeenCalledWith('TestLogger');
|
||||
});
|
||||
|
||||
it('应该在设置工厂后清空已创建的日志器', () => {
|
||||
const logger1 = manager.getLogger('TestLogger');
|
||||
|
||||
manager.setLoggerFactory(() => ({
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
fatal: jest.fn()
|
||||
}));
|
||||
|
||||
const logger2 = manager.getLogger('TestLogger');
|
||||
expect(logger2).not.toBe(logger1);
|
||||
});
|
||||
|
||||
it('应该延迟创建默认日志器直到首次使用', () => {
|
||||
const factorySpy = jest.fn(() => ({
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
fatal: jest.fn()
|
||||
}));
|
||||
|
||||
manager.setLoggerFactory(factorySpy);
|
||||
// 此时不应该调用工厂
|
||||
expect(factorySpy).not.toHaveBeenCalled();
|
||||
|
||||
// 获取默认日志器时才调用
|
||||
manager.getLogger();
|
||||
expect(factorySpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('应该在已创建日志器后设置工厂时发出警告', () => {
|
||||
const warnSpy = jest.spyOn(console, 'warn').mockImplementation();
|
||||
|
||||
// 先创建一个日志器
|
||||
manager.getLogger('ExistingLogger');
|
||||
|
||||
// 再设置工厂
|
||||
manager.setLoggerFactory(() => ({
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
fatal: jest.fn()
|
||||
}));
|
||||
|
||||
expect(warnSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining('setLoggerFactory 应该在导入 ECS 模块之前调用')
|
||||
);
|
||||
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('全局颜色配置', () => {
|
||||
let consoleSpy: jest.SpyInstance;
|
||||
|
||||
|
||||
beforeEach(() => {
|
||||
consoleSpy = jest.spyOn(console, 'info').mockImplementation();
|
||||
});
|
||||
|
||||
|
||||
afterEach(() => {
|
||||
consoleSpy.mockRestore();
|
||||
resetLoggerColors();
|
||||
});
|
||||
|
||||
it('应该支持全局设置颜色配置', () => {
|
||||
const logger = createLogger('TestLogger');
|
||||
|
||||
setLoggerColors({
|
||||
info: Colors.MAGENTA
|
||||
});
|
||||
|
||||
const logger = createLogger('TestLogger');
|
||||
logger.info('测试消息');
|
||||
|
||||
const call = consoleSpy.mock.calls[0][0];
|
||||
@@ -179,17 +280,18 @@ describe('Logger', () => {
|
||||
});
|
||||
|
||||
it('应该支持重置颜色配置为默认值', () => {
|
||||
const logger = createLogger('TestLogger');
|
||||
|
||||
setLoggerColors({
|
||||
info: Colors.MAGENTA
|
||||
});
|
||||
|
||||
resetLoggerColors();
|
||||
|
||||
const logger = createLogger('TestLogger');
|
||||
logger.info('测试消息');
|
||||
|
||||
const call = consoleSpy.mock.calls[0][0];
|
||||
expect(call).toContain('\x1b[32m');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user