@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/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 createLocalFormat(store) {
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 createProductionFormat(store) {
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 createFormat(isLocal, store) {
164
- return isLocal ? createLocalFormat(store) : createProductionFormat(store);
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
- function createTransports(config) {
167
- const result = [new winston.transports.Console()];
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 = [new winston.transports.Console()];
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
- assertLogLevel(config.level);
319
+ const { defaultLevel, rules } = parseLevelConfig(config.level);
221
320
  const loggerStore = store ?? new LoggerStore();
222
- const isLocal = process.env.NODE_ENV !== "production";
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
- format: createFormat(isLocal, loggerStore),
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: config.level,
237
- levelOverrides: /* @__PURE__ */ new Map()
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.delete(key);
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.clear();
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 createLocalFormat(store) {
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 createProductionFormat(store) {
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 createFormat(isLocal, store) {
158
- return isLocal ? createLocalFormat(store) : createProductionFormat(store);
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
- function createTransports(config) {
161
- const result = [new transports.Console()];
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 = [new transports.Console()];
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
- assertLogLevel(config.level);
313
+ const { defaultLevel, rules } = parseLevelConfig(config.level);
215
314
  const loggerStore = store ?? new LoggerStore();
216
- const isLocal = process.env.NODE_ENV !== "production";
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
- format: createFormat(isLocal, loggerStore),
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: config.level,
231
- levelOverrides: /* @__PURE__ */ new Map()
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.delete(key);
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.clear();
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