@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
@@ -0,0 +1,155 @@
1
+ /**
2
+ * 日志等级类型
3
+ * @remarks
4
+ * - debug: 调试信息,最详细的日志级别
5
+ * - info: 一般信息,用于记录正常的系统操作
6
+ * - warn: 警告信息,表示潜在的问题
7
+ * - error: 错误信息,表示系统出现错误
8
+ * - silent: 静默模式,不输出任何日志
9
+ */
10
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
11
+ /**
12
+ * Logger 配置选项
13
+ */
14
+ export interface LoggerOptions {
15
+ /** 日志等级,默认为 'info' */
16
+ level?: LogLevel;
17
+ /** 文件输出配置 */
18
+ file?: FileOptions;
19
+ /** 控制台输出配置 */
20
+ console?: ConsoleOptions;
21
+ /** Logger 名称,用于区分不同的 logger 实例 */
22
+ name?: string;
23
+ /** 日志格式化配置 */
24
+ format?: FormatOptions;
25
+ /** 异步写入配置(Node.js) */
26
+ async?: AsyncWriteOptions;
27
+ /** 错误处理配置 */
28
+ errorHandling?: ErrorHandlingOptions;
29
+ }
30
+ /**
31
+ * 文件输出配置选项
32
+ */
33
+ export interface FileOptions {
34
+ /** 是否启用文件输出,默认为 true */
35
+ enabled?: boolean;
36
+ /** 日志文件存储路径,默认为 './logs' */
37
+ path?: string;
38
+ /** 单个日志文件的最大大小(字节),默认为 10485760(10 MB) */
39
+ maxSize?: number;
40
+ /** 最大保留的日志文件数量,默认为 30 */
41
+ maxFiles?: number;
42
+ /** 日志文件名前缀,默认为 'app' */
43
+ filename?: string;
44
+ /** 日志文件最大保留天数,超过该天数的日志将被自动删除,默认为 30 天 */
45
+ maxAge?: number;
46
+ /** 是否压缩旧的日志文件(gzip),默认为 false */
47
+ compress?: boolean;
48
+ /** 写入失败时的重试次数,默认为 3 */
49
+ retryCount?: number;
50
+ /** 重试间隔基数(毫秒),实际延迟为 retryDelay * attempt,默认为 100 */
51
+ retryDelay?: number;
52
+ }
53
+ /**
54
+ * 控制台输出配置选项
55
+ */
56
+ export interface ConsoleOptions {
57
+ /** 是否启用控制台输出,默认为 true */
58
+ enabled?: boolean;
59
+ /** 是否启用彩色输出,默认为 true */
60
+ colors?: boolean;
61
+ /** 是否显示时间戳,默认为 true */
62
+ timestamp?: boolean;
63
+ }
64
+ /**
65
+ * 日志条目接口
66
+ * @internal
67
+ */
68
+ export interface LogEntry {
69
+ /** 日志等级 */
70
+ level: LogLevel;
71
+ /** 日志消息内容 */
72
+ message: string;
73
+ /** 时间戳 */
74
+ timestamp: string;
75
+ /** Logger 名称 */
76
+ name?: string;
77
+ /** 调用者文件路径 */
78
+ file?: string;
79
+ /** 调用者行号 */
80
+ line?: number;
81
+ /** 附加数据 */
82
+ data?: any;
83
+ }
84
+ /**
85
+ * Logger 事件类型
86
+ */
87
+ export type LoggerEventType = 'error' | 'fileWriteError' | 'levelChange';
88
+ /**
89
+ * Logger 事件处理程序
90
+ */
91
+ export type LoggerEventHandler = (event: LoggerEvent) => void;
92
+ /**
93
+ * Logger 事件接口
94
+ */
95
+ export interface LoggerEvent {
96
+ /** 事件类型 */
97
+ type: LoggerEventType;
98
+ /** 事件消息 */
99
+ message: string;
100
+ /** 事件发生的时间戳 */
101
+ timestamp: string;
102
+ /** 相关的错误对象(如果有) */
103
+ error?: Error;
104
+ /** 事件的附加数据 */
105
+ data?: any;
106
+ }
107
+ /**
108
+ * 日志格式化配置选项
109
+ */
110
+ export interface FormatOptions {
111
+ /** 是否启用自定义 formatter 函数,默认为 false。
112
+ * 仅控制 `formatter` 函数是否生效;`json` 模式独立工作,不受此开关影响 */
113
+ enabled?: boolean;
114
+ /** 日期时间格式,默认为 'YYYY-MM-DD HH:mm:ss.SSS' */
115
+ timestampFormat?: string;
116
+ /** 自定义格式化函数 */
117
+ formatter?: (entry: LogEntry) => string;
118
+ /** 是否包含调用栈信息,默认为 true */
119
+ includeStack?: boolean;
120
+ /** 是否包含 logger 名称,默认为 true */
121
+ includeName?: boolean;
122
+ /** JSON 格式输出,默认为 false */
123
+ json?: boolean;
124
+ /** JSON 缩进空格数(仅当 json=true 时生效),0 表示不缩进 */
125
+ jsonIndent?: number;
126
+ }
127
+ /**
128
+ * 异步写入配置选项(Node.js)
129
+ */
130
+ export interface AsyncWriteOptions {
131
+ /** 是否启用异步写入,默认为 false */
132
+ enabled?: boolean;
133
+ /** 写入队列最大长度,默认为 1000 */
134
+ queueSize?: number;
135
+ /** 批量写入的最大条数,默认为 100 */
136
+ batchSize?: number;
137
+ /** 批量写入的最大等待时间(毫秒),默认为 1000 */
138
+ flushInterval?: number;
139
+ /** 队列满时的处理策略:'drop'(丢弃新消息)、'block'(等待当前批次写完再继续)、
140
+ * 'overflow'(当前与 'block' 等效:等待写完后继续;未来可扩展为独立溢出队列) */
141
+ overflowStrategy?: 'drop' | 'block' | 'overflow';
142
+ }
143
+ /**
144
+ * 错误处理配置选项
145
+ */
146
+ export interface ErrorHandlingOptions {
147
+ /** 是否静默错误:true(默认)→ 抑制所有 stderr 输出,仅通过 onError 回调和事件通知;
148
+ * false → 与 fallbackToConsole 协同:当 fallbackToConsole:true 时输出 console.error */
149
+ silent?: boolean;
150
+ /** 错误回调函数 */
151
+ onError?: (error: Error, context: string) => void;
152
+ /** 是否在错误时降级到控制台输出,默认为 true */
153
+ fallbackToConsole?: boolean;
154
+ }
155
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { AsyncWriteOptions } from '../core/types';
2
+ /**
3
+ * 异步写入队列 - 批量缓冲日志消息,按批次大小或定时间隔写入。
4
+ * @internal
5
+ */
6
+ export declare class AsyncQueue {
7
+ private queue;
8
+ private isWriting;
9
+ private flushTimer?;
10
+ private readonly options;
11
+ private readonly onFlush;
12
+ constructor(options: Required<AsyncWriteOptions>, onFlush: (messages: string[]) => Promise<void>);
13
+ get size(): number;
14
+ get writing(): boolean;
15
+ /** 启动定时刷新器 */
16
+ start(): void;
17
+ /** 将消息加入队列 */
18
+ enqueue(message: string): Promise<void>;
19
+ /** 立即刷新队列 */
20
+ flush(): Promise<void>;
21
+ /** 停止定时器并持续刷新直到队列完全清空 */
22
+ stop(): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=async-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-queue.d.ts","sourceRoot":"","sources":["../../src/file/async-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEjD;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,UAAU,CAAC,CAAgB;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;gBAEnD,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC;IAKhG,IAAI,IAAI,IAAI,MAAM,CAA6B;IAC/C,IAAI,OAAO,IAAI,OAAO,CAA0B;IAEhD,cAAc;IACd,KAAK,IAAI,IAAI;IAWb,cAAc;IACR,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB7C,aAAa;IACP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B,yBAAyB;IACnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAyB5B"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AsyncQueue = void 0;
4
+ /**
5
+ * 异步写入队列 - 批量缓冲日志消息,按批次大小或定时间隔写入。
6
+ * @internal
7
+ */
8
+ class AsyncQueue {
9
+ constructor(options, onFlush) {
10
+ this.queue = [];
11
+ this.isWriting = false;
12
+ this.options = options;
13
+ this.onFlush = onFlush;
14
+ }
15
+ get size() { return this.queue.length; }
16
+ get writing() { return this.isWriting; }
17
+ /** 启动定时刷新器 */
18
+ start() {
19
+ if (this.flushTimer)
20
+ return;
21
+ this.flushTimer = setInterval(() => {
22
+ if (this.queue.length > 0) {
23
+ this.flush().catch(e => console.error('Failed to flush log queue:', e));
24
+ }
25
+ }, this.options.flushInterval);
26
+ // unref 使定时器不阻止进程自然退出(进程中只剩这个定时器时可以退出)
27
+ this.flushTimer.unref?.();
28
+ }
29
+ /** 将消息加入队列 */
30
+ async enqueue(message) {
31
+ // 用 while 而非 if:flush 失败时消息会被退回队列,队列仍可能满,需重新判断。
32
+ // 若一直用 if,flush 失败后依然 push,队列长度将无限突破 queueSize 上界。
33
+ while (this.queue.length >= this.options.queueSize) {
34
+ switch (this.options.overflowStrategy) {
35
+ case 'drop': return;
36
+ case 'block':
37
+ case 'overflow':
38
+ // 'block' 和 'overflow' 均在此处先刷写一批再继续入队。
39
+ // 注意:'overflow' 字面含义为"溢出到新队列",当前实现与 'block' 等效——
40
+ // 都是等待当前批次写完后继续。如需真正独立溢出队列,需扩展此处逻辑。
41
+ await this.flush();
42
+ break;
43
+ }
44
+ }
45
+ this.queue.push(message);
46
+ if (this.queue.length >= this.options.batchSize) {
47
+ await this.flush();
48
+ }
49
+ }
50
+ /** 立即刷新队列 */
51
+ async flush() {
52
+ if (this.isWriting || this.queue.length === 0)
53
+ return;
54
+ this.isWriting = true;
55
+ const messages = this.queue.splice(0, this.options.batchSize);
56
+ try {
57
+ await this.onFlush(messages);
58
+ }
59
+ catch (e) {
60
+ console.error('Failed to flush queue:', e);
61
+ this.queue.unshift(...messages);
62
+ }
63
+ finally {
64
+ this.isWriting = false;
65
+ }
66
+ }
67
+ /** 停止定时器并持续刷新直到队列完全清空 */
68
+ async stop() {
69
+ if (this.flushTimer) {
70
+ clearInterval(this.flushTimer);
71
+ this.flushTimer = undefined;
72
+ }
73
+ // 循环直到队列彻底清空(每次最多写 batchSize 条)。
74
+ // 若 onFlush 持续失败,flush() 会将消息退回队列,此处设置最大重试轮次防止死循环。
75
+ // FLUSH_SAFETY_BUFFER 额外轮次:防止 onFlush 间歇性失败时循环提前终止。
76
+ const FLUSH_SAFETY_BUFFER = 3;
77
+ const maxAttempts = Math.ceil(this.queue.length / this.options.batchSize) + FLUSH_SAFETY_BUFFER;
78
+ let attempts = 0;
79
+ while (this.queue.length > 0 && attempts < maxAttempts) {
80
+ if (this.isWriting) {
81
+ // 如果当前正在进行 flush(可能来自 setInterval),等待一小段时间再重试
82
+ await new Promise(r => setTimeout(r, 10));
83
+ attempts++;
84
+ continue;
85
+ }
86
+ await this.flush();
87
+ attempts++;
88
+ }
89
+ if (this.queue.length > 0) {
90
+ console.error(`@chaeco/logger: AsyncQueue stopped with ${this.queue.length} unwritten messages (flush failed repeatedly)`);
91
+ }
92
+ }
93
+ }
94
+ exports.AsyncQueue = AsyncQueue;
95
+ //# sourceMappingURL=async-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-queue.js","sourceRoot":"","sources":["../../src/file/async-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { FileOptions, AsyncWriteOptions } from '../core/types';
2
+ /**
3
+ * 文件管理器 - 管理日志文件写入(仅 Node.js)。
4
+ * @internal
5
+ */
6
+ export declare class FileManager {
7
+ private isInitialized;
8
+ private initError?;
9
+ private nodeWriter;
10
+ private asyncQueue?;
11
+ private readonly options;
12
+ private readonly asyncOptions?;
13
+ constructor(options?: FileOptions, asyncOptions?: AsyncWriteOptions);
14
+ /** 提前初始化(可选,首次写入时也会自动初始化) */
15
+ init(): void;
16
+ write(message: string): Promise<void>;
17
+ /** 获取当前文件配置(只读),供 child logger 复制时使用 */
18
+ getOptions(): Readonly<Required<FileOptions>>;
19
+ /** 获取异步写入配置(只读),供 child logger 继承异步策略 */
20
+ getAsyncOptions(): Readonly<AsyncWriteOptions> | undefined;
21
+ /** 关闭存储,刷新剩余队列 */
22
+ close(): Promise<void>;
23
+ /** 获取异步队列状态 */
24
+ getQueueStatus(): {
25
+ size: number;
26
+ isWriting: boolean;
27
+ };
28
+ }
29
+ //# sourceMappingURL=file-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-manager.d.ts","sourceRoot":"","sources":["../../src/file/file-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAI9D;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAO;IACzB,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAmB;gBAErC,OAAO,GAAE,WAAgB,EAAE,YAAY,CAAC,EAAE,iBAAiB;IA4BvE,6BAA6B;IACtB,IAAI,IAAI,IAAI;IAYb,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,wCAAwC;IACxC,UAAU,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAI7C,yCAAyC;IACzC,eAAe,IAAI,QAAQ,CAAC,iBAAiB,CAAC,GAAG,SAAS;IAI1D,kBAAkB;IACZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,eAAe;IACf,cAAc,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE;CAGvD"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileManager = void 0;
4
+ const node_writer_1 = require("./node-writer");
5
+ const async_queue_1 = require("./async-queue");
6
+ /**
7
+ * 文件管理器 - 管理日志文件写入(仅 Node.js)。
8
+ * @internal
9
+ */
10
+ class FileManager {
11
+ constructor(options = {}, asyncOptions) {
12
+ this.isInitialized = false;
13
+ this.asyncOptions = asyncOptions;
14
+ this.options = {
15
+ enabled: options.enabled ?? true,
16
+ path: options.path ?? './logs',
17
+ maxSize: options.maxSize ?? 10 * 1024 * 1024,
18
+ maxFiles: options.maxFiles ?? 30,
19
+ filename: options.filename ?? 'app',
20
+ maxAge: options.maxAge ?? 30,
21
+ compress: options.compress ?? false,
22
+ retryCount: options.retryCount ?? 3,
23
+ retryDelay: options.retryDelay ?? 100,
24
+ };
25
+ this.nodeWriter = new node_writer_1.NodeWriter(this.options);
26
+ if (asyncOptions?.enabled) {
27
+ const ao = {
28
+ enabled: asyncOptions.enabled,
29
+ queueSize: asyncOptions.queueSize ?? 1000,
30
+ batchSize: asyncOptions.batchSize ?? 100,
31
+ flushInterval: asyncOptions.flushInterval ?? 1000,
32
+ overflowStrategy: asyncOptions.overflowStrategy ?? 'drop',
33
+ };
34
+ this.asyncQueue = new async_queue_1.AsyncQueue(ao, msgs => this.nodeWriter.writeBatch(msgs));
35
+ this.asyncQueue.start();
36
+ }
37
+ }
38
+ /** 提前初始化(可选,首次写入时也会自动初始化) */
39
+ init() {
40
+ if (this.isInitialized)
41
+ return;
42
+ try {
43
+ this.nodeWriter.init();
44
+ if (this.nodeWriter.initError)
45
+ this.initError = this.nodeWriter.initError;
46
+ else
47
+ this.isInitialized = true;
48
+ }
49
+ catch (e) {
50
+ this.initError = e instanceof Error ? e : new Error(String(e));
51
+ console.warn('@chaeco/logger: Failed to initialize FileManager:', e);
52
+ }
53
+ }
54
+ async write(message) {
55
+ if (!this.options.enabled)
56
+ return;
57
+ if (!this.isInitialized && !this.initError)
58
+ this.init();
59
+ if (this.initError)
60
+ return;
61
+ if (this.asyncQueue) {
62
+ await this.asyncQueue.enqueue(message);
63
+ return;
64
+ }
65
+ await this.nodeWriter.write(message);
66
+ }
67
+ /** 获取当前文件配置(只读),供 child logger 复制时使用 */
68
+ getOptions() {
69
+ return this.options;
70
+ }
71
+ /** 获取异步写入配置(只读),供 child logger 继承异步策略 */
72
+ getAsyncOptions() {
73
+ return this.asyncOptions;
74
+ }
75
+ /** 关闭存储,刷新剩余队列 */
76
+ async close() {
77
+ await this.asyncQueue?.stop();
78
+ }
79
+ /** 获取异步队列状态 */
80
+ getQueueStatus() {
81
+ return { size: this.asyncQueue?.size ?? 0, isWriting: this.asyncQueue?.writing ?? false };
82
+ }
83
+ }
84
+ exports.FileManager = FileManager;
85
+ //# sourceMappingURL=file-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-manager.js","sourceRoot":"","sources":["../../src/file/file-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { FileOptions } from '../core/types';
2
+ /**
3
+ * Node.js 文件写入器 - 管理日志文件的创建、轮转、压缩与清理。
4
+ * @internal
5
+ */
6
+ export declare class NodeWriter {
7
+ private readonly options;
8
+ private currentFilePath;
9
+ private currentFileSize;
10
+ private fileIndex;
11
+ private _initError;
12
+ /** 初始化错误(只读),如果初始化失败则值不为 undefined */
13
+ get initError(): Error | undefined;
14
+ constructor(options: Required<FileOptions>);
15
+ init(): void;
16
+ /** 写入单条消息(内部使用 appendFileSync,通过重试逻辑提供可靠性) */
17
+ write(message: string): Promise<void>;
18
+ /** 批量写入消息(由 AsyncQueue 刷新时调用) */
19
+ writeBatch(messages: string[]): Promise<void>;
20
+ private ensureLogDirectory;
21
+ private initializeCurrentFile;
22
+ private getIndexedFilePath;
23
+ private shouldRotateFile;
24
+ private rotateFile;
25
+ private cleanupOldFiles;
26
+ private compressOldLogs;
27
+ private checkDateRotation;
28
+ private appendToFileWithRetry;
29
+ }
30
+ //# sourceMappingURL=node-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-writer.d.ts","sourceRoot":"","sources":["../../src/file/node-writer.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAO3C;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,UAAU,CAAmB;IAErC,sCAAsC;IACtC,IAAI,SAAS,IAAI,KAAK,GAAG,SAAS,CAA2B;gBAEjD,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC;IAQ1C,IAAI,IAAI,IAAI;IAKZ,8CAA8C;IACxC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,iCAAiC;IAC3B,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,qBAAqB;IA2B7B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,eAAe;YAiCT,eAAe;IAuB7B,OAAO,CAAC,iBAAiB;YAMX,qBAAqB;CAiBpC"}