@rawnodes/logger 1.5.1 → 1.7.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 +228 -148
- package/dist/index.d.mts +25 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.js +131 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var winston = require('winston');
|
|
4
4
|
var async_hooks = require('async_hooks');
|
|
5
|
-
var util = require('util');
|
|
6
5
|
var DailyRotateFile = require('winston-daily-rotate-file');
|
|
6
|
+
var util = require('util');
|
|
7
7
|
var crypto = require('crypto');
|
|
8
8
|
|
|
9
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -124,6 +124,43 @@ function formatMeta(meta, colors) {
|
|
|
124
124
|
${key}: ${value}`;
|
|
125
125
|
}).join("");
|
|
126
126
|
}
|
|
127
|
+
function flattenObject(obj, prefix = "") {
|
|
128
|
+
const result = {};
|
|
129
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
130
|
+
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
131
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Error)) {
|
|
132
|
+
Object.assign(result, flattenObject(value, newKey));
|
|
133
|
+
} else {
|
|
134
|
+
result[newKey] = value;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
function formatLogfmtValue(value) {
|
|
140
|
+
if (value === null || value === void 0) {
|
|
141
|
+
return "";
|
|
142
|
+
}
|
|
143
|
+
if (typeof value === "string") {
|
|
144
|
+
if (value.includes(" ") || value.includes('"') || value.includes("=")) {
|
|
145
|
+
return `"${value.replace(/"/g, '\\"')}"`;
|
|
146
|
+
}
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
150
|
+
return String(value);
|
|
151
|
+
}
|
|
152
|
+
if (value instanceof Error) {
|
|
153
|
+
return `"${value.message.replace(/"/g, '\\"')}"`;
|
|
154
|
+
}
|
|
155
|
+
if (Array.isArray(value)) {
|
|
156
|
+
return `"${JSON.stringify(value).replace(/"/g, '\\"')}"`;
|
|
157
|
+
}
|
|
158
|
+
return `"${JSON.stringify(value).replace(/"/g, '\\"')}"`;
|
|
159
|
+
}
|
|
160
|
+
function formatLogfmt(data) {
|
|
161
|
+
const flattened = flattenObject(data);
|
|
162
|
+
return Object.entries(flattened).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${formatLogfmtValue(value)}`).join(" ");
|
|
163
|
+
}
|
|
127
164
|
function addStoreContext(store) {
|
|
128
165
|
return winston.format((info) => {
|
|
129
166
|
const storeContext = store.getStore();
|
|
@@ -138,7 +175,7 @@ function maskSecretsFormat(options) {
|
|
|
138
175
|
return maskSecrets(info, options);
|
|
139
176
|
})();
|
|
140
177
|
}
|
|
141
|
-
function
|
|
178
|
+
function createPlainFormat(store) {
|
|
142
179
|
return winston.format.combine(
|
|
143
180
|
winston.format.errors({ stack: true }),
|
|
144
181
|
winston.format.timestamp(),
|
|
@@ -151,7 +188,7 @@ function createLocalFormat(store) {
|
|
|
151
188
|
})
|
|
152
189
|
);
|
|
153
190
|
}
|
|
154
|
-
function
|
|
191
|
+
function createJsonFormat(store) {
|
|
155
192
|
return winston.format.combine(
|
|
156
193
|
winston.format.errors({ stack: true }),
|
|
157
194
|
winston.format.timestamp(),
|
|
@@ -160,14 +197,59 @@ function createProductionFormat(store) {
|
|
|
160
197
|
winston.format.json()
|
|
161
198
|
);
|
|
162
199
|
}
|
|
163
|
-
function
|
|
164
|
-
return
|
|
200
|
+
function createLogfmtFormat(store) {
|
|
201
|
+
return winston.format.combine(
|
|
202
|
+
winston.format.errors({ stack: true }),
|
|
203
|
+
winston.format.timestamp(),
|
|
204
|
+
addStoreContext(store),
|
|
205
|
+
maskSecretsFormat(),
|
|
206
|
+
winston.format.printf(({ timestamp, level, context, message, ...meta }) => {
|
|
207
|
+
const data = {
|
|
208
|
+
level,
|
|
209
|
+
msg: message,
|
|
210
|
+
context: context || DEFAULT_CONTEXT,
|
|
211
|
+
ts: timestamp,
|
|
212
|
+
...meta
|
|
213
|
+
};
|
|
214
|
+
return formatLogfmt(data);
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
function createSimpleFormat(store) {
|
|
219
|
+
return winston.format.combine(
|
|
220
|
+
winston.format.errors({ stack: true }),
|
|
221
|
+
winston.format.timestamp(),
|
|
222
|
+
addStoreContext(store),
|
|
223
|
+
maskSecretsFormat(),
|
|
224
|
+
winston.format.printf(({ timestamp, level, message }) => {
|
|
225
|
+
return `[${timestamp}] ${level}: ${message}`;
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
function createFormat(logFormat, store) {
|
|
230
|
+
switch (logFormat) {
|
|
231
|
+
case "plain":
|
|
232
|
+
return createPlainFormat(store);
|
|
233
|
+
case "json":
|
|
234
|
+
return createJsonFormat(store);
|
|
235
|
+
case "logfmt":
|
|
236
|
+
return createLogfmtFormat(store);
|
|
237
|
+
case "simple":
|
|
238
|
+
return createSimpleFormat(store);
|
|
239
|
+
}
|
|
165
240
|
}
|
|
166
|
-
|
|
167
|
-
|
|
241
|
+
|
|
242
|
+
// src/transports.ts
|
|
243
|
+
function createTransports(config, store) {
|
|
244
|
+
const result = [
|
|
245
|
+
new winston.transports.Console({
|
|
246
|
+
format: createFormat(config.console.format, store)
|
|
247
|
+
})
|
|
248
|
+
];
|
|
168
249
|
if (config.file) {
|
|
169
250
|
result.push(
|
|
170
251
|
new DailyRotateFile__default.default({
|
|
252
|
+
format: createFormat(config.file.format, store),
|
|
171
253
|
dirname: config.file.dirname,
|
|
172
254
|
filename: config.file.filename,
|
|
173
255
|
datePattern: config.file.datePattern ?? "YYYY-MM-DD",
|
|
@@ -179,11 +261,16 @@ function createTransports(config) {
|
|
|
179
261
|
}
|
|
180
262
|
return result;
|
|
181
263
|
}
|
|
182
|
-
function createExceptionHandlers(config) {
|
|
183
|
-
const result = [
|
|
264
|
+
function createExceptionHandlers(config, store) {
|
|
265
|
+
const result = [
|
|
266
|
+
new winston.transports.Console({
|
|
267
|
+
format: createFormat(config.console.format, store)
|
|
268
|
+
})
|
|
269
|
+
];
|
|
184
270
|
if (config.file) {
|
|
185
271
|
result.push(
|
|
186
272
|
new DailyRotateFile__default.default({
|
|
273
|
+
format: createFormat(config.file.format, store),
|
|
187
274
|
dirname: config.file.dirname,
|
|
188
275
|
filename: `exceptions-${config.file.filename}`,
|
|
189
276
|
datePattern: config.file.datePattern ?? "YYYY-MM-DD",
|
|
@@ -216,25 +303,40 @@ function assertLogLevel(level) {
|
|
|
216
303
|
}
|
|
217
304
|
|
|
218
305
|
// src/state.ts
|
|
306
|
+
function parseLevelConfig(level) {
|
|
307
|
+
if (typeof level === "string") {
|
|
308
|
+
assertLogLevel(level);
|
|
309
|
+
return { defaultLevel: level, rules: [] };
|
|
310
|
+
}
|
|
311
|
+
assertLogLevel(level.default);
|
|
312
|
+
const rules = (level.rules ?? []).map((rule) => {
|
|
313
|
+
assertLogLevel(rule.level);
|
|
314
|
+
return { match: rule.match, level: rule.level, readonly: true };
|
|
315
|
+
});
|
|
316
|
+
return { defaultLevel: level.default, rules };
|
|
317
|
+
}
|
|
219
318
|
function createState(config, store) {
|
|
220
|
-
|
|
319
|
+
const { defaultLevel, rules } = parseLevelConfig(config.level);
|
|
221
320
|
const loggerStore = store ?? new LoggerStore();
|
|
222
|
-
const
|
|
223
|
-
const exceptionHandlers = createExceptionHandlers(config);
|
|
321
|
+
const exceptionHandlers = createExceptionHandlers(config, loggerStore);
|
|
224
322
|
const winston$1 = winston.createLogger({
|
|
225
323
|
level: "silly",
|
|
226
324
|
// Accept all, we filter in shouldLog()
|
|
227
|
-
|
|
228
|
-
transports: createTransports(config),
|
|
325
|
+
transports: createTransports(config, loggerStore),
|
|
229
326
|
exceptionHandlers,
|
|
230
327
|
rejectionHandlers: exceptionHandlers,
|
|
231
328
|
exitOnError: false
|
|
232
329
|
});
|
|
330
|
+
const levelOverrides = /* @__PURE__ */ new Map();
|
|
331
|
+
for (const rule of rules) {
|
|
332
|
+
const key = JSON.stringify(rule.match);
|
|
333
|
+
levelOverrides.set(key, rule);
|
|
334
|
+
}
|
|
233
335
|
return {
|
|
234
336
|
winston: winston$1,
|
|
235
337
|
store: loggerStore,
|
|
236
|
-
defaultLevel
|
|
237
|
-
levelOverrides
|
|
338
|
+
defaultLevel,
|
|
339
|
+
levelOverrides
|
|
238
340
|
};
|
|
239
341
|
}
|
|
240
342
|
function shouldLog(state, level, context) {
|
|
@@ -279,10 +381,18 @@ var Logger = class _Logger {
|
|
|
279
381
|
}
|
|
280
382
|
removeLevelOverride(match) {
|
|
281
383
|
const key = JSON.stringify(match);
|
|
282
|
-
this.state.levelOverrides.
|
|
384
|
+
const override = this.state.levelOverrides.get(key);
|
|
385
|
+
if (override?.readonly) {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
return this.state.levelOverrides.delete(key);
|
|
283
389
|
}
|
|
284
390
|
clearLevelOverrides() {
|
|
285
|
-
this.state.levelOverrides
|
|
391
|
+
for (const [key, override] of this.state.levelOverrides) {
|
|
392
|
+
if (!override.readonly) {
|
|
393
|
+
this.state.levelOverrides.delete(key);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
286
396
|
}
|
|
287
397
|
getLevelOverrides() {
|
|
288
398
|
return Array.from(this.state.levelOverrides.values());
|
|
@@ -441,6 +551,9 @@ exports.assertLogLevel = assertLogLevel;
|
|
|
441
551
|
exports.createMasker = createMasker;
|
|
442
552
|
exports.createSingletonLogger = createSingletonLogger;
|
|
443
553
|
exports.extractRequestId = extractRequestId;
|
|
554
|
+
exports.flattenObject = flattenObject;
|
|
555
|
+
exports.formatLogfmt = formatLogfmt;
|
|
556
|
+
exports.formatLogfmtValue = formatLogfmtValue;
|
|
444
557
|
exports.generateRequestId = generateRequestId;
|
|
445
558
|
exports.getOrGenerateRequestId = getOrGenerateRequestId;
|
|
446
559
|
exports.isValidLogLevel = isValidLogLevel;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/store.ts","../src/utils/mask-secrets.ts","../src/formatters.ts","../src/transports.ts","../src/types.ts","../src/state.ts","../src/logger.ts","../src/singleton.ts","../src/utils/timing.ts","../src/utils/request-id.ts"],"names":["AsyncLocalStorage","inspect","format","transports","DailyRotateFile","winston","createLogger","randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["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","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 | symbol, unknown> = {};\n\n // Copy Symbol properties first (important for Winston's internal symbols)\n for (const sym of Object.getOwnPropertySymbols(obj)) {\n result[sym] = (obj as Record<symbol, unknown>)[sym];\n }\n\n // Process string keys\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 type { LoggerConfig } from './types.js';\n\ntype Transport = transports.ConsoleTransportInstance | DailyRotateFile;\n\nexport function createTransports(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 ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\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: `exceptions-${config.file.filename}`,\n datePattern: config.file.datePattern ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\n }),\n );\n }\n\n return result;\n}\n","export const LOG_LEVELS = {\n error: 0,\n warn: 1,\n info: 2,\n http: 3,\n verbose: 4,\n debug: 5,\n silly: 6,\n} as const;\n\nexport type LogLevel = keyof typeof LOG_LEVELS;\n\nexport function isValidLogLevel(level: string): level is LogLevel {\n return level in LOG_LEVELS;\n}\n\nexport function assertLogLevel(level: string): asserts level is LogLevel {\n if (!isValidLogLevel(level)) {\n throw new Error(`Invalid log level: \"${level}\". Valid levels: ${Object.keys(LOG_LEVELS).join(', ')}`);\n }\n}\n\nexport interface FileConfig {\n dirname: string;\n filename: string;\n datePattern?: string;\n zippedArchive?: boolean;\n maxSize?: string;\n maxFiles?: string;\n}\n\nexport interface LoggerConfig {\n level: LogLevel;\n file?: FileConfig;\n}\n\nexport type LoggerContext = Record<string, unknown>;\n\nexport type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & { context?: string };\n\nexport interface LevelOverride<TContext extends LoggerContext> {\n match: LevelOverrideMatch<TContext>;\n level: LogLevel;\n}\n\nexport type Meta = object | (() => object);\n","import { createLogger, type Logger as WinstonLogger } from 'winston';\nimport { LoggerStore } from './store.js';\nimport { createFormat } from './formatters.js';\nimport { createTransports, createExceptionHandlers } from './transports.js';\nimport {\n LOG_LEVELS,\n assertLogLevel,\n type LoggerConfig,\n type LoggerContext,\n type LevelOverride,\n type LogLevel,\n} from './types.js';\n\nexport interface LoggerState<TContext extends LoggerContext> {\n winston: WinstonLogger;\n store: LoggerStore<TContext>;\n defaultLevel: LogLevel;\n levelOverrides: Map<string, LevelOverride<TContext>>;\n}\n\nexport function createState<TContext extends LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n): LoggerState<TContext> {\n assertLogLevel(config.level);\n\n const loggerStore = store ?? new LoggerStore<TContext>();\n const isLocal = process.env.NODE_ENV !== 'production';\n const exceptionHandlers = createExceptionHandlers(config);\n\n const winston = createLogger({\n level: 'silly', // Accept all, we filter in shouldLog()\n format: createFormat(isLocal, loggerStore),\n transports: createTransports(config),\n exceptionHandlers,\n rejectionHandlers: exceptionHandlers,\n exitOnError: false,\n });\n\n return {\n winston,\n store: loggerStore,\n defaultLevel: config.level,\n levelOverrides: new Map(),\n };\n}\n\nexport function shouldLog<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n level: LogLevel,\n context?: string,\n): boolean {\n const effectiveLevel = getEffectiveLevel(state, context);\n return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];\n}\n\nfunction getEffectiveLevel<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n loggerContext?: string,\n): LogLevel {\n const storeContext = state.store.getStore();\n\n for (const { match, level } of state.levelOverrides.values()) {\n if (matchesContext(storeContext, loggerContext, match)) {\n return level;\n }\n }\n return state.defaultLevel;\n}\n\nfunction matchesContext<TContext extends LoggerContext>(\n storeContext: TContext | undefined,\n loggerContext: string | undefined,\n match: Partial<TContext & { context: string }>,\n): boolean {\n const combined = { ...storeContext, context: loggerContext } as TContext & { context: string };\n return Object.entries(match).every(([key, value]) => combined[key as keyof typeof combined] === value);\n}\n","import { LoggerStore } from './store.js';\nimport { createState, shouldLog, type LoggerState } from './state.js';\nimport { assertLogLevel, type LoggerConfig, type LoggerContext, type LevelOverride, type LevelOverrideMatch, type LogLevel, type Meta } from './types.js';\n\nexport class Logger<TContext extends LoggerContext = LoggerContext> {\n private constructor(\n private state: LoggerState<TContext>,\n private context: string,\n ) {}\n\n static create<TContext extends LoggerContext = LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n ): Logger<TContext> {\n const state = createState(config, store);\n return new Logger(state, 'APP');\n }\n\n for(context: string): Logger<TContext> {\n return new Logger(this.state, context);\n }\n\n // State accessors\n\n getStore(): LoggerStore<TContext> {\n return this.state.store;\n }\n\n setLevelOverride(match: LevelOverrideMatch<TContext>, level: LogLevel): void {\n assertLogLevel(level);\n const key = JSON.stringify(match);\n this.state.levelOverrides.set(key, { match, level });\n }\n\n removeLevelOverride(match: LevelOverrideMatch<TContext>): void {\n const key = JSON.stringify(match);\n this.state.levelOverrides.delete(key);\n }\n\n clearLevelOverrides(): void {\n this.state.levelOverrides.clear();\n }\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return Array.from(this.state.levelOverrides.values());\n }\n\n // Profiling\n\n profile(id: string, meta?: object): void {\n this.state.winston.profile(id, meta);\n }\n\n // Logging methods\n\n error(message: string, error?: Error | unknown, meta?: Meta): void {\n if (!shouldLog(this.state, 'error', this.context)) return;\n this.log('error', message, meta, error);\n }\n\n warn(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'warn', this.context)) return;\n this.log('warn', message, meta);\n }\n\n info(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'info', this.context)) return;\n this.log('info', message, meta);\n }\n\n http(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'http', this.context)) return;\n this.log('http', message, meta);\n }\n\n verbose(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'verbose', this.context)) return;\n this.log('verbose', message, meta);\n }\n\n debug(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'debug', this.context)) return;\n this.log('debug', message, meta);\n }\n\n silly(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'silly', this.context)) return;\n this.log('silly', message, meta);\n }\n\n // Private\n\n private log(level: LogLevel, message: string, meta?: Meta, error?: Error | unknown): void {\n const resolved = typeof meta === 'function' ? meta() : meta;\n const logMeta: Record<string, unknown> = { context: this.context, ...resolved };\n\n if (error instanceof Error) {\n logMeta.errorMessage = error.message;\n logMeta.stack = error.stack;\n } else if (error !== undefined) {\n logMeta.error = error;\n }\n\n this.state.winston.log(level, message, logMeta);\n }\n}\n","import { Logger } from './logger.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext, LevelOverride, LogLevel } from './types.js';\n\nexport interface SingletonLogger<TContext extends LoggerContext> {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;\n get(): Logger<TContext>;\n for(context: string): Logger<TContext>;\n getStore(): LoggerStore<TContext>;\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void;\n removeLevelOverride(match: Partial<TContext>): void;\n getLevelOverrides(): LevelOverride<TContext>[];\n clearLevelOverrides(): void;\n}\n\nexport function createSingletonLogger<\n TContext extends LoggerContext = LoggerContext,\n>(): SingletonLogger<TContext> {\n let root: Logger<TContext> | null = null;\n\n const ensureInit = (): Logger<TContext> => {\n if (!root) {\n throw new Error('Logger not initialized. Call init(config) first.');\n }\n return root;\n };\n\n return {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext> {\n if (!root) {\n root = Logger.create(config, store);\n }\n return root;\n },\n\n get(): Logger<TContext> {\n return ensureInit();\n },\n\n for(context: string): Logger<TContext> {\n return ensureInit().for(context);\n },\n\n getStore(): LoggerStore<TContext> {\n return ensureInit().getStore();\n },\n\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void {\n ensureInit().setLevelOverride(match, level);\n },\n\n removeLevelOverride(match: Partial<TContext>): void {\n ensureInit().removeLevelOverride(match);\n },\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return ensureInit().getLevelOverrides();\n },\n\n clearLevelOverrides(): void {\n ensureInit().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"]}
|
|
1
|
+
{"version":3,"sources":["../src/store.ts","../src/utils/mask-secrets.ts","../src/formatters.ts","../src/transports.ts","../src/types.ts","../src/state.ts","../src/logger.ts","../src/singleton.ts","../src/utils/timing.ts","../src/utils/request-id.ts"],"names":["AsyncLocalStorage","inspect","format","transports","DailyRotateFile","winston","createLogger","randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["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","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 | symbol, unknown> = {};\n\n // Copy Symbol properties first (important for Winston's internal symbols)\n for (const sym of Object.getOwnPropertySymbols(obj)) {\n result[sym] = (obj as Record<symbol, unknown>)[sym];\n }\n\n // Process string keys\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 { LogFormat, 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\nexport function flattenObject(obj: Record<string, unknown>, prefix = ''): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const newKey = prefix ? `${prefix}.${key}` : key;\n\n if (value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Error)) {\n Object.assign(result, flattenObject(value as Record<string, unknown>, newKey));\n } else {\n result[newKey] = value;\n }\n }\n\n return result;\n}\n\nexport function formatLogfmtValue(value: unknown): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (typeof value === 'string') {\n if (value.includes(' ') || value.includes('\"') || value.includes('=')) {\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`;\n }\n return value;\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n\n if (value instanceof Error) {\n return `\"${value.message.replace(/\"/g, '\\\\\"')}\"`;\n }\n\n if (Array.isArray(value)) {\n return `\"${JSON.stringify(value).replace(/\"/g, '\\\\\"')}\"`;\n }\n\n return `\"${JSON.stringify(value).replace(/\"/g, '\\\\\"')}\"`;\n}\n\nexport function formatLogfmt(data: Record<string, unknown>): string {\n const flattened = flattenObject(data);\n\n return Object.entries(flattened)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => `${key}=${formatLogfmtValue(value)}`)\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 createPlainFormat<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 createJsonFormat<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 createLogfmtFormat<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 data: Record<string, unknown> = {\n level,\n msg: message,\n context: context || DEFAULT_CONTEXT,\n ts: timestamp,\n ...meta,\n };\n return formatLogfmt(data);\n }),\n );\n}\n\nexport function createSimpleFormat<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, message }) => {\n return `[${timestamp}] ${level}: ${message}`;\n }),\n );\n}\n\nexport function createFormat<TContext extends LoggerContext>(logFormat: LogFormat, store: LoggerStore<TContext>): Logform.Format {\n switch (logFormat) {\n case 'plain':\n return createPlainFormat(store);\n case 'json':\n return createJsonFormat(store);\n case 'logfmt':\n return createLogfmtFormat(store);\n case 'simple':\n return createSimpleFormat(store);\n }\n}\n","import { transports } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport { createFormat } from './formatters.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext } from './types.js';\n\ntype Transport = transports.ConsoleTransportInstance | DailyRotateFile;\n\nexport function createTransports<TContext extends LoggerContext>(\n config: LoggerConfig,\n store: LoggerStore<TContext>,\n): Transport[] {\n const result: Transport[] = [\n new transports.Console({\n format: createFormat(config.console.format, store),\n }),\n ];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n format: createFormat(config.file.format, store),\n dirname: config.file.dirname,\n filename: config.file.filename,\n datePattern: config.file.datePattern ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\n }),\n );\n }\n\n return result;\n}\n\nexport function createExceptionHandlers<TContext extends LoggerContext>(\n config: LoggerConfig,\n store: LoggerStore<TContext>,\n): Transport[] {\n const result: Transport[] = [\n new transports.Console({\n format: createFormat(config.console.format, store),\n }),\n ];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n format: createFormat(config.file.format, store),\n dirname: config.file.dirname,\n filename: `exceptions-${config.file.filename}`,\n datePattern: config.file.datePattern ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\n }),\n );\n }\n\n return result;\n}\n","export const LOG_LEVELS = {\n error: 0,\n warn: 1,\n info: 2,\n http: 3,\n verbose: 4,\n debug: 5,\n silly: 6,\n} as const;\n\nexport type LogLevel = keyof typeof LOG_LEVELS;\n\nexport function isValidLogLevel(level: string): level is LogLevel {\n return level in LOG_LEVELS;\n}\n\nexport function assertLogLevel(level: string): asserts level is LogLevel {\n if (!isValidLogLevel(level)) {\n throw new Error(`Invalid log level: \"${level}\". Valid levels: ${Object.keys(LOG_LEVELS).join(', ')}`);\n }\n}\n\nexport type LogFormat = 'json' | 'plain' | 'logfmt' | 'simple';\n\nexport interface ConsoleConfig {\n format: LogFormat;\n}\n\nexport interface FileConfig {\n format: LogFormat;\n dirname: string;\n filename: string;\n datePattern?: string;\n zippedArchive?: boolean;\n maxSize?: string;\n maxFiles?: string;\n}\n\nexport interface LevelRule {\n match: Record<string, unknown> & { context?: string };\n level: LogLevel;\n}\n\nexport interface LevelConfigObject {\n default: LogLevel;\n rules?: LevelRule[];\n}\n\nexport type LevelConfig = LogLevel | LevelConfigObject;\n\nexport interface LoggerConfig {\n level: LevelConfig;\n console: ConsoleConfig;\n file?: FileConfig;\n}\n\nexport type LoggerContext = Record<string, unknown>;\n\nexport type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & { context?: string };\n\nexport interface LevelOverride<TContext extends LoggerContext> {\n match: LevelOverrideMatch<TContext>;\n level: LogLevel;\n readonly?: boolean;\n}\n\nexport type Meta = object | (() => object);\n","import { createLogger, type Logger as WinstonLogger } from 'winston';\nimport { LoggerStore } from './store.js';\nimport { createTransports, createExceptionHandlers } from './transports.js';\nimport {\n LOG_LEVELS,\n assertLogLevel,\n type LoggerConfig,\n type LoggerContext,\n type LevelOverride,\n type LogLevel,\n type LevelConfig,\n} from './types.js';\n\nexport interface LoggerState<TContext extends LoggerContext> {\n winston: WinstonLogger;\n store: LoggerStore<TContext>;\n defaultLevel: LogLevel;\n levelOverrides: Map<string, LevelOverride<TContext>>;\n}\n\nfunction parseLevelConfig(level: LevelConfig): { defaultLevel: LogLevel; rules: LevelOverride<LoggerContext>[] } {\n if (typeof level === 'string') {\n assertLogLevel(level);\n return { defaultLevel: level, rules: [] };\n }\n\n assertLogLevel(level.default);\n const rules: LevelOverride<LoggerContext>[] = (level.rules ?? []).map((rule) => {\n assertLogLevel(rule.level);\n return { match: rule.match, level: rule.level, readonly: true };\n });\n\n return { defaultLevel: level.default, rules };\n}\n\nexport function createState<TContext extends LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n): LoggerState<TContext> {\n const { defaultLevel, rules } = parseLevelConfig(config.level);\n\n const loggerStore = store ?? new LoggerStore<TContext>();\n const exceptionHandlers = createExceptionHandlers(config, loggerStore);\n\n const winston = createLogger({\n level: 'silly', // Accept all, we filter in shouldLog()\n transports: createTransports(config, loggerStore),\n exceptionHandlers,\n rejectionHandlers: exceptionHandlers,\n exitOnError: false,\n });\n\n const levelOverrides = new Map<string, LevelOverride<TContext>>();\n for (const rule of rules) {\n const key = JSON.stringify(rule.match);\n levelOverrides.set(key, rule as LevelOverride<TContext>);\n }\n\n return {\n winston,\n store: loggerStore,\n defaultLevel,\n levelOverrides,\n };\n}\n\nexport function shouldLog<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n level: LogLevel,\n context?: string,\n): boolean {\n const effectiveLevel = getEffectiveLevel(state, context);\n return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];\n}\n\nfunction getEffectiveLevel<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n loggerContext?: string,\n): LogLevel {\n const storeContext = state.store.getStore();\n\n for (const { match, level } of state.levelOverrides.values()) {\n if (matchesContext(storeContext, loggerContext, match)) {\n return level;\n }\n }\n return state.defaultLevel;\n}\n\nfunction matchesContext<TContext extends LoggerContext>(\n storeContext: TContext | undefined,\n loggerContext: string | undefined,\n match: Partial<TContext & { context: string }>,\n): boolean {\n const combined = { ...storeContext, context: loggerContext } as TContext & { context: string };\n return Object.entries(match).every(([key, value]) => combined[key as keyof typeof combined] === value);\n}\n","import { LoggerStore } from './store.js';\nimport { createState, shouldLog, type LoggerState } from './state.js';\nimport { assertLogLevel, type LoggerConfig, type LoggerContext, type LevelOverride, type LevelOverrideMatch, type LogLevel, type Meta } from './types.js';\n\nexport class Logger<TContext extends LoggerContext = LoggerContext> {\n private constructor(\n private state: LoggerState<TContext>,\n private context: string,\n ) {}\n\n static create<TContext extends LoggerContext = LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n ): Logger<TContext> {\n const state = createState(config, store);\n return new Logger(state, 'APP');\n }\n\n for(context: string): Logger<TContext> {\n return new Logger(this.state, context);\n }\n\n // State accessors\n\n getStore(): LoggerStore<TContext> {\n return this.state.store;\n }\n\n setLevelOverride(match: LevelOverrideMatch<TContext>, level: LogLevel): void {\n assertLogLevel(level);\n const key = JSON.stringify(match);\n this.state.levelOverrides.set(key, { match, level });\n }\n\n removeLevelOverride(match: LevelOverrideMatch<TContext>): boolean {\n const key = JSON.stringify(match);\n const override = this.state.levelOverrides.get(key);\n if (override?.readonly) {\n return false;\n }\n return this.state.levelOverrides.delete(key);\n }\n\n clearLevelOverrides(): void {\n for (const [key, override] of this.state.levelOverrides) {\n if (!override.readonly) {\n this.state.levelOverrides.delete(key);\n }\n }\n }\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return Array.from(this.state.levelOverrides.values());\n }\n\n // Profiling\n\n profile(id: string, meta?: object): void {\n this.state.winston.profile(id, meta);\n }\n\n // Logging methods\n\n error(message: string, error?: Error | unknown, meta?: Meta): void {\n if (!shouldLog(this.state, 'error', this.context)) return;\n this.log('error', message, meta, error);\n }\n\n warn(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'warn', this.context)) return;\n this.log('warn', message, meta);\n }\n\n info(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'info', this.context)) return;\n this.log('info', message, meta);\n }\n\n http(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'http', this.context)) return;\n this.log('http', message, meta);\n }\n\n verbose(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'verbose', this.context)) return;\n this.log('verbose', message, meta);\n }\n\n debug(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'debug', this.context)) return;\n this.log('debug', message, meta);\n }\n\n silly(message: string, meta?: Meta): void {\n if (!shouldLog(this.state, 'silly', this.context)) return;\n this.log('silly', message, meta);\n }\n\n // Private\n\n private log(level: LogLevel, message: string, meta?: Meta, error?: Error | unknown): void {\n const resolved = typeof meta === 'function' ? meta() : meta;\n const logMeta: Record<string, unknown> = { context: this.context, ...resolved };\n\n if (error instanceof Error) {\n logMeta.errorMessage = error.message;\n logMeta.stack = error.stack;\n } else if (error !== undefined) {\n logMeta.error = error;\n }\n\n this.state.winston.log(level, message, logMeta);\n }\n}\n","import { Logger } from './logger.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext, LevelOverride, LogLevel } from './types.js';\n\nexport interface SingletonLogger<TContext extends LoggerContext> {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;\n get(): Logger<TContext>;\n for(context: string): Logger<TContext>;\n getStore(): LoggerStore<TContext>;\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void;\n removeLevelOverride(match: Partial<TContext>): void;\n getLevelOverrides(): LevelOverride<TContext>[];\n clearLevelOverrides(): void;\n}\n\nexport function createSingletonLogger<\n TContext extends LoggerContext = LoggerContext,\n>(): SingletonLogger<TContext> {\n let root: Logger<TContext> | null = null;\n\n const ensureInit = (): Logger<TContext> => {\n if (!root) {\n throw new Error('Logger not initialized. Call init(config) first.');\n }\n return root;\n };\n\n return {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext> {\n if (!root) {\n root = Logger.create(config, store);\n }\n return root;\n },\n\n get(): Logger<TContext> {\n return ensureInit();\n },\n\n for(context: string): Logger<TContext> {\n return ensureInit().for(context);\n },\n\n getStore(): LoggerStore<TContext> {\n return ensureInit().getStore();\n },\n\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void {\n ensureInit().setLevelOverride(match, level);\n },\n\n removeLevelOverride(match: Partial<TContext>): void {\n ensureInit().removeLevelOverride(match);\n },\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return ensureInit().getLevelOverrides();\n },\n\n clearLevelOverrides(): void {\n ensureInit().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"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger, transports, format } from 'winston';
|
|
2
2
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
|
-
import { inspect } from 'util';
|
|
4
3
|
import DailyRotateFile from 'winston-daily-rotate-file';
|
|
4
|
+
import { inspect } from 'util';
|
|
5
5
|
import { randomUUID } from 'crypto';
|
|
6
6
|
|
|
7
7
|
// src/state.ts
|
|
@@ -118,6 +118,43 @@ function formatMeta(meta, colors) {
|
|
|
118
118
|
${key}: ${value}`;
|
|
119
119
|
}).join("");
|
|
120
120
|
}
|
|
121
|
+
function flattenObject(obj, prefix = "") {
|
|
122
|
+
const result = {};
|
|
123
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
124
|
+
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
125
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Error)) {
|
|
126
|
+
Object.assign(result, flattenObject(value, newKey));
|
|
127
|
+
} else {
|
|
128
|
+
result[newKey] = value;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
function formatLogfmtValue(value) {
|
|
134
|
+
if (value === null || value === void 0) {
|
|
135
|
+
return "";
|
|
136
|
+
}
|
|
137
|
+
if (typeof value === "string") {
|
|
138
|
+
if (value.includes(" ") || value.includes('"') || value.includes("=")) {
|
|
139
|
+
return `"${value.replace(/"/g, '\\"')}"`;
|
|
140
|
+
}
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
144
|
+
return String(value);
|
|
145
|
+
}
|
|
146
|
+
if (value instanceof Error) {
|
|
147
|
+
return `"${value.message.replace(/"/g, '\\"')}"`;
|
|
148
|
+
}
|
|
149
|
+
if (Array.isArray(value)) {
|
|
150
|
+
return `"${JSON.stringify(value).replace(/"/g, '\\"')}"`;
|
|
151
|
+
}
|
|
152
|
+
return `"${JSON.stringify(value).replace(/"/g, '\\"')}"`;
|
|
153
|
+
}
|
|
154
|
+
function formatLogfmt(data) {
|
|
155
|
+
const flattened = flattenObject(data);
|
|
156
|
+
return Object.entries(flattened).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${formatLogfmtValue(value)}`).join(" ");
|
|
157
|
+
}
|
|
121
158
|
function addStoreContext(store) {
|
|
122
159
|
return format((info) => {
|
|
123
160
|
const storeContext = store.getStore();
|
|
@@ -132,7 +169,7 @@ function maskSecretsFormat(options) {
|
|
|
132
169
|
return maskSecrets(info, options);
|
|
133
170
|
})();
|
|
134
171
|
}
|
|
135
|
-
function
|
|
172
|
+
function createPlainFormat(store) {
|
|
136
173
|
return format.combine(
|
|
137
174
|
format.errors({ stack: true }),
|
|
138
175
|
format.timestamp(),
|
|
@@ -145,7 +182,7 @@ function createLocalFormat(store) {
|
|
|
145
182
|
})
|
|
146
183
|
);
|
|
147
184
|
}
|
|
148
|
-
function
|
|
185
|
+
function createJsonFormat(store) {
|
|
149
186
|
return format.combine(
|
|
150
187
|
format.errors({ stack: true }),
|
|
151
188
|
format.timestamp(),
|
|
@@ -154,14 +191,59 @@ function createProductionFormat(store) {
|
|
|
154
191
|
format.json()
|
|
155
192
|
);
|
|
156
193
|
}
|
|
157
|
-
function
|
|
158
|
-
return
|
|
194
|
+
function createLogfmtFormat(store) {
|
|
195
|
+
return format.combine(
|
|
196
|
+
format.errors({ stack: true }),
|
|
197
|
+
format.timestamp(),
|
|
198
|
+
addStoreContext(store),
|
|
199
|
+
maskSecretsFormat(),
|
|
200
|
+
format.printf(({ timestamp, level, context, message, ...meta }) => {
|
|
201
|
+
const data = {
|
|
202
|
+
level,
|
|
203
|
+
msg: message,
|
|
204
|
+
context: context || DEFAULT_CONTEXT,
|
|
205
|
+
ts: timestamp,
|
|
206
|
+
...meta
|
|
207
|
+
};
|
|
208
|
+
return formatLogfmt(data);
|
|
209
|
+
})
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
function createSimpleFormat(store) {
|
|
213
|
+
return format.combine(
|
|
214
|
+
format.errors({ stack: true }),
|
|
215
|
+
format.timestamp(),
|
|
216
|
+
addStoreContext(store),
|
|
217
|
+
maskSecretsFormat(),
|
|
218
|
+
format.printf(({ timestamp, level, message }) => {
|
|
219
|
+
return `[${timestamp}] ${level}: ${message}`;
|
|
220
|
+
})
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
function createFormat(logFormat, store) {
|
|
224
|
+
switch (logFormat) {
|
|
225
|
+
case "plain":
|
|
226
|
+
return createPlainFormat(store);
|
|
227
|
+
case "json":
|
|
228
|
+
return createJsonFormat(store);
|
|
229
|
+
case "logfmt":
|
|
230
|
+
return createLogfmtFormat(store);
|
|
231
|
+
case "simple":
|
|
232
|
+
return createSimpleFormat(store);
|
|
233
|
+
}
|
|
159
234
|
}
|
|
160
|
-
|
|
161
|
-
|
|
235
|
+
|
|
236
|
+
// src/transports.ts
|
|
237
|
+
function createTransports(config, store) {
|
|
238
|
+
const result = [
|
|
239
|
+
new transports.Console({
|
|
240
|
+
format: createFormat(config.console.format, store)
|
|
241
|
+
})
|
|
242
|
+
];
|
|
162
243
|
if (config.file) {
|
|
163
244
|
result.push(
|
|
164
245
|
new DailyRotateFile({
|
|
246
|
+
format: createFormat(config.file.format, store),
|
|
165
247
|
dirname: config.file.dirname,
|
|
166
248
|
filename: config.file.filename,
|
|
167
249
|
datePattern: config.file.datePattern ?? "YYYY-MM-DD",
|
|
@@ -173,11 +255,16 @@ function createTransports(config) {
|
|
|
173
255
|
}
|
|
174
256
|
return result;
|
|
175
257
|
}
|
|
176
|
-
function createExceptionHandlers(config) {
|
|
177
|
-
const result = [
|
|
258
|
+
function createExceptionHandlers(config, store) {
|
|
259
|
+
const result = [
|
|
260
|
+
new transports.Console({
|
|
261
|
+
format: createFormat(config.console.format, store)
|
|
262
|
+
})
|
|
263
|
+
];
|
|
178
264
|
if (config.file) {
|
|
179
265
|
result.push(
|
|
180
266
|
new DailyRotateFile({
|
|
267
|
+
format: createFormat(config.file.format, store),
|
|
181
268
|
dirname: config.file.dirname,
|
|
182
269
|
filename: `exceptions-${config.file.filename}`,
|
|
183
270
|
datePattern: config.file.datePattern ?? "YYYY-MM-DD",
|
|
@@ -210,25 +297,40 @@ function assertLogLevel(level) {
|
|
|
210
297
|
}
|
|
211
298
|
|
|
212
299
|
// src/state.ts
|
|
300
|
+
function parseLevelConfig(level) {
|
|
301
|
+
if (typeof level === "string") {
|
|
302
|
+
assertLogLevel(level);
|
|
303
|
+
return { defaultLevel: level, rules: [] };
|
|
304
|
+
}
|
|
305
|
+
assertLogLevel(level.default);
|
|
306
|
+
const rules = (level.rules ?? []).map((rule) => {
|
|
307
|
+
assertLogLevel(rule.level);
|
|
308
|
+
return { match: rule.match, level: rule.level, readonly: true };
|
|
309
|
+
});
|
|
310
|
+
return { defaultLevel: level.default, rules };
|
|
311
|
+
}
|
|
213
312
|
function createState(config, store) {
|
|
214
|
-
|
|
313
|
+
const { defaultLevel, rules } = parseLevelConfig(config.level);
|
|
215
314
|
const loggerStore = store ?? new LoggerStore();
|
|
216
|
-
const
|
|
217
|
-
const exceptionHandlers = createExceptionHandlers(config);
|
|
315
|
+
const exceptionHandlers = createExceptionHandlers(config, loggerStore);
|
|
218
316
|
const winston = createLogger({
|
|
219
317
|
level: "silly",
|
|
220
318
|
// Accept all, we filter in shouldLog()
|
|
221
|
-
|
|
222
|
-
transports: createTransports(config),
|
|
319
|
+
transports: createTransports(config, loggerStore),
|
|
223
320
|
exceptionHandlers,
|
|
224
321
|
rejectionHandlers: exceptionHandlers,
|
|
225
322
|
exitOnError: false
|
|
226
323
|
});
|
|
324
|
+
const levelOverrides = /* @__PURE__ */ new Map();
|
|
325
|
+
for (const rule of rules) {
|
|
326
|
+
const key = JSON.stringify(rule.match);
|
|
327
|
+
levelOverrides.set(key, rule);
|
|
328
|
+
}
|
|
227
329
|
return {
|
|
228
330
|
winston,
|
|
229
331
|
store: loggerStore,
|
|
230
|
-
defaultLevel
|
|
231
|
-
levelOverrides
|
|
332
|
+
defaultLevel,
|
|
333
|
+
levelOverrides
|
|
232
334
|
};
|
|
233
335
|
}
|
|
234
336
|
function shouldLog(state, level, context) {
|
|
@@ -273,10 +375,18 @@ var Logger = class _Logger {
|
|
|
273
375
|
}
|
|
274
376
|
removeLevelOverride(match) {
|
|
275
377
|
const key = JSON.stringify(match);
|
|
276
|
-
this.state.levelOverrides.
|
|
378
|
+
const override = this.state.levelOverrides.get(key);
|
|
379
|
+
if (override?.readonly) {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
return this.state.levelOverrides.delete(key);
|
|
277
383
|
}
|
|
278
384
|
clearLevelOverrides() {
|
|
279
|
-
this.state.levelOverrides
|
|
385
|
+
for (const [key, override] of this.state.levelOverrides) {
|
|
386
|
+
if (!override.readonly) {
|
|
387
|
+
this.state.levelOverrides.delete(key);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
280
390
|
}
|
|
281
391
|
getLevelOverrides() {
|
|
282
392
|
return Array.from(this.state.levelOverrides.values());
|
|
@@ -428,6 +538,6 @@ function getOrGenerateRequestId(headers, options = {}) {
|
|
|
428
538
|
return extractRequestId(headers) ?? generateRequestId(options);
|
|
429
539
|
}
|
|
430
540
|
|
|
431
|
-
export { LOG_LEVELS, Logger, LoggerStore, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
|
|
541
|
+
export { LOG_LEVELS, Logger, LoggerStore, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
|
|
432
542
|
//# sourceMappingURL=index.mjs.map
|
|
433
543
|
//# sourceMappingURL=index.mjs.map
|