@chaeco/logger 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/README.zh-CN.md +126 -0
  4. package/dist/core/logger.d.ts +41 -0
  5. package/dist/core/logger.d.ts.map +1 -0
  6. package/dist/core/logger.js +233 -0
  7. package/dist/core/logger.js.map +1 -0
  8. package/dist/core/types.d.ts +155 -0
  9. package/dist/core/types.d.ts.map +1 -0
  10. package/dist/core/types.js +3 -0
  11. package/dist/core/types.js.map +1 -0
  12. package/dist/file/async-queue.d.ts +24 -0
  13. package/dist/file/async-queue.d.ts.map +1 -0
  14. package/dist/file/async-queue.js +95 -0
  15. package/dist/file/async-queue.js.map +1 -0
  16. package/dist/file/file-manager.d.ts +29 -0
  17. package/dist/file/file-manager.d.ts.map +1 -0
  18. package/dist/file/file-manager.js +85 -0
  19. package/dist/file/file-manager.js.map +1 -0
  20. package/dist/file/node-writer.d.ts +30 -0
  21. package/dist/file/node-writer.d.ts.map +1 -0
  22. package/dist/file/node-writer.js +219 -0
  23. package/dist/file/node-writer.js.map +1 -0
  24. package/dist/index.d.ts +16 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +22 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/utils/caller-info.d.ts +29 -0
  29. package/dist/utils/caller-info.d.ts.map +1 -0
  30. package/dist/utils/caller-info.js +120 -0
  31. package/dist/utils/caller-info.js.map +1 -0
  32. package/dist/utils/color-utils.d.ts +19 -0
  33. package/dist/utils/color-utils.d.ts.map +1 -0
  34. package/dist/utils/color-utils.js +51 -0
  35. package/dist/utils/color-utils.js.map +1 -0
  36. package/dist/utils/formatter.d.ts +51 -0
  37. package/dist/utils/formatter.d.ts.map +1 -0
  38. package/dist/utils/formatter.js +166 -0
  39. package/dist/utils/formatter.js.map +1 -0
  40. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 chaeco
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # @chaeco/logger
2
+
3
+ A feature-rich, high-performance logging library for Node.js.
4
+
5
+ [![npm version](https://img.shields.io/badge/version-0.1.6-blue.svg)](https://github.com/chaeco/logger)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-3178c6.svg)](https://www.typescriptlang.org/)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D16-339933.svg)](https://nodejs.org/)
9
+ [![Build](https://img.shields.io/badge/build-passing-brightgreen.svg)](https://github.com/chaeco/logger)
10
+ [![Coverage](https://img.shields.io/badge/coverage-77%20tests-brightgreen.svg)](https://github.com/chaeco/logger)
11
+
12
+ [English](README.md) | [中文](README.zh-CN.md)
13
+
14
+ ## Features
15
+
16
+ - ✅ **Standard Log Levels**: `debug`, `info`, `warn`, `error`, and `silent`.
17
+ - ✅ **Auto-Context**: Automatically captures caller file path and line numbers.
18
+ - ✅ **File Management**: Size-based rotation, age/count cleanup, Gzip compression.
19
+ - ✅ **Async Queue**: Batch writing with `drop` / `block` / `overflow` strategies.
20
+ - ✅ **Formatting**: Plain text, JSON, and custom `formatter` function.
21
+ - ✅ **Event Hooks**: `levelChange`, `fileWriteError` event listeners.
22
+ - ✅ **Child Logger**: `logger.child('module')` inherits config with scoped name.
23
+ - ✅ **TypeScript Native**: Full type safety and intellisense.
24
+ - ⚠️ **Node.js only**: Browser environments are not supported.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install github:chaeco/logger
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ### Basic Usage
35
+
36
+ ```typescript
37
+ import { logger } from '@chaeco/logger';
38
+
39
+ // Use directly - directory is created automatically on first write
40
+ logger.info('Application started');
41
+ logger.warn('Warning detected', { code: 4001 });
42
+ logger.error(new Error('Database connection failed'));
43
+ logger.debug('Debug details', { timing: 142 });
44
+
45
+ // Disable logging
46
+ logger.setLevel('silent');
47
+ ```
48
+
49
+ > **Note**: Log directories are created automatically upon the first log entry. No manual initialization is required.
50
+
51
+ ### Advanced Configuration
52
+
53
+ ```typescript
54
+ import { Logger } from '@chaeco/logger';
55
+
56
+ const logger = new Logger({
57
+ level: 'info',
58
+ name: 'api-service',
59
+ file: {
60
+ path: './logs',
61
+ maxSize: 10 * 1024 * 1024, // 10MB
62
+ maxFiles: 30,
63
+ maxAge: 30, // days
64
+ compress: true, // gzip logs older than today
65
+ },
66
+ console: { enabled: true, colors: true, timestamp: true },
67
+ async: {
68
+ enabled: true,
69
+ batchSize: 100,
70
+ flushInterval: 1000,
71
+ overflowStrategy: 'drop', // 'drop' | 'block' | 'overflow'
72
+ },
73
+ format: { json: true, jsonIndent: 2 },
74
+ errorHandling: {
75
+ silent: true,
76
+ onError: (err, ctx) => console.error(`[${ctx}]`, err.message),
77
+ },
78
+ });
79
+ ```
80
+
81
+ ### Child Logger
82
+
83
+ ```typescript
84
+ const dbLogger = logger.child('db');
85
+ dbLogger.info('Connected'); // logged as [api-service:db]
86
+
87
+ const reqLogger = logger.child('request');
88
+ reqLogger.warn('Slow response', { duration: 3200 });
89
+ ```
90
+
91
+ ### Event Hooks
92
+
93
+ ```typescript
94
+ logger.on('levelChange', (e) => {
95
+ console.log(`Level changed: ${e.data.oldLevel} → ${e.data.newLevel}`);
96
+ });
97
+
98
+ logger.on('fileWriteError', (e) => {
99
+ // trigger external alert (e.g. Sentry, PagerDuty)
100
+ console.error('Log write failed:', e.error?.message);
101
+ });
102
+ ```
103
+
104
+ ### Lifecycle
105
+
106
+ ```typescript
107
+ // Flush async queue and close file handles before process exit
108
+ process.on('SIGTERM', async () => {
109
+ await logger.close();
110
+ process.exit(0);
111
+ });
112
+ ```
113
+
114
+ ## Documentation
115
+
116
+ - [Detailed Examples](docs/examples.md)
117
+ - [Performance Optimization](docs/performance.md)
118
+ - [Production Best Practices](docs/production.md)
119
+ - [Changelog](CHANGELOG.md)
120
+
121
+ ## License
122
+
123
+ MIT © [chaeco](https://github.com/chaeco)
@@ -0,0 +1,126 @@
1
+ # @chaeco/logger
2
+
3
+ 一个功能丰富、高性能的 Node.js 日志库。
4
+
5
+ [![npm version](https://img.shields.io/badge/版本-0.1.6-blue.svg)](https://github.com/chaeco/logger)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-3178c6.svg)](https://www.typescriptlang.org/)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D16-339933.svg)](https://nodejs.org/)
9
+ [![Build](https://img.shields.io/badge/构建-通过-brightgreen.svg)](https://github.com/chaeco/logger)
10
+ [![Coverage](https://img.shields.io/badge/测试-77%20tests-brightgreen.svg)](https://github.com/chaeco/logger)
11
+
12
+ [English](README.md) | 中文
13
+
14
+ ## 功能特性
15
+
16
+ - ✅ **标准日志级别**: `debug`、`info`、`warn`、`error` 和 `silent`。
17
+ - ✅ **自动上下文**: 自动捕获调用者文件路径和行号。
18
+ - ✅ **文件管理**:
19
+ - 基于大小的自动日志轮转。
20
+ - 基于时间/数量的自动清理旧日志。
21
+ - 内置 Gzip 压缩归档日志。
22
+ - ✅ **异步队列**: 高性能异步批量写入,支持 `drop` / `block` / `overflow` 溢出策略。
23
+ - ✅ **格式化**: 纯文本、JSON 格式及自定义 formatter 函数。
24
+ - ✅ **事件钩子**: 支持 `levelChange`、`fileWriteError` 事件监听。
25
+ - ✅ **子 Logger**: `logger.child('module')` 继承父级配置,独立命名。
26
+ - ✅ **TypeScript 原生支持**: 完整的类型安全和智能感知。
27
+ - ⚠️ **仅支持 Node.js**: 不支持浏览器环境。
28
+
29
+ ## 安装
30
+
31
+ ```bash
32
+ npm install github:chaeco/logger
33
+ ```
34
+
35
+ ## 快速开始
36
+
37
+ ### 基本用法
38
+
39
+ ```typescript
40
+ import { logger } from '@chaeco/logger';
41
+
42
+ // 直接使用 - 首次写入时自动创建目录
43
+ logger.info('应用已启动');
44
+ logger.warn('检测到警告', { code: 4001 });
45
+ logger.error(new Error('数据库连接失败'));
46
+ logger.debug('调试信息', { timing: 142 });
47
+
48
+ // 禁用日志
49
+ logger.setLevel('silent');
50
+ ```
51
+
52
+ > **注意**: 日志目录会在首次日志记录时自动创建,不需要手动初始化。
53
+
54
+ ### 高级配置
55
+
56
+ ```typescript
57
+ import { Logger } from '@chaeco/logger';
58
+
59
+ const logger = new Logger({
60
+ level: 'info',
61
+ name: 'api-service',
62
+ file: {
63
+ path: './logs',
64
+ maxSize: 10 * 1024 * 1024, // 10MB
65
+ maxFiles: 30,
66
+ maxAge: 30, // 天数
67
+ compress: true, // 压缩今天之前的日志文件(gzip)
68
+ },
69
+ console: { enabled: true, colors: true, timestamp: true },
70
+ async: {
71
+ enabled: true,
72
+ batchSize: 100,
73
+ flushInterval: 1000,
74
+ overflowStrategy: 'drop', // 'drop' | 'block' | 'overflow'
75
+ },
76
+ format: { json: true, jsonIndent: 2 },
77
+ errorHandling: {
78
+ silent: true,
79
+ onError: (err, ctx) => console.error(`[${ctx}]`, err.message),
80
+ },
81
+ });
82
+ ```
83
+
84
+ ### 子 Logger
85
+
86
+ ```typescript
87
+ const dbLogger = logger.child('db');
88
+ dbLogger.info('已连接'); // 输出名称为 [api-service:db]
89
+
90
+ const reqLogger = logger.child('request');
91
+ reqLogger.warn('响应较慢', { duration: 3200 });
92
+ ```
93
+
94
+ ### 事件钩子
95
+
96
+ ```typescript
97
+ logger.on('levelChange', (e) => {
98
+ console.log(`日志级别变更: ${e.data.oldLevel} → ${e.data.newLevel}`);
99
+ });
100
+
101
+ logger.on('fileWriteError', (e) => {
102
+ // 触发外部告警(如 Sentry、钉钉机器人等)
103
+ console.error('日志写入失败:', e.error?.message);
104
+ });
105
+ ```
106
+
107
+ ### 生命周期
108
+
109
+ ```typescript
110
+ // 进程退出前刷新异步队列并关闭文件句柄
111
+ process.on('SIGTERM', async () => {
112
+ await logger.close();
113
+ process.exit(0);
114
+ });
115
+ ```
116
+
117
+ ## 文档
118
+
119
+ - [详细示例](docs/zh-CN/examples.md)
120
+ - [性能优化](docs/zh-CN/performance.md)
121
+ - [生产部署最佳实践](docs/zh-CN/production.md)
122
+ - [更新日志](docs/zh-CN/CHANGELOG.md)
123
+
124
+ ## 许可证
125
+
126
+ MIT © [chaeco](https://github.com/chaeco)
@@ -0,0 +1,41 @@
1
+ import { LogLevel, LoggerOptions, LoggerEventType, LoggerEventHandler, FormatOptions, ErrorHandlingOptions } from './types';
2
+ /**
3
+ * 日志器主类
4
+ * @remarks
5
+ * 扁平结构,无继承。支持多级别日志、彩色控制台输出、文件写入、事件钩子与子 Logger。
6
+ * 仅支持 Node.js 运行时。
7
+ */
8
+ export declare class Logger {
9
+ private level;
10
+ private readonly name;
11
+ private fileManager;
12
+ private consoleEnabled;
13
+ private readonly formatter;
14
+ private readonly callerInfoHelper;
15
+ private readonly errorHandling;
16
+ private readonly eventHandlers;
17
+ private readonly levelPriority;
18
+ constructor(options?: LoggerOptions);
19
+ init(): void;
20
+ debug(...args: any[]): void;
21
+ info(...args: any[]): void;
22
+ warn(...args: any[]): void;
23
+ error(...args: any[]): void;
24
+ setLevel(level: LogLevel): void;
25
+ getLevel(): LogLevel;
26
+ configureFormat(options: Partial<FormatOptions>): void;
27
+ configureErrorHandling(options: ErrorHandlingOptions): void;
28
+ updateConfig(options: LoggerOptions): void;
29
+ on(type: LoggerEventType, handler: LoggerEventHandler): void;
30
+ off(type: LoggerEventType, handler: LoggerEventHandler): void;
31
+ child(name: string): Logger;
32
+ close(): Promise<void>;
33
+ private shouldLog;
34
+ private emitEvent;
35
+ private createLogEntry;
36
+ private writeToConsole;
37
+ private writeToFile;
38
+ private handleWriteError;
39
+ private log;
40
+ }
41
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EAAE,aAAa,EACvB,eAAe,EAAE,kBAAkB,EACnC,aAAa,EAAE,oBAAoB,EACpC,MAAM,SAAS,CAAA;AAMhB;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IACzC,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAyB;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE7B;IACD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwD;IACtF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE7B;gBAEW,OAAO,GAAE,aAAkB;IA6BvC,IAAI,IAAI,IAAI;IAIZ,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAC3B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAC1B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAC1B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAM/B,QAAQ,IAAI,QAAQ;IAIpB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAItD,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAM3D,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAgB1C,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAK5D,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAS7D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IA+BrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,GAAG;CAwBZ"}
@@ -0,0 +1,233 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Logger = void 0;
7
+ const file_manager_1 = require("../file/file-manager");
8
+ const caller_info_1 = require("../utils/caller-info");
9
+ const formatter_1 = require("../utils/formatter");
10
+ const dayjs_1 = __importDefault(require("dayjs"));
11
+ /**
12
+ * 日志器主类
13
+ * @remarks
14
+ * 扁平结构,无继承。支持多级别日志、彩色控制台输出、文件写入、事件钩子与子 Logger。
15
+ * 仅支持 Node.js 运行时。
16
+ */
17
+ class Logger {
18
+ constructor(options = {}) {
19
+ this.callerInfoHelper = new caller_info_1.CallerInfoHelper();
20
+ this.errorHandling = {
21
+ silent: true, onError: undefined, fallbackToConsole: true,
22
+ };
23
+ this.eventHandlers = new Map();
24
+ this.levelPriority = {
25
+ debug: 0, info: 1, warn: 2, error: 3, silent: 999,
26
+ };
27
+ this.level = options.level ?? 'info';
28
+ this.name = options.name;
29
+ if (options.file?.enabled !== false) {
30
+ this.fileManager = new file_manager_1.FileManager(options.file, options.async);
31
+ }
32
+ this.consoleEnabled = options.console?.enabled ?? true;
33
+ this.formatter = new formatter_1.LogFormatter({
34
+ consoleColors: options.console?.colors ?? true,
35
+ consoleTimestamp: options.console?.timestamp ?? true,
36
+ format: {
37
+ enabled: options.format?.enabled ?? false,
38
+ timestampFormat: options.format?.timestampFormat ?? 'YYYY-MM-DD HH:mm:ss.SSS',
39
+ formatter: options.format?.formatter,
40
+ includeStack: options.format?.includeStack ?? true,
41
+ includeName: options.format?.includeName ?? true,
42
+ json: options.format?.json ?? false,
43
+ jsonIndent: options.format?.jsonIndent ?? 0,
44
+ },
45
+ });
46
+ if (options.errorHandling)
47
+ this.configureErrorHandling(options.errorHandling);
48
+ }
49
+ // ─── 初始化 ──────────────────────────────────────────────
50
+ init() { this.fileManager?.init(); }
51
+ // ─── 核心日志方法 ─────────────────────────────────────────
52
+ debug(...args) { this.log('debug', ...args); }
53
+ info(...args) { this.log('info', ...args); }
54
+ warn(...args) { this.log('warn', ...args); }
55
+ error(...args) { this.log('error', ...args); }
56
+ // ─── 等级控制 ─────────────────────────────────────────────
57
+ setLevel(level) {
58
+ const old = this.level;
59
+ this.level = level;
60
+ this.emitEvent('levelChange', `日志等级已从 ${old} 更改为 ${level}`, undefined, { oldLevel: old, newLevel: level });
61
+ }
62
+ getLevel() { return this.level; }
63
+ // ─── 配置 ─────────────────────────────────────────────────
64
+ configureFormat(options) {
65
+ this.formatter.updateFormat(options);
66
+ }
67
+ configureErrorHandling(options) {
68
+ if (options.silent !== undefined)
69
+ this.errorHandling.silent = options.silent;
70
+ if (options.onError !== undefined)
71
+ this.errorHandling.onError = options.onError;
72
+ if (options.fallbackToConsole !== undefined)
73
+ this.errorHandling.fallbackToConsole = options.fallbackToConsole;
74
+ }
75
+ updateConfig(options) {
76
+ if (options.level !== undefined)
77
+ this.setLevel(options.level);
78
+ if (options.console !== undefined) {
79
+ this.consoleEnabled = options.console.enabled ?? this.consoleEnabled;
80
+ this.formatter.settings.consoleColors = options.console.colors ?? this.formatter.settings.consoleColors;
81
+ this.formatter.settings.consoleTimestamp = options.console.timestamp ?? this.formatter.settings.consoleTimestamp;
82
+ }
83
+ if (options.file !== undefined && options.file.enabled !== false && !this.fileManager) {
84
+ this.fileManager = new file_manager_1.FileManager(options.file, options.async);
85
+ }
86
+ if (options.format)
87
+ this.configureFormat(options.format);
88
+ if (options.errorHandling)
89
+ this.configureErrorHandling(options.errorHandling);
90
+ }
91
+ // ─── 事件 ────────────────────────────────────────────────
92
+ on(type, handler) {
93
+ if (!this.eventHandlers.has(type))
94
+ this.eventHandlers.set(type, []);
95
+ this.eventHandlers.get(type).push(handler);
96
+ }
97
+ off(type, handler) {
98
+ const handlers = this.eventHandlers.get(type);
99
+ if (!handlers)
100
+ return;
101
+ const i = handlers.indexOf(handler);
102
+ if (i > -1)
103
+ handlers.splice(i, 1);
104
+ }
105
+ // ─── 子 Logger ───────────────────────────────────────────
106
+ child(name) {
107
+ const { consoleColors, consoleTimestamp, format } = this.formatter.settings;
108
+ const opts = {
109
+ level: this.level,
110
+ name: this.name ? `${this.name}:${name}` : name,
111
+ console: { enabled: this.consoleEnabled, colors: consoleColors, timestamp: consoleTimestamp },
112
+ format: { ...format },
113
+ errorHandling: { ...this.errorHandling },
114
+ };
115
+ if (this.fileManager) {
116
+ const fmOpts = this.fileManager.getOptions();
117
+ opts.file = {
118
+ enabled: true,
119
+ path: fmOpts.path,
120
+ maxSize: fmOpts.maxSize,
121
+ maxFiles: fmOpts.maxFiles,
122
+ filename: fmOpts.filename,
123
+ maxAge: fmOpts.maxAge,
124
+ compress: fmOpts.compress,
125
+ retryCount: fmOpts.retryCount,
126
+ retryDelay: fmOpts.retryDelay,
127
+ };
128
+ opts.async = this.fileManager.getAsyncOptions();
129
+ }
130
+ else {
131
+ opts.file = { enabled: false };
132
+ }
133
+ return new Logger(opts);
134
+ }
135
+ // ─── 生命周期 ────────────────────────────────────────────
136
+ async close() {
137
+ if (this.fileManager) {
138
+ try {
139
+ await this.fileManager.close();
140
+ }
141
+ catch (e) {
142
+ console.error('Error closing FileManager:', e);
143
+ }
144
+ }
145
+ }
146
+ // ─── 内部实现 ────────────────────────────────────────────
147
+ shouldLog(level) {
148
+ return this.levelPriority[level] >= this.levelPriority[this.level];
149
+ }
150
+ emitEvent(type, message, error, data) {
151
+ const handlers = this.eventHandlers.get(type);
152
+ if (!handlers?.length)
153
+ return;
154
+ const event = { type, message, error, data, timestamp: (0, dayjs_1.default)().format('YYYY-MM-DD HH:mm:ss.SSS') };
155
+ for (const h of handlers) {
156
+ try {
157
+ h(event);
158
+ }
159
+ catch (e) {
160
+ console.error('Error in logger event handler:', e);
161
+ }
162
+ }
163
+ }
164
+ createLogEntry(level, message, data) {
165
+ const { file, line } = this.callerInfoHelper.getCallerInfo();
166
+ const entry = {
167
+ level,
168
+ message,
169
+ timestamp: (0, dayjs_1.default)().format('YYYY-MM-DD HH:mm:ss.SSS'),
170
+ data,
171
+ };
172
+ if (this.name)
173
+ entry.name = this.name;
174
+ if (file)
175
+ entry.file = file;
176
+ if (line)
177
+ entry.line = line;
178
+ return entry;
179
+ }
180
+ writeToConsole(entry) {
181
+ if (!this.consoleEnabled)
182
+ return;
183
+ const msg = this.formatter.formatConsoleMessage(entry);
184
+ const consoleFn = entry.level === 'error' ? console.error : console.log;
185
+ consoleFn(msg);
186
+ }
187
+ writeToFile(entry) {
188
+ if (!this.fileManager)
189
+ return;
190
+ const msg = this.formatter.formatMessage(entry);
191
+ this.fileManager.write(msg).catch(e => this.handleWriteError(e, msg, entry));
192
+ }
193
+ handleWriteError(error, message, entry) {
194
+ const err = error instanceof Error ? error : new Error(String(error));
195
+ try {
196
+ this.errorHandling.onError?.(err, 'file_write');
197
+ }
198
+ catch (e) {
199
+ console.error('Error in error handler:', e);
200
+ }
201
+ const preview = message.length > 120 ? message.slice(0, 120) + '…' : message;
202
+ this.emitEvent('fileWriteError', `文件写入失败: ${preview}`, err);
203
+ if (this.errorHandling.fallbackToConsole && !this.errorHandling.silent && entry)
204
+ console.error('[Logger Fallback]', this.formatter.formatConsoleMessage(entry));
205
+ }
206
+ log(level, ...args) {
207
+ if (!this.shouldLog(level))
208
+ return;
209
+ let message;
210
+ let data;
211
+ if (args.length === 0) {
212
+ message = '';
213
+ data = undefined;
214
+ }
215
+ else if (typeof args[0] === 'string') {
216
+ message = args[0];
217
+ data = args.length === 2 ? args[1] : args.length > 2 ? args.slice(1) : undefined;
218
+ }
219
+ else if (args[0] instanceof Error) {
220
+ message = args[0].message || String(args[0]);
221
+ data = args.length > 1 ? { error: args[0], additionalData: args.slice(1) } : args[0];
222
+ }
223
+ else {
224
+ message = '';
225
+ data = args.length === 1 ? args[0] : args;
226
+ }
227
+ const entry = this.createLogEntry(level, message, data);
228
+ this.writeToConsole(entry);
229
+ this.writeToFile(entry);
230
+ }
231
+ }
232
+ exports.Logger = Logger;
233
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"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"}