@rawnodes/logger 1.7.0 → 1.8.0
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.
- package/README.md +200 -2
- package/dist/index.d.mts +142 -6
- package/dist/index.d.ts +142 -6
- package/dist/index.js +509 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +503 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -105,6 +105,198 @@ const logger = Logger.create({
|
|
|
105
105
|
});
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
### Per-Transport Level
|
|
109
|
+
|
|
110
|
+
Each transport can have its own log level:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const logger = Logger.create({
|
|
114
|
+
level: 'silly', // accept all at logger level
|
|
115
|
+
console: {
|
|
116
|
+
format: 'plain',
|
|
117
|
+
level: 'debug', // console: debug and above
|
|
118
|
+
},
|
|
119
|
+
file: {
|
|
120
|
+
format: 'json',
|
|
121
|
+
level: 'warn', // file: only warn and error
|
|
122
|
+
dirname: 'logs',
|
|
123
|
+
filename: 'app-%DATE%.log',
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
| Scenario | Console | File |
|
|
129
|
+
|----------|---------|------|
|
|
130
|
+
| Development | `debug` | — |
|
|
131
|
+
| Production | `info` | `warn` |
|
|
132
|
+
| Troubleshooting | `debug` | `info` |
|
|
133
|
+
| Critical alerts | `info` | `error` |
|
|
134
|
+
|
|
135
|
+
This is useful for sending only critical errors to alerting systems while keeping verbose logs in console.
|
|
136
|
+
|
|
137
|
+
### Per-Transport Rules
|
|
138
|
+
|
|
139
|
+
Each transport can have its own filtering rules. Use `level: 'off'` with rules to create a whitelist pattern:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
const logger = Logger.create({
|
|
143
|
+
level: 'info',
|
|
144
|
+
console: { format: 'plain' },
|
|
145
|
+
file: {
|
|
146
|
+
format: 'json',
|
|
147
|
+
level: 'off', // off by default
|
|
148
|
+
rules: [
|
|
149
|
+
{ match: { context: 'payments' }, level: 'error' }, // only errors from payments
|
|
150
|
+
{ match: { context: 'auth' }, level: 'warn' }, // warn+ from auth
|
|
151
|
+
],
|
|
152
|
+
dirname: 'logs',
|
|
153
|
+
filename: 'critical-%DATE%.log',
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Only error logs from 'payments' context go to file
|
|
158
|
+
logger.for('payments').error('Payment failed'); // → file
|
|
159
|
+
logger.for('payments').info('Processing'); // ✗ not logged to file
|
|
160
|
+
logger.for('other').error('Generic error'); // ✗ not logged to file (no matching rule)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Rules can also match store context (AsyncLocalStorage):
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
const logger = Logger.create({
|
|
167
|
+
level: 'info',
|
|
168
|
+
console: { format: 'plain' },
|
|
169
|
+
file: {
|
|
170
|
+
format: 'json',
|
|
171
|
+
level: 'off',
|
|
172
|
+
rules: [
|
|
173
|
+
{ match: { userId: 123 }, level: 'debug' }, // debug for specific user
|
|
174
|
+
{ match: { context: 'api', premium: true }, level: 'debug' }, // debug for premium API users
|
|
175
|
+
],
|
|
176
|
+
dirname: 'logs',
|
|
177
|
+
filename: 'debug-%DATE%.log',
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Logs for user 123 go to file
|
|
182
|
+
store.run({ userId: 123 }, () => {
|
|
183
|
+
logger.debug('User action'); // → file
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Use `level: 'off'` in rules to suppress specific contexts:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const logger = Logger.create({
|
|
191
|
+
level: 'debug',
|
|
192
|
+
console: {
|
|
193
|
+
format: 'plain',
|
|
194
|
+
level: 'debug',
|
|
195
|
+
rules: [
|
|
196
|
+
{ match: { context: 'noisy-module' }, level: 'off' }, // suppress noisy logs
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
logger.for('noisy-module').debug('Spam'); // ✗ not logged
|
|
202
|
+
logger.for('other').debug('Useful info'); // → logged
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## External Transports
|
|
206
|
+
|
|
207
|
+
### Discord
|
|
208
|
+
|
|
209
|
+
Send logs to Discord via webhooks with rich embeds:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
const logger = Logger.create({
|
|
213
|
+
level: 'info',
|
|
214
|
+
console: { format: 'plain' },
|
|
215
|
+
discord: {
|
|
216
|
+
webhookUrl: 'https://discord.com/api/webhooks/xxx/yyy',
|
|
217
|
+
level: 'error', // only errors to Discord
|
|
218
|
+
username: 'My App Logger', // optional bot name
|
|
219
|
+
avatarUrl: 'https://...', // optional avatar
|
|
220
|
+
embedColors: { // optional custom colors
|
|
221
|
+
error: 0xFF0000,
|
|
222
|
+
warn: 0xFFAA00,
|
|
223
|
+
},
|
|
224
|
+
batchSize: 10, // messages per batch (default: 10)
|
|
225
|
+
flushInterval: 2000, // flush interval ms (default: 2000)
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Telegram
|
|
231
|
+
|
|
232
|
+
Send logs to Telegram chats/channels:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
const logger = Logger.create({
|
|
236
|
+
level: 'info',
|
|
237
|
+
console: { format: 'plain' },
|
|
238
|
+
telegram: {
|
|
239
|
+
botToken: process.env.TG_BOT_TOKEN!,
|
|
240
|
+
chatId: process.env.TG_CHAT_ID!,
|
|
241
|
+
level: 'warn', // warn and above
|
|
242
|
+
parseMode: 'Markdown', // 'Markdown' | 'MarkdownV2' | 'HTML'
|
|
243
|
+
disableNotification: false, // mute non-error by default
|
|
244
|
+
threadId: 123, // optional forum topic ID
|
|
245
|
+
replyToMessageId: 456, // optional reply to message
|
|
246
|
+
batchSize: 20, // default: 20
|
|
247
|
+
flushInterval: 1000, // default: 1000
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Use `level: 'off'` with rules for selective logging:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
telegram: {
|
|
256
|
+
botToken: '...',
|
|
257
|
+
chatId: '...',
|
|
258
|
+
level: 'off', // off by default
|
|
259
|
+
rules: [
|
|
260
|
+
{ match: { context: 'payments' }, level: 'error' }, // only payment errors
|
|
261
|
+
],
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### CloudWatch
|
|
266
|
+
|
|
267
|
+
Send logs to AWS CloudWatch Logs:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
const logger = Logger.create({
|
|
271
|
+
level: 'info',
|
|
272
|
+
console: { format: 'plain' },
|
|
273
|
+
cloudwatch: {
|
|
274
|
+
logGroupName: '/app/my-service',
|
|
275
|
+
logStreamName: `${hostname}-${Date.now()}`,
|
|
276
|
+
region: 'us-east-1',
|
|
277
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
278
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
279
|
+
createLogGroup: true, // auto-create group (default: false)
|
|
280
|
+
createLogStream: true, // auto-create stream (default: true)
|
|
281
|
+
batchSize: 100, // default: 100
|
|
282
|
+
flushInterval: 1000, // default: 1000
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Transport Options
|
|
288
|
+
|
|
289
|
+
All external transports support:
|
|
290
|
+
|
|
291
|
+
| Option | Default | Description |
|
|
292
|
+
|--------|---------|-------------|
|
|
293
|
+
| `level` | — | Log level filter |
|
|
294
|
+
| `rules` | — | Per-transport filtering rules |
|
|
295
|
+
| `batchSize` | varies | Max messages per batch |
|
|
296
|
+
| `flushInterval` | varies | Flush interval in ms |
|
|
297
|
+
| `maxRetries` | 3 | Retry count on failure |
|
|
298
|
+
| `retryDelay` | 1000 | Base retry delay in ms |
|
|
299
|
+
|
|
108
300
|
## Singleton Pattern
|
|
109
301
|
|
|
110
302
|
For app-wide logging:
|
|
@@ -312,7 +504,7 @@ class Logger<TContext> {
|
|
|
312
504
|
### Types
|
|
313
505
|
|
|
314
506
|
```typescript
|
|
315
|
-
type LogLevel = 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly';
|
|
507
|
+
type LogLevel = 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly' | 'off';
|
|
316
508
|
type LogFormat = 'json' | 'plain' | 'logfmt' | 'simple';
|
|
317
509
|
type Meta = object | (() => object);
|
|
318
510
|
|
|
@@ -321,9 +513,15 @@ interface LoggerConfig {
|
|
|
321
513
|
default: LogLevel;
|
|
322
514
|
rules?: LevelRule[];
|
|
323
515
|
};
|
|
324
|
-
console: {
|
|
516
|
+
console: {
|
|
517
|
+
format: LogFormat;
|
|
518
|
+
level?: LogLevel; // optional, overrides global level
|
|
519
|
+
rules?: LevelRule[]; // optional, per-transport filtering
|
|
520
|
+
};
|
|
325
521
|
file?: {
|
|
326
522
|
format: LogFormat;
|
|
523
|
+
level?: LogLevel; // optional, overrides global level
|
|
524
|
+
rules?: LevelRule[]; // optional, per-transport filtering
|
|
327
525
|
dirname: string;
|
|
328
526
|
filename: string;
|
|
329
527
|
datePattern?: string;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import TransportStream from 'winston-transport';
|
|
2
|
+
|
|
1
3
|
declare const LOG_LEVELS: {
|
|
4
|
+
readonly off: -1;
|
|
2
5
|
readonly error: 0;
|
|
3
6
|
readonly warn: 1;
|
|
4
7
|
readonly info: 2;
|
|
@@ -11,11 +14,21 @@ type LogLevel = keyof typeof LOG_LEVELS;
|
|
|
11
14
|
declare function isValidLogLevel(level: string): level is LogLevel;
|
|
12
15
|
declare function assertLogLevel(level: string): asserts level is LogLevel;
|
|
13
16
|
type LogFormat = 'json' | 'plain' | 'logfmt' | 'simple';
|
|
17
|
+
interface LevelRule {
|
|
18
|
+
match: Record<string, unknown> & {
|
|
19
|
+
context?: string;
|
|
20
|
+
};
|
|
21
|
+
level: LogLevel;
|
|
22
|
+
}
|
|
14
23
|
interface ConsoleConfig {
|
|
15
24
|
format: LogFormat;
|
|
25
|
+
level?: LogLevel;
|
|
26
|
+
rules?: LevelRule[];
|
|
16
27
|
}
|
|
17
28
|
interface FileConfig {
|
|
18
29
|
format: LogFormat;
|
|
30
|
+
level?: LogLevel;
|
|
31
|
+
rules?: LevelRule[];
|
|
19
32
|
dirname: string;
|
|
20
33
|
filename: string;
|
|
21
34
|
datePattern?: string;
|
|
@@ -23,11 +36,39 @@ interface FileConfig {
|
|
|
23
36
|
maxSize?: string;
|
|
24
37
|
maxFiles?: string;
|
|
25
38
|
}
|
|
26
|
-
interface
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
interface HttpTransportBaseConfig {
|
|
40
|
+
level?: LogLevel;
|
|
41
|
+
rules?: LevelRule[];
|
|
42
|
+
batchSize?: number;
|
|
43
|
+
flushInterval?: number;
|
|
44
|
+
maxRetries?: number;
|
|
45
|
+
retryDelay?: number;
|
|
46
|
+
}
|
|
47
|
+
interface DiscordConfig extends HttpTransportBaseConfig {
|
|
48
|
+
webhookUrl: string;
|
|
49
|
+
username?: string;
|
|
50
|
+
avatarUrl?: string;
|
|
51
|
+
embedColors?: Partial<Record<LogLevel, number>>;
|
|
52
|
+
includeTimestamp?: boolean;
|
|
53
|
+
includeMeta?: boolean;
|
|
54
|
+
maxEmbedFields?: number;
|
|
55
|
+
}
|
|
56
|
+
interface TelegramConfig extends HttpTransportBaseConfig {
|
|
57
|
+
botToken: string;
|
|
58
|
+
chatId: string | number;
|
|
59
|
+
parseMode?: 'Markdown' | 'MarkdownV2' | 'HTML';
|
|
60
|
+
disableNotification?: boolean;
|
|
61
|
+
threadId?: number;
|
|
62
|
+
replyToMessageId?: number;
|
|
63
|
+
}
|
|
64
|
+
interface CloudWatchConfig extends HttpTransportBaseConfig {
|
|
65
|
+
logGroupName: string;
|
|
66
|
+
logStreamName: string;
|
|
67
|
+
region: string;
|
|
68
|
+
accessKeyId: string;
|
|
69
|
+
secretAccessKey: string;
|
|
70
|
+
createLogGroup?: boolean;
|
|
71
|
+
createLogStream?: boolean;
|
|
31
72
|
}
|
|
32
73
|
interface LevelConfigObject {
|
|
33
74
|
default: LogLevel;
|
|
@@ -38,6 +79,9 @@ interface LoggerConfig {
|
|
|
38
79
|
level: LevelConfig;
|
|
39
80
|
console: ConsoleConfig;
|
|
40
81
|
file?: FileConfig;
|
|
82
|
+
discord?: DiscordConfig;
|
|
83
|
+
telegram?: TelegramConfig;
|
|
84
|
+
cloudwatch?: CloudWatchConfig;
|
|
41
85
|
}
|
|
42
86
|
type LoggerContext = Record<string, unknown>;
|
|
43
87
|
type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
|
|
@@ -90,6 +134,98 @@ interface SingletonLogger<TContext extends LoggerContext> {
|
|
|
90
134
|
}
|
|
91
135
|
declare function createSingletonLogger<TContext extends LoggerContext = LoggerContext>(): SingletonLogger<TContext>;
|
|
92
136
|
|
|
137
|
+
declare function matchesContext(storeContext: LoggerContext | undefined, loggerContext: string | undefined, match: Record<string, unknown> & {
|
|
138
|
+
context?: string;
|
|
139
|
+
}): boolean;
|
|
140
|
+
|
|
141
|
+
interface BufferedMessage {
|
|
142
|
+
level: LogLevel;
|
|
143
|
+
message: string;
|
|
144
|
+
timestamp: Date;
|
|
145
|
+
context?: string;
|
|
146
|
+
meta?: Record<string, unknown>;
|
|
147
|
+
}
|
|
148
|
+
interface BufferOptions {
|
|
149
|
+
batchSize: number;
|
|
150
|
+
flushInterval: number;
|
|
151
|
+
maxRetries: number;
|
|
152
|
+
retryDelay: number;
|
|
153
|
+
onFlush: (messages: BufferedMessage[]) => Promise<void>;
|
|
154
|
+
onError?: (error: Error, messages: BufferedMessage[]) => void;
|
|
155
|
+
}
|
|
156
|
+
declare class MessageBuffer {
|
|
157
|
+
private options;
|
|
158
|
+
private queue;
|
|
159
|
+
private timer;
|
|
160
|
+
private flushing;
|
|
161
|
+
private closed;
|
|
162
|
+
constructor(options: BufferOptions);
|
|
163
|
+
add(message: BufferedMessage): void;
|
|
164
|
+
flush(): Promise<void>;
|
|
165
|
+
close(): Promise<void>;
|
|
166
|
+
private scheduleFlush;
|
|
167
|
+
private clearTimer;
|
|
168
|
+
private sendWithRetry;
|
|
169
|
+
private delay;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
interface BaseHttpTransportOptions {
|
|
173
|
+
batchSize?: number;
|
|
174
|
+
flushInterval?: number;
|
|
175
|
+
maxRetries?: number;
|
|
176
|
+
retryDelay?: number;
|
|
177
|
+
}
|
|
178
|
+
declare abstract class BaseHttpTransport extends TransportStream {
|
|
179
|
+
protected buffer: MessageBuffer;
|
|
180
|
+
constructor(opts?: BaseHttpTransportOptions);
|
|
181
|
+
log(info: Record<string, unknown>, callback: () => void): void;
|
|
182
|
+
close(): Promise<void>;
|
|
183
|
+
protected transformMessage(info: Record<string, unknown>): BufferedMessage;
|
|
184
|
+
protected handleError(error: Error, messages: BufferedMessage[]): void;
|
|
185
|
+
protected abstract sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
declare class DiscordTransport extends BaseHttpTransport {
|
|
189
|
+
private config;
|
|
190
|
+
constructor(config: DiscordConfig);
|
|
191
|
+
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
192
|
+
private createEmbed;
|
|
193
|
+
private metaToFields;
|
|
194
|
+
private sendWebhook;
|
|
195
|
+
private chunkArray;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare class TelegramTransport extends BaseHttpTransport {
|
|
199
|
+
private config;
|
|
200
|
+
private apiUrl;
|
|
201
|
+
constructor(config: TelegramConfig);
|
|
202
|
+
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
203
|
+
private formatBatchMessage;
|
|
204
|
+
private formatMarkdown;
|
|
205
|
+
private formatHtml;
|
|
206
|
+
private shouldMute;
|
|
207
|
+
private sendMessage;
|
|
208
|
+
private escapeMarkdownV2;
|
|
209
|
+
private escapeHtml;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
declare class CloudWatchTransport extends BaseHttpTransport {
|
|
213
|
+
private config;
|
|
214
|
+
private client;
|
|
215
|
+
private sequenceToken;
|
|
216
|
+
private initialized;
|
|
217
|
+
private initPromise;
|
|
218
|
+
constructor(config: CloudWatchConfig);
|
|
219
|
+
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
220
|
+
private ensureInitialized;
|
|
221
|
+
private initialize;
|
|
222
|
+
private createLogGroupIfNotExists;
|
|
223
|
+
private createLogStreamIfNotExists;
|
|
224
|
+
private fetchSequenceToken;
|
|
225
|
+
private isResourceAlreadyExistsError;
|
|
226
|
+
private isInvalidSequenceTokenError;
|
|
227
|
+
}
|
|
228
|
+
|
|
93
229
|
interface TimingResult {
|
|
94
230
|
label: string;
|
|
95
231
|
durationMs: number;
|
|
@@ -124,4 +260,4 @@ declare function flattenObject(obj: Record<string, unknown>, prefix?: string): R
|
|
|
124
260
|
declare function formatLogfmtValue(value: unknown): string;
|
|
125
261
|
declare function formatLogfmt(data: Record<string, unknown>): string;
|
|
126
262
|
|
|
127
|
-
export { type ConsoleConfig, type FileConfig, LOG_LEVELS, type LevelConfig, type LevelConfigObject, type LevelOverride, type LevelOverrideMatch, type LevelRule, type LogFormat, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type Meta, type RequestIdOptions, type SingletonLogger, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
|
|
263
|
+
export { BaseHttpTransport, type BaseHttpTransportOptions, type BufferOptions, type BufferedMessage, type CloudWatchConfig, CloudWatchTransport, type ConsoleConfig, type DiscordConfig, DiscordTransport, type FileConfig, type HttpTransportBaseConfig, LOG_LEVELS, type LevelConfig, type LevelConfigObject, type LevelOverride, type LevelOverrideMatch, type LevelRule, type LogFormat, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, MessageBuffer, type Meta, type RequestIdOptions, type SingletonLogger, type TelegramConfig, TelegramTransport, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import TransportStream from 'winston-transport';
|
|
2
|
+
|
|
1
3
|
declare const LOG_LEVELS: {
|
|
4
|
+
readonly off: -1;
|
|
2
5
|
readonly error: 0;
|
|
3
6
|
readonly warn: 1;
|
|
4
7
|
readonly info: 2;
|
|
@@ -11,11 +14,21 @@ type LogLevel = keyof typeof LOG_LEVELS;
|
|
|
11
14
|
declare function isValidLogLevel(level: string): level is LogLevel;
|
|
12
15
|
declare function assertLogLevel(level: string): asserts level is LogLevel;
|
|
13
16
|
type LogFormat = 'json' | 'plain' | 'logfmt' | 'simple';
|
|
17
|
+
interface LevelRule {
|
|
18
|
+
match: Record<string, unknown> & {
|
|
19
|
+
context?: string;
|
|
20
|
+
};
|
|
21
|
+
level: LogLevel;
|
|
22
|
+
}
|
|
14
23
|
interface ConsoleConfig {
|
|
15
24
|
format: LogFormat;
|
|
25
|
+
level?: LogLevel;
|
|
26
|
+
rules?: LevelRule[];
|
|
16
27
|
}
|
|
17
28
|
interface FileConfig {
|
|
18
29
|
format: LogFormat;
|
|
30
|
+
level?: LogLevel;
|
|
31
|
+
rules?: LevelRule[];
|
|
19
32
|
dirname: string;
|
|
20
33
|
filename: string;
|
|
21
34
|
datePattern?: string;
|
|
@@ -23,11 +36,39 @@ interface FileConfig {
|
|
|
23
36
|
maxSize?: string;
|
|
24
37
|
maxFiles?: string;
|
|
25
38
|
}
|
|
26
|
-
interface
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
interface HttpTransportBaseConfig {
|
|
40
|
+
level?: LogLevel;
|
|
41
|
+
rules?: LevelRule[];
|
|
42
|
+
batchSize?: number;
|
|
43
|
+
flushInterval?: number;
|
|
44
|
+
maxRetries?: number;
|
|
45
|
+
retryDelay?: number;
|
|
46
|
+
}
|
|
47
|
+
interface DiscordConfig extends HttpTransportBaseConfig {
|
|
48
|
+
webhookUrl: string;
|
|
49
|
+
username?: string;
|
|
50
|
+
avatarUrl?: string;
|
|
51
|
+
embedColors?: Partial<Record<LogLevel, number>>;
|
|
52
|
+
includeTimestamp?: boolean;
|
|
53
|
+
includeMeta?: boolean;
|
|
54
|
+
maxEmbedFields?: number;
|
|
55
|
+
}
|
|
56
|
+
interface TelegramConfig extends HttpTransportBaseConfig {
|
|
57
|
+
botToken: string;
|
|
58
|
+
chatId: string | number;
|
|
59
|
+
parseMode?: 'Markdown' | 'MarkdownV2' | 'HTML';
|
|
60
|
+
disableNotification?: boolean;
|
|
61
|
+
threadId?: number;
|
|
62
|
+
replyToMessageId?: number;
|
|
63
|
+
}
|
|
64
|
+
interface CloudWatchConfig extends HttpTransportBaseConfig {
|
|
65
|
+
logGroupName: string;
|
|
66
|
+
logStreamName: string;
|
|
67
|
+
region: string;
|
|
68
|
+
accessKeyId: string;
|
|
69
|
+
secretAccessKey: string;
|
|
70
|
+
createLogGroup?: boolean;
|
|
71
|
+
createLogStream?: boolean;
|
|
31
72
|
}
|
|
32
73
|
interface LevelConfigObject {
|
|
33
74
|
default: LogLevel;
|
|
@@ -38,6 +79,9 @@ interface LoggerConfig {
|
|
|
38
79
|
level: LevelConfig;
|
|
39
80
|
console: ConsoleConfig;
|
|
40
81
|
file?: FileConfig;
|
|
82
|
+
discord?: DiscordConfig;
|
|
83
|
+
telegram?: TelegramConfig;
|
|
84
|
+
cloudwatch?: CloudWatchConfig;
|
|
41
85
|
}
|
|
42
86
|
type LoggerContext = Record<string, unknown>;
|
|
43
87
|
type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
|
|
@@ -90,6 +134,98 @@ interface SingletonLogger<TContext extends LoggerContext> {
|
|
|
90
134
|
}
|
|
91
135
|
declare function createSingletonLogger<TContext extends LoggerContext = LoggerContext>(): SingletonLogger<TContext>;
|
|
92
136
|
|
|
137
|
+
declare function matchesContext(storeContext: LoggerContext | undefined, loggerContext: string | undefined, match: Record<string, unknown> & {
|
|
138
|
+
context?: string;
|
|
139
|
+
}): boolean;
|
|
140
|
+
|
|
141
|
+
interface BufferedMessage {
|
|
142
|
+
level: LogLevel;
|
|
143
|
+
message: string;
|
|
144
|
+
timestamp: Date;
|
|
145
|
+
context?: string;
|
|
146
|
+
meta?: Record<string, unknown>;
|
|
147
|
+
}
|
|
148
|
+
interface BufferOptions {
|
|
149
|
+
batchSize: number;
|
|
150
|
+
flushInterval: number;
|
|
151
|
+
maxRetries: number;
|
|
152
|
+
retryDelay: number;
|
|
153
|
+
onFlush: (messages: BufferedMessage[]) => Promise<void>;
|
|
154
|
+
onError?: (error: Error, messages: BufferedMessage[]) => void;
|
|
155
|
+
}
|
|
156
|
+
declare class MessageBuffer {
|
|
157
|
+
private options;
|
|
158
|
+
private queue;
|
|
159
|
+
private timer;
|
|
160
|
+
private flushing;
|
|
161
|
+
private closed;
|
|
162
|
+
constructor(options: BufferOptions);
|
|
163
|
+
add(message: BufferedMessage): void;
|
|
164
|
+
flush(): Promise<void>;
|
|
165
|
+
close(): Promise<void>;
|
|
166
|
+
private scheduleFlush;
|
|
167
|
+
private clearTimer;
|
|
168
|
+
private sendWithRetry;
|
|
169
|
+
private delay;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
interface BaseHttpTransportOptions {
|
|
173
|
+
batchSize?: number;
|
|
174
|
+
flushInterval?: number;
|
|
175
|
+
maxRetries?: number;
|
|
176
|
+
retryDelay?: number;
|
|
177
|
+
}
|
|
178
|
+
declare abstract class BaseHttpTransport extends TransportStream {
|
|
179
|
+
protected buffer: MessageBuffer;
|
|
180
|
+
constructor(opts?: BaseHttpTransportOptions);
|
|
181
|
+
log(info: Record<string, unknown>, callback: () => void): void;
|
|
182
|
+
close(): Promise<void>;
|
|
183
|
+
protected transformMessage(info: Record<string, unknown>): BufferedMessage;
|
|
184
|
+
protected handleError(error: Error, messages: BufferedMessage[]): void;
|
|
185
|
+
protected abstract sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
declare class DiscordTransport extends BaseHttpTransport {
|
|
189
|
+
private config;
|
|
190
|
+
constructor(config: DiscordConfig);
|
|
191
|
+
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
192
|
+
private createEmbed;
|
|
193
|
+
private metaToFields;
|
|
194
|
+
private sendWebhook;
|
|
195
|
+
private chunkArray;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare class TelegramTransport extends BaseHttpTransport {
|
|
199
|
+
private config;
|
|
200
|
+
private apiUrl;
|
|
201
|
+
constructor(config: TelegramConfig);
|
|
202
|
+
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
203
|
+
private formatBatchMessage;
|
|
204
|
+
private formatMarkdown;
|
|
205
|
+
private formatHtml;
|
|
206
|
+
private shouldMute;
|
|
207
|
+
private sendMessage;
|
|
208
|
+
private escapeMarkdownV2;
|
|
209
|
+
private escapeHtml;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
declare class CloudWatchTransport extends BaseHttpTransport {
|
|
213
|
+
private config;
|
|
214
|
+
private client;
|
|
215
|
+
private sequenceToken;
|
|
216
|
+
private initialized;
|
|
217
|
+
private initPromise;
|
|
218
|
+
constructor(config: CloudWatchConfig);
|
|
219
|
+
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
220
|
+
private ensureInitialized;
|
|
221
|
+
private initialize;
|
|
222
|
+
private createLogGroupIfNotExists;
|
|
223
|
+
private createLogStreamIfNotExists;
|
|
224
|
+
private fetchSequenceToken;
|
|
225
|
+
private isResourceAlreadyExistsError;
|
|
226
|
+
private isInvalidSequenceTokenError;
|
|
227
|
+
}
|
|
228
|
+
|
|
93
229
|
interface TimingResult {
|
|
94
230
|
label: string;
|
|
95
231
|
durationMs: number;
|
|
@@ -124,4 +260,4 @@ declare function flattenObject(obj: Record<string, unknown>, prefix?: string): R
|
|
|
124
260
|
declare function formatLogfmtValue(value: unknown): string;
|
|
125
261
|
declare function formatLogfmt(data: Record<string, unknown>): string;
|
|
126
262
|
|
|
127
|
-
export { type ConsoleConfig, type FileConfig, LOG_LEVELS, type LevelConfig, type LevelConfigObject, type LevelOverride, type LevelOverrideMatch, type LevelRule, type LogFormat, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type Meta, type RequestIdOptions, type SingletonLogger, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
|
|
263
|
+
export { BaseHttpTransport, type BaseHttpTransportOptions, type BufferOptions, type BufferedMessage, type CloudWatchConfig, CloudWatchTransport, type ConsoleConfig, type DiscordConfig, DiscordTransport, type FileConfig, type HttpTransportBaseConfig, LOG_LEVELS, type LevelConfig, type LevelConfigObject, type LevelOverride, type LevelOverrideMatch, type LevelRule, type LogFormat, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, MessageBuffer, type Meta, type RequestIdOptions, type SingletonLogger, type TelegramConfig, TelegramTransport, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync };
|