@rawnodes/logger 1.0.0 → 1.2.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.
Files changed (48) hide show
  1. package/dist/index.d.mts +97 -0
  2. package/dist/index.d.ts +97 -6
  3. package/dist/index.js +415 -6
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +401 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +13 -6
  8. package/dist/formatters.d.ts +0 -7
  9. package/dist/formatters.d.ts.map +0 -1
  10. package/dist/formatters.js +0 -37
  11. package/dist/formatters.js.map +0 -1
  12. package/dist/index.d.ts.map +0 -1
  13. package/dist/logger.d.ts +0 -30
  14. package/dist/logger.d.ts.map +0 -1
  15. package/dist/logger.js +0 -131
  16. package/dist/logger.js.map +0 -1
  17. package/dist/singleton.d.ts +0 -15
  18. package/dist/singleton.d.ts.map +0 -1
  19. package/dist/singleton.js +0 -40
  20. package/dist/singleton.js.map +0 -1
  21. package/dist/store.d.ts +0 -7
  22. package/dist/store.d.ts.map +0 -1
  23. package/dist/store.js +0 -11
  24. package/dist/store.js.map +0 -1
  25. package/dist/transports.d.ts +0 -7
  26. package/dist/transports.d.ts.map +0 -1
  27. package/dist/transports.js +0 -22
  28. package/dist/transports.js.map +0 -1
  29. package/dist/types.d.ts +0 -23
  30. package/dist/types.d.ts.map +0 -1
  31. package/dist/types.js +0 -2
  32. package/dist/types.js.map +0 -1
  33. package/dist/utils/index.d.ts +0 -4
  34. package/dist/utils/index.d.ts.map +0 -1
  35. package/dist/utils/index.js +0 -4
  36. package/dist/utils/index.js.map +0 -1
  37. package/dist/utils/mask-secrets.d.ts +0 -8
  38. package/dist/utils/mask-secrets.d.ts.map +0 -1
  39. package/dist/utils/mask-secrets.js +0 -69
  40. package/dist/utils/mask-secrets.js.map +0 -1
  41. package/dist/utils/request-id.d.ts +0 -8
  42. package/dist/utils/request-id.d.ts.map +0 -1
  43. package/dist/utils/request-id.js +0 -24
  44. package/dist/utils/request-id.js.map +0 -1
  45. package/dist/utils/timing.d.ts +0 -18
  46. package/dist/utils/timing.d.ts.map +0 -1
  47. package/dist/utils/timing.js +0 -37
  48. package/dist/utils/timing.js.map +0 -1
@@ -0,0 +1,97 @@
1
+ import { Logger } from 'winston';
2
+
3
+ interface ConsoleConfig {
4
+ level: string;
5
+ }
6
+ interface FileConfig {
7
+ dirname: string;
8
+ filename: string;
9
+ level: string;
10
+ datePattern: string;
11
+ zippedArchive?: boolean;
12
+ maxSize?: string;
13
+ maxFiles?: string;
14
+ }
15
+ interface LoggerConfig {
16
+ level: string;
17
+ console: ConsoleConfig;
18
+ file?: FileConfig;
19
+ }
20
+ type LoggerContext = Record<string, unknown>;
21
+ interface LevelOverride<TContext extends LoggerContext> {
22
+ match: Partial<TContext>;
23
+ level: string;
24
+ }
25
+
26
+ declare class LoggerStore<TContext extends LoggerContext = LoggerContext> {
27
+ private storage;
28
+ getStore(): TContext | undefined;
29
+ run<T>(context: TContext, fn: () => T): T;
30
+ }
31
+
32
+ declare class BaseLogger<TContext extends LoggerContext = LoggerContext> {
33
+ private winstonLogger;
34
+ private defaultLevel;
35
+ private store;
36
+ private levelOverrides;
37
+ constructor(config: LoggerConfig, store?: LoggerStore<TContext>);
38
+ getStore(): LoggerStore<TContext>;
39
+ setLevelOverride(match: Partial<TContext>, level: string): void;
40
+ removeLevelOverride(match: Partial<TContext>): void;
41
+ clearLevelOverrides(): void;
42
+ getLevelOverrides(): LevelOverride<TContext>[];
43
+ private getEffectiveLevel;
44
+ private matchesContext;
45
+ private shouldLog;
46
+ getChildLogger(context: string): Logger;
47
+ profile(id: string, meta?: object): void;
48
+ log(message: string, context?: string, meta?: object): void;
49
+ error(message: string, error?: Error | unknown, context?: string): void;
50
+ warn(message: string, context?: string, meta?: object): void;
51
+ debug(message: string, context?: string, meta?: object): void;
52
+ info(message: string, context?: string, meta?: object): void;
53
+ verbose(message: string, context?: string, meta?: object): void;
54
+ }
55
+
56
+ interface SingletonLogger<TContext extends LoggerContext> {
57
+ getInstance(config?: LoggerConfig): BaseLogger<TContext>;
58
+ getStore(): LoggerStore<TContext>;
59
+ for(context: string): Logger;
60
+ setLevelOverride(match: Partial<TContext>, level: string): void;
61
+ removeLevelOverride(match: Partial<TContext>): void;
62
+ getLevelOverrides(): LevelOverride<TContext>[];
63
+ clearLevelOverrides(): void;
64
+ }
65
+ declare function createSingletonLogger<TContext extends LoggerContext>(): SingletonLogger<TContext>;
66
+
67
+ interface TimingResult {
68
+ label: string;
69
+ durationMs: number;
70
+ durationFormatted: string;
71
+ }
72
+ declare function measureAsync<T>(label: string, fn: () => Promise<T>): Promise<{
73
+ result: T;
74
+ timing: TimingResult;
75
+ }>;
76
+ declare function measureSync<T>(label: string, fn: () => T): {
77
+ result: T;
78
+ timing: TimingResult;
79
+ };
80
+
81
+ interface RequestIdOptions {
82
+ prefix?: string;
83
+ short?: boolean;
84
+ }
85
+ declare function generateRequestId(options?: RequestIdOptions): string;
86
+ declare function extractRequestId(headers: Record<string, string | string[] | undefined>): string | undefined;
87
+ declare function getOrGenerateRequestId(headers: Record<string, string | string[] | undefined>, options?: RequestIdOptions): string;
88
+
89
+ interface MaskSecretsOptions {
90
+ patterns?: string[];
91
+ mask?: string;
92
+ deep?: boolean;
93
+ }
94
+ declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
95
+ declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
96
+
97
+ export { BaseLogger, type ConsoleConfig, type FileConfig, type LevelOverride, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type RequestIdOptions, type SingletonLogger, type TimingResult, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, maskSecrets, measureAsync, measureSync };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,97 @@
1
- export { BaseLogger } from './logger.js';
2
- export { createSingletonLogger, type SingletonLogger } from './singleton.js';
3
- export { LoggerStore } from './store.js';
4
- export type { LoggerConfig, ConsoleConfig, FileConfig, LoggerContext, LevelOverride, } from './types.js';
5
- export { createTimer, measureAsync, measureSync, type Timer, type TimingResult, generateRequestId, extractRequestId, getOrGenerateRequestId, type RequestIdOptions, maskSecrets, createMasker, type MaskSecretsOptions, } from './utils/index.js';
6
- //# sourceMappingURL=index.d.ts.map
1
+ import { Logger } from 'winston';
2
+
3
+ interface ConsoleConfig {
4
+ level: string;
5
+ }
6
+ interface FileConfig {
7
+ dirname: string;
8
+ filename: string;
9
+ level: string;
10
+ datePattern: string;
11
+ zippedArchive?: boolean;
12
+ maxSize?: string;
13
+ maxFiles?: string;
14
+ }
15
+ interface LoggerConfig {
16
+ level: string;
17
+ console: ConsoleConfig;
18
+ file?: FileConfig;
19
+ }
20
+ type LoggerContext = Record<string, unknown>;
21
+ interface LevelOverride<TContext extends LoggerContext> {
22
+ match: Partial<TContext>;
23
+ level: string;
24
+ }
25
+
26
+ declare class LoggerStore<TContext extends LoggerContext = LoggerContext> {
27
+ private storage;
28
+ getStore(): TContext | undefined;
29
+ run<T>(context: TContext, fn: () => T): T;
30
+ }
31
+
32
+ declare class BaseLogger<TContext extends LoggerContext = LoggerContext> {
33
+ private winstonLogger;
34
+ private defaultLevel;
35
+ private store;
36
+ private levelOverrides;
37
+ constructor(config: LoggerConfig, store?: LoggerStore<TContext>);
38
+ getStore(): LoggerStore<TContext>;
39
+ setLevelOverride(match: Partial<TContext>, level: string): void;
40
+ removeLevelOverride(match: Partial<TContext>): void;
41
+ clearLevelOverrides(): void;
42
+ getLevelOverrides(): LevelOverride<TContext>[];
43
+ private getEffectiveLevel;
44
+ private matchesContext;
45
+ private shouldLog;
46
+ getChildLogger(context: string): Logger;
47
+ profile(id: string, meta?: object): void;
48
+ log(message: string, context?: string, meta?: object): void;
49
+ error(message: string, error?: Error | unknown, context?: string): void;
50
+ warn(message: string, context?: string, meta?: object): void;
51
+ debug(message: string, context?: string, meta?: object): void;
52
+ info(message: string, context?: string, meta?: object): void;
53
+ verbose(message: string, context?: string, meta?: object): void;
54
+ }
55
+
56
+ interface SingletonLogger<TContext extends LoggerContext> {
57
+ getInstance(config?: LoggerConfig): BaseLogger<TContext>;
58
+ getStore(): LoggerStore<TContext>;
59
+ for(context: string): Logger;
60
+ setLevelOverride(match: Partial<TContext>, level: string): void;
61
+ removeLevelOverride(match: Partial<TContext>): void;
62
+ getLevelOverrides(): LevelOverride<TContext>[];
63
+ clearLevelOverrides(): void;
64
+ }
65
+ declare function createSingletonLogger<TContext extends LoggerContext>(): SingletonLogger<TContext>;
66
+
67
+ interface TimingResult {
68
+ label: string;
69
+ durationMs: number;
70
+ durationFormatted: string;
71
+ }
72
+ declare function measureAsync<T>(label: string, fn: () => Promise<T>): Promise<{
73
+ result: T;
74
+ timing: TimingResult;
75
+ }>;
76
+ declare function measureSync<T>(label: string, fn: () => T): {
77
+ result: T;
78
+ timing: TimingResult;
79
+ };
80
+
81
+ interface RequestIdOptions {
82
+ prefix?: string;
83
+ short?: boolean;
84
+ }
85
+ declare function generateRequestId(options?: RequestIdOptions): string;
86
+ declare function extractRequestId(headers: Record<string, string | string[] | undefined>): string | undefined;
87
+ declare function getOrGenerateRequestId(headers: Record<string, string | string[] | undefined>, options?: RequestIdOptions): string;
88
+
89
+ interface MaskSecretsOptions {
90
+ patterns?: string[];
91
+ mask?: string;
92
+ deep?: boolean;
93
+ }
94
+ declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
95
+ declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
96
+
97
+ export { BaseLogger, type ConsoleConfig, type FileConfig, type LevelOverride, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type RequestIdOptions, type SingletonLogger, type TimingResult, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, maskSecrets, measureAsync, measureSync };
package/dist/index.js CHANGED
@@ -1,7 +1,416 @@
1
- // Core
2
- export { BaseLogger } from './logger.js';
3
- export { createSingletonLogger } from './singleton.js';
4
- export { LoggerStore } from './store.js';
5
- // Utilities
6
- export { createTimer, measureAsync, measureSync, generateRequestId, extractRequestId, getOrGenerateRequestId, maskSecrets, createMasker, } from './utils/index.js';
1
+ 'use strict';
2
+
3
+ var winston = require('winston');
4
+ var util = require('util');
5
+ var DailyRotateFile = require('winston-daily-rotate-file');
6
+ var async_hooks = require('async_hooks');
7
+ var crypto = require('crypto');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var DailyRotateFile__default = /*#__PURE__*/_interopDefault(DailyRotateFile);
12
+
13
+ // src/logger.ts
14
+
15
+ // src/utils/mask-secrets.ts
16
+ var DEFAULT_SECRET_PATTERNS = [
17
+ "password",
18
+ "secret",
19
+ "token",
20
+ "apikey",
21
+ "api_key",
22
+ "api-key",
23
+ "auth",
24
+ "credential",
25
+ "private"
26
+ ];
27
+ var DEFAULT_MASK = "***";
28
+ function isSecretKey(key, patterns) {
29
+ const lowerKey = key.toLowerCase();
30
+ return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));
31
+ }
32
+ function maskUrlCredentials(url, mask) {
33
+ try {
34
+ const parsed = new URL(url);
35
+ if (parsed.password) {
36
+ parsed.password = mask;
37
+ }
38
+ if (parsed.username && parsed.password) {
39
+ parsed.username = mask;
40
+ }
41
+ return parsed.toString();
42
+ } catch {
43
+ return url;
44
+ }
45
+ }
46
+ function maskSecrets(obj, options = {}) {
47
+ const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;
48
+ if (obj === null || obj === void 0) {
49
+ return obj;
50
+ }
51
+ if (typeof obj === "string") {
52
+ if (obj.startsWith("http://") || obj.startsWith("https://")) {
53
+ return maskUrlCredentials(obj, mask);
54
+ }
55
+ return obj;
56
+ }
57
+ if (Array.isArray(obj)) {
58
+ return deep ? obj.map((item) => maskSecrets(item, options)) : obj;
59
+ }
60
+ if (typeof obj === "object") {
61
+ const result = {};
62
+ for (const [key, value] of Object.entries(obj)) {
63
+ if (isSecretKey(key, patterns)) {
64
+ result[key] = mask;
65
+ } else if (deep && typeof value === "object" && value !== null) {
66
+ result[key] = maskSecrets(value, options);
67
+ } else if (typeof value === "string") {
68
+ result[key] = maskSecrets(value, options);
69
+ } else {
70
+ result[key] = value;
71
+ }
72
+ }
73
+ return result;
74
+ }
75
+ return obj;
76
+ }
77
+ function createMasker(options = {}) {
78
+ return (obj) => maskSecrets(obj, options);
79
+ }
80
+
81
+ // src/formatters.ts
82
+ var DEFAULT_CONTEXT = "APP";
83
+ var LEVEL_COLORS = {
84
+ error: "\x1B[31m",
85
+ // red
86
+ warn: "\x1B[33m",
87
+ // yellow
88
+ info: "\x1B[32m",
89
+ // green
90
+ http: "\x1B[35m",
91
+ // magenta
92
+ verbose: "\x1B[36m",
93
+ // cyan
94
+ debug: "\x1B[34m",
95
+ // blue
96
+ silly: "\x1B[90m"
97
+ // grey
98
+ };
99
+ var RESET = "\x1B[0m";
100
+ function colorizeLevel(level) {
101
+ const color = LEVEL_COLORS[level] || "";
102
+ return color ? `${color}${level}${RESET}` : level;
103
+ }
104
+ function formatMeta(meta, colors) {
105
+ return Object.entries(meta).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => {
106
+ if (typeof value === "object") {
107
+ const inspected = util.inspect(value, { depth: 4, colors, compact: false });
108
+ return `
109
+ ${key}: ${inspected.split("\n").join("\n ")}`;
110
+ }
111
+ return `
112
+ ${key}: ${value}`;
113
+ }).join("");
114
+ }
115
+ function addStoreContext(store) {
116
+ return winston.format((info) => {
117
+ const storeContext = store.getStore();
118
+ if (storeContext) {
119
+ return { ...info, ...storeContext };
120
+ }
121
+ return info;
122
+ })();
123
+ }
124
+ function maskSecretsFormat(options) {
125
+ return winston.format((info) => {
126
+ return maskSecrets(info, options);
127
+ })();
128
+ }
129
+ function createLocalFormat(store) {
130
+ return winston.format.combine(
131
+ winston.format.errors({ stack: true }),
132
+ winston.format.timestamp(),
133
+ addStoreContext(store),
134
+ maskSecretsFormat(),
135
+ winston.format.printf(({ timestamp, level, context, message, ...meta }) => {
136
+ const formattedMeta = formatMeta(meta, true);
137
+ const coloredLevel = colorizeLevel(level);
138
+ return `[${timestamp}] ${coloredLevel} [${context || DEFAULT_CONTEXT}] ${message}${formattedMeta}`;
139
+ })
140
+ );
141
+ }
142
+ function createProductionFormat(store) {
143
+ return winston.format.combine(
144
+ winston.format.errors({ stack: true }),
145
+ winston.format.timestamp(),
146
+ addStoreContext(store),
147
+ maskSecretsFormat(),
148
+ winston.format.json()
149
+ );
150
+ }
151
+ function createFormat(isLocal, store) {
152
+ return isLocal ? createLocalFormat(store) : createProductionFormat(store);
153
+ }
154
+ function createTransports(config) {
155
+ const result = [
156
+ new winston.transports.Console({
157
+ level: config.console.level
158
+ })
159
+ ];
160
+ if (config.file) {
161
+ result.push(
162
+ new DailyRotateFile__default.default({
163
+ dirname: config.file.dirname,
164
+ filename: config.file.filename,
165
+ level: config.file.level,
166
+ datePattern: config.file.datePattern,
167
+ zippedArchive: config.file.zippedArchive,
168
+ maxSize: config.file.maxSize,
169
+ maxFiles: config.file.maxFiles
170
+ })
171
+ );
172
+ }
173
+ return result;
174
+ }
175
+ function createExceptionHandlers(config) {
176
+ const result = [new winston.transports.Console()];
177
+ if (config.file) {
178
+ result.push(
179
+ new DailyRotateFile__default.default({
180
+ dirname: config.file.dirname,
181
+ filename: config.file.filename,
182
+ datePattern: config.file.datePattern,
183
+ zippedArchive: config.file.zippedArchive,
184
+ maxSize: config.file.maxSize,
185
+ maxFiles: config.file.maxFiles
186
+ })
187
+ );
188
+ }
189
+ return result;
190
+ }
191
+ var LoggerStore = class {
192
+ storage = new async_hooks.AsyncLocalStorage();
193
+ getStore() {
194
+ return this.storage.getStore();
195
+ }
196
+ run(context, fn) {
197
+ return this.storage.run(context, fn);
198
+ }
199
+ };
200
+
201
+ // src/logger.ts
202
+ var DEFAULT_CONTEXT2 = "APP";
203
+ var LOG_LEVELS = {
204
+ error: 0,
205
+ warn: 1,
206
+ info: 2,
207
+ http: 3,
208
+ verbose: 4,
209
+ debug: 5,
210
+ silly: 6
211
+ };
212
+ var BaseLogger = class {
213
+ winstonLogger;
214
+ defaultLevel;
215
+ store;
216
+ levelOverrides = /* @__PURE__ */ new Map();
217
+ constructor(config, store) {
218
+ const isLocal = process.env.NODE_ENV !== "production";
219
+ this.defaultLevel = config.level;
220
+ this.store = store ?? new LoggerStore();
221
+ const exceptionHandlers = createExceptionHandlers(config);
222
+ this.winstonLogger = winston.createLogger({
223
+ level: "silly",
224
+ // Allow all, we filter manually
225
+ format: createFormat(isLocal, this.store),
226
+ transports: createTransports(config),
227
+ exceptionHandlers,
228
+ rejectionHandlers: exceptionHandlers,
229
+ exitOnError: false
230
+ });
231
+ }
232
+ getStore() {
233
+ return this.store;
234
+ }
235
+ setLevelOverride(match, level) {
236
+ const key = JSON.stringify(match);
237
+ this.levelOverrides.set(key, { match, level });
238
+ }
239
+ removeLevelOverride(match) {
240
+ const key = JSON.stringify(match);
241
+ this.levelOverrides.delete(key);
242
+ }
243
+ clearLevelOverrides() {
244
+ this.levelOverrides.clear();
245
+ }
246
+ getLevelOverrides() {
247
+ return Array.from(this.levelOverrides.values());
248
+ }
249
+ getEffectiveLevel() {
250
+ const context = this.store.getStore();
251
+ if (!context) return this.defaultLevel;
252
+ for (const { match, level } of this.levelOverrides.values()) {
253
+ if (this.matchesContext(context, match)) {
254
+ return level;
255
+ }
256
+ }
257
+ return this.defaultLevel;
258
+ }
259
+ matchesContext(context, match) {
260
+ return Object.entries(match).every(([key, value]) => context[key] === value);
261
+ }
262
+ shouldLog(level) {
263
+ const effectiveLevel = this.getEffectiveLevel();
264
+ return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];
265
+ }
266
+ getChildLogger(context) {
267
+ return this.winstonLogger.child({ context });
268
+ }
269
+ profile(id, meta) {
270
+ this.winstonLogger.profile(id, meta);
271
+ }
272
+ log(message, context, meta) {
273
+ if (!this.shouldLog("info")) return;
274
+ this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT2, ...meta });
275
+ }
276
+ error(message, error, context) {
277
+ if (!this.shouldLog("error")) return;
278
+ const meta = { context: context || DEFAULT_CONTEXT2 };
279
+ if (error instanceof Error) {
280
+ meta.errorMessage = error.message;
281
+ meta.errorStack = error.stack;
282
+ } else if (error) {
283
+ meta.error = error;
284
+ }
285
+ this.winstonLogger.error(message, meta);
286
+ }
287
+ warn(message, context, meta) {
288
+ if (!this.shouldLog("warn")) return;
289
+ this.winstonLogger.warn(message, { context: context || DEFAULT_CONTEXT2, ...meta });
290
+ }
291
+ debug(message, context, meta) {
292
+ if (!this.shouldLog("debug")) return;
293
+ this.winstonLogger.debug(message, { context: context || DEFAULT_CONTEXT2, ...meta });
294
+ }
295
+ info(message, context, meta) {
296
+ if (!this.shouldLog("info")) return;
297
+ this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT2, ...meta });
298
+ }
299
+ verbose(message, context, meta) {
300
+ if (!this.shouldLog("verbose")) return;
301
+ this.winstonLogger.verbose(message, { context: context || DEFAULT_CONTEXT2, ...meta });
302
+ }
303
+ };
304
+
305
+ // src/singleton.ts
306
+ function createSingletonLogger() {
307
+ let instance = null;
308
+ const ensureInstance = () => {
309
+ if (!instance) {
310
+ throw new Error("Logger not initialized. Call getInstance(config) first.");
311
+ }
312
+ return instance;
313
+ };
314
+ return {
315
+ getInstance(config) {
316
+ if (!instance) {
317
+ if (!config) {
318
+ throw new Error("Logger config is required for first initialization");
319
+ }
320
+ instance = new BaseLogger(config);
321
+ }
322
+ return instance;
323
+ },
324
+ getStore() {
325
+ return ensureInstance().getStore();
326
+ },
327
+ for(context) {
328
+ return ensureInstance().getChildLogger(context);
329
+ },
330
+ setLevelOverride(match, level) {
331
+ ensureInstance().setLevelOverride(match, level);
332
+ },
333
+ removeLevelOverride(match) {
334
+ ensureInstance().removeLevelOverride(match);
335
+ },
336
+ getLevelOverrides() {
337
+ return ensureInstance().getLevelOverrides();
338
+ },
339
+ clearLevelOverrides() {
340
+ ensureInstance().clearLevelOverrides();
341
+ }
342
+ };
343
+ }
344
+
345
+ // src/utils/timing.ts
346
+ function formatDuration(ms) {
347
+ if (ms < 1e3) {
348
+ return `${ms.toFixed(2)}ms`;
349
+ }
350
+ if (ms < 6e4) {
351
+ return `${(ms / 1e3).toFixed(2)}s`;
352
+ }
353
+ const minutes = Math.floor(ms / 6e4);
354
+ const seconds = (ms % 6e4 / 1e3).toFixed(1);
355
+ return `${minutes}m ${seconds}s`;
356
+ }
357
+ function createTimer(label) {
358
+ const start = performance.now();
359
+ return {
360
+ end() {
361
+ const durationMs = performance.now() - start;
362
+ return {
363
+ label,
364
+ durationMs,
365
+ durationFormatted: formatDuration(durationMs)
366
+ };
367
+ }
368
+ };
369
+ }
370
+ async function measureAsync(label, fn) {
371
+ const timer = createTimer(label);
372
+ const result = await fn();
373
+ const timing = timer.end();
374
+ return { result, timing };
375
+ }
376
+ function measureSync(label, fn) {
377
+ const timer = createTimer(label);
378
+ const result = fn();
379
+ const timing = timer.end();
380
+ return { result, timing };
381
+ }
382
+ function generateRequestId(options = {}) {
383
+ const { prefix, short = false } = options;
384
+ const uuid = crypto.randomUUID();
385
+ const id = short ? uuid.split("-")[0] : uuid;
386
+ return prefix ? `${prefix}-${id}` : id;
387
+ }
388
+ function extractRequestId(headers) {
389
+ const headerNames = ["x-request-id", "x-correlation-id", "x-trace-id"];
390
+ for (const name of headerNames) {
391
+ const value = headers[name];
392
+ if (typeof value === "string" && value.length > 0) {
393
+ return value;
394
+ }
395
+ if (Array.isArray(value) && value.length > 0) {
396
+ return value[0];
397
+ }
398
+ }
399
+ return void 0;
400
+ }
401
+ function getOrGenerateRequestId(headers, options = {}) {
402
+ return extractRequestId(headers) ?? generateRequestId(options);
403
+ }
404
+
405
+ exports.BaseLogger = BaseLogger;
406
+ exports.LoggerStore = LoggerStore;
407
+ exports.createMasker = createMasker;
408
+ exports.createSingletonLogger = createSingletonLogger;
409
+ exports.extractRequestId = extractRequestId;
410
+ exports.generateRequestId = generateRequestId;
411
+ exports.getOrGenerateRequestId = getOrGenerateRequestId;
412
+ exports.maskSecrets = maskSecrets;
413
+ exports.measureAsync = measureAsync;
414
+ exports.measureSync = measureSync;
415
+ //# sourceMappingURL=index.js.map
7
416
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAwB,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAWzC,YAAY;AACZ,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EAGX,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EAEtB,WAAW,EACX,YAAY,GAEb,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"sources":["../src/utils/mask-secrets.ts","../src/formatters.ts","../src/transports.ts","../src/store.ts","../src/logger.ts","../src/singleton.ts","../src/utils/timing.ts","../src/utils/request-id.ts"],"names":["inspect","format","transports","DailyRotateFile","AsyncLocalStorage","DEFAULT_CONTEXT","createLogger","randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["const DEFAULT_SECRET_PATTERNS = [\n 'password',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'api-key',\n 'auth',\n 'credential',\n 'private',\n];\n\nconst DEFAULT_MASK = '***';\n\nexport interface MaskSecretsOptions {\n patterns?: string[];\n mask?: string;\n deep?: boolean;\n}\n\nfunction isSecretKey(key: string, patterns: string[]): boolean {\n const lowerKey = key.toLowerCase();\n return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));\n}\n\nfunction maskUrlCredentials(url: string, mask: string): string {\n try {\n const parsed = new URL(url);\n if (parsed.password) {\n parsed.password = mask;\n }\n if (parsed.username && parsed.password) {\n parsed.username = mask;\n }\n return parsed.toString();\n } catch {\n return url;\n }\n}\n\nexport function maskSecrets(\n obj: unknown,\n options: MaskSecretsOptions = {},\n): unknown {\n const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;\n\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (typeof obj === 'string') {\n if (obj.startsWith('http://') || obj.startsWith('https://')) {\n return maskUrlCredentials(obj, mask);\n }\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return deep ? obj.map((item) => maskSecrets(item, options)) : obj;\n }\n\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n if (isSecretKey(key, patterns)) {\n result[key] = mask;\n } else if (deep && typeof value === 'object' && value !== null) {\n result[key] = maskSecrets(value, options);\n } else if (typeof value === 'string') {\n result[key] = maskSecrets(value, options);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n }\n\n return obj;\n}\n\nexport function createMasker(options: MaskSecretsOptions = {}) {\n return (obj: unknown): unknown => maskSecrets(obj, options);\n}\n","import { inspect } from 'util';\nimport { format, Logform } from 'winston';\nimport { LoggerStore } from './store.js';\nimport type { LoggerContext } from './types.js';\nimport { maskSecrets, type MaskSecretsOptions } from './utils/mask-secrets.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LEVEL_COLORS: Record<string, string> = {\n error: '\\x1b[31m', // red\n warn: '\\x1b[33m', // yellow\n info: '\\x1b[32m', // green\n http: '\\x1b[35m', // magenta\n verbose: '\\x1b[36m', // cyan\n debug: '\\x1b[34m', // blue\n silly: '\\x1b[90m', // grey\n};\nconst RESET = '\\x1b[0m';\n\nfunction colorizeLevel(level: string): string {\n const color = LEVEL_COLORS[level] || '';\n return color ? `${color}${level}${RESET}` : level;\n}\n\nfunction formatMeta(meta: Record<string, unknown>, colors: boolean): string {\n return Object.entries(meta)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => {\n if (typeof value === 'object') {\n const inspected = inspect(value, { depth: 4, colors, compact: false });\n return `\\n ${key}: ${inspected.split('\\n').join('\\n ')}`;\n }\n return `\\n ${key}: ${value}`;\n })\n .join('');\n}\n\nfunction addStoreContext<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format((info) => {\n const storeContext = store.getStore();\n if (storeContext) {\n return { ...info, ...storeContext };\n }\n return info;\n })();\n}\n\nfunction maskSecretsFormat(options?: MaskSecretsOptions): Logform.Format {\n return format((info) => {\n return maskSecrets(info, options) as Logform.TransformableInfo;\n })();\n}\n\nexport function createLocalFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.printf(({ timestamp, level, context, message, ...meta }) => {\n const formattedMeta = formatMeta(meta, true);\n const coloredLevel = colorizeLevel(level);\n return `[${timestamp}] ${coloredLevel} [${context || DEFAULT_CONTEXT}] ${message}${formattedMeta}`;\n }),\n );\n}\n\nexport function createProductionFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.json(),\n );\n}\n\nexport function createFormat<TContext extends LoggerContext>(isLocal: boolean, store: LoggerStore<TContext>): Logform.Format {\n return isLocal ? createLocalFormat(store) : createProductionFormat(store);\n}\n","import { transports } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport { LoggerConfig } from './types.js';\n\ntype Transport = transports.ConsoleTransportInstance | DailyRotateFile;\n\nexport function createTransports(config: LoggerConfig): Transport[] {\n const result: Transport[] = [\n new transports.Console({\n level: config.console.level,\n }),\n ];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n level: config.file.level,\n datePattern: config.file.datePattern,\n zippedArchive: config.file.zippedArchive,\n maxSize: config.file.maxSize,\n maxFiles: config.file.maxFiles,\n }),\n );\n }\n\n return result;\n}\n\nexport function createExceptionHandlers(config: LoggerConfig): Transport[] {\n const result: Transport[] = [new transports.Console()];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n datePattern: config.file.datePattern,\n zippedArchive: config.file.zippedArchive,\n maxSize: config.file.maxSize,\n maxFiles: config.file.maxFiles,\n }),\n );\n }\n\n return result;\n}\n","import { AsyncLocalStorage } from 'async_hooks';\nimport type { LoggerContext } from './types.js';\n\nexport class LoggerStore<TContext extends LoggerContext = LoggerContext> {\n private storage = new AsyncLocalStorage<TContext>();\n\n getStore(): TContext | undefined {\n return this.storage.getStore();\n }\n\n run<T>(context: TContext, fn: () => T): T {\n return this.storage.run(context, fn);\n }\n}\n","import { createLogger, Logger } from 'winston';\nimport type { LoggerConfig, LoggerContext, LevelOverride } from './types.js';\nimport { createFormat } from './formatters.js';\nimport { createTransports, createExceptionHandlers } from './transports.js';\nimport { LoggerStore } from './store.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LOG_LEVELS: Record<string, number> = {\n error: 0,\n warn: 1,\n info: 2,\n http: 3,\n verbose: 4,\n debug: 5,\n silly: 6,\n};\n\nexport class BaseLogger<TContext extends LoggerContext = LoggerContext> {\n private winstonLogger: Logger;\n private defaultLevel: string;\n private store: LoggerStore<TContext>;\n private levelOverrides: Map<string, LevelOverride<TContext>> = new Map();\n\n constructor(config: LoggerConfig, store?: LoggerStore<TContext>) {\n const isLocal = process.env.NODE_ENV !== 'production';\n\n this.defaultLevel = config.level;\n this.store = store ?? new LoggerStore<TContext>();\n\n const exceptionHandlers = createExceptionHandlers(config);\n\n this.winstonLogger = createLogger({\n level: 'silly', // Allow all, we filter manually\n format: createFormat(isLocal, this.store),\n transports: createTransports(config),\n exceptionHandlers,\n rejectionHandlers: exceptionHandlers,\n exitOnError: false,\n });\n }\n\n getStore(): LoggerStore<TContext> {\n return this.store;\n }\n\n setLevelOverride(match: Partial<TContext>, level: string): void {\n const key = JSON.stringify(match);\n this.levelOverrides.set(key, { match, level });\n }\n\n removeLevelOverride(match: Partial<TContext>): void {\n const key = JSON.stringify(match);\n this.levelOverrides.delete(key);\n }\n\n clearLevelOverrides(): void {\n this.levelOverrides.clear();\n }\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return Array.from(this.levelOverrides.values());\n }\n\n private getEffectiveLevel(): string {\n const context = this.store.getStore();\n if (!context) return this.defaultLevel;\n\n for (const { match, level } of this.levelOverrides.values()) {\n if (this.matchesContext(context, match)) {\n return level;\n }\n }\n return this.defaultLevel;\n }\n\n private matchesContext(context: TContext, match: Partial<TContext>): boolean {\n return Object.entries(match).every(([key, value]) => context[key] === value);\n }\n\n private shouldLog(level: string): boolean {\n const effectiveLevel = this.getEffectiveLevel();\n return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];\n }\n\n getChildLogger(context: string): Logger {\n return this.winstonLogger.child({ context });\n }\n\n profile(id: string, meta?: object): void {\n this.winstonLogger.profile(id, meta);\n }\n\n log(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('info')) return;\n this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n error(message: string, error?: Error | unknown, context?: string): void {\n if (!this.shouldLog('error')) return;\n const meta: Record<string, unknown> = { context: context || DEFAULT_CONTEXT };\n if (error instanceof Error) {\n meta.errorMessage = error.message;\n meta.errorStack = error.stack;\n } else if (error) {\n meta.error = error;\n }\n this.winstonLogger.error(message, meta);\n }\n\n warn(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('warn')) return;\n this.winstonLogger.warn(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n debug(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('debug')) return;\n this.winstonLogger.debug(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n info(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('info')) return;\n this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n verbose(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('verbose')) return;\n this.winstonLogger.verbose(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n}\n","import { Logger } from 'winston';\nimport { BaseLogger } from './logger.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext, LevelOverride } from './types.js';\n\nexport interface SingletonLogger<TContext extends LoggerContext> {\n getInstance(config?: LoggerConfig): BaseLogger<TContext>;\n getStore(): LoggerStore<TContext>;\n for(context: string): Logger;\n setLevelOverride(match: Partial<TContext>, level: string): void;\n removeLevelOverride(match: Partial<TContext>): void;\n getLevelOverrides(): LevelOverride<TContext>[];\n clearLevelOverrides(): void;\n}\n\nexport function createSingletonLogger<TContext extends LoggerContext>(): SingletonLogger<TContext> {\n let instance: BaseLogger<TContext> | null = null;\n\n const ensureInstance = (): BaseLogger<TContext> => {\n if (!instance) {\n throw new Error('Logger not initialized. Call getInstance(config) first.');\n }\n return instance;\n };\n\n return {\n getInstance(config?: LoggerConfig): BaseLogger<TContext> {\n if (!instance) {\n if (!config) {\n throw new Error('Logger config is required for first initialization');\n }\n instance = new BaseLogger<TContext>(config);\n }\n return instance;\n },\n\n getStore(): LoggerStore<TContext> {\n return ensureInstance().getStore();\n },\n\n for(context: string): Logger {\n return ensureInstance().getChildLogger(context);\n },\n\n setLevelOverride(match: Partial<TContext>, level: string): void {\n ensureInstance().setLevelOverride(match, level);\n },\n\n removeLevelOverride(match: Partial<TContext>): void {\n ensureInstance().removeLevelOverride(match);\n },\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return ensureInstance().getLevelOverrides();\n },\n\n clearLevelOverrides(): void {\n ensureInstance().clearLevelOverrides();\n },\n };\n}\n","export interface TimingResult {\n label: string;\n durationMs: number;\n durationFormatted: string;\n}\n\nexport interface Timer {\n end: () => TimingResult;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms.toFixed(2)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function createTimer(label: string): Timer {\n const start = performance.now();\n\n return {\n end(): TimingResult {\n const durationMs = performance.now() - start;\n return {\n label,\n durationMs,\n durationFormatted: formatDuration(durationMs),\n };\n },\n };\n}\n\nexport async function measureAsync<T>(\n label: string,\n fn: () => Promise<T>,\n): Promise<{ result: T; timing: TimingResult }> {\n const timer = createTimer(label);\n const result = await fn();\n const timing = timer.end();\n return { result, timing };\n}\n\nexport function measureSync<T>(\n label: string,\n fn: () => T,\n): { result: T; timing: TimingResult } {\n const timer = createTimer(label);\n const result = fn();\n const timing = timer.end();\n return { result, timing };\n}\n","import { randomUUID } from 'crypto';\n\nexport interface RequestIdOptions {\n prefix?: string;\n short?: boolean;\n}\n\nexport function generateRequestId(options: RequestIdOptions = {}): string {\n const { prefix, short = false } = options;\n const uuid = randomUUID();\n const id = short ? uuid.split('-')[0] : uuid;\n return prefix ? `${prefix}-${id}` : id;\n}\n\nexport function extractRequestId(headers: Record<string, string | string[] | undefined>): string | undefined {\n const headerNames = ['x-request-id', 'x-correlation-id', 'x-trace-id'];\n\n for (const name of headerNames) {\n const value = headers[name];\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n if (Array.isArray(value) && value.length > 0) {\n return value[0];\n }\n }\n\n return undefined;\n}\n\nexport function getOrGenerateRequestId(\n headers: Record<string, string | string[] | undefined>,\n options: RequestIdOptions = {},\n): string {\n return extractRequestId(headers) ?? generateRequestId(options);\n}\n"]}