@octaviaflow/logger 1.0.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 +306 -0
- package/dist/index.js +982 -0
- package/dist/index.js.map +18 -0
- package/dist/presets/index.js +1163 -0
- package/dist/presets/index.js.map +21 -0
- package/package.json +73 -0
- package/types/logger.d.ts +494 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/constants.ts", "../src/transports/base.ts", "../src/transports/console.ts", "../src/utils/helpers.ts", "../src/transports/file.ts", "../src/transports/http.ts", "../src/formatters/index.ts", "../src/context/manager.ts", "../src/logger.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// ============================================\n// Logger Constants\n// ============================================\n\nimport type { LogLevel } from '../types/logger.js';\n\nexport const LOG_LEVELS: Record<LogLevel, number> = {\n fatal: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n trace: 5,\n} as const;\n\nexport const LOG_LEVEL_NAMES: Record<number, LogLevel> = {\n 0: 'fatal',\n 1: 'error',\n 2: 'warn',\n 3: 'info',\n 4: 'debug',\n 5: 'trace',\n} as const;\n\nexport const COLORS = {\n fatal: '\\x1b[35m', // Magenta\n error: '\\x1b[31m', // Red\n warn: '\\x1b[33m', // Yellow\n info: '\\x1b[36m', // Cyan\n debug: '\\x1b[32m', // Green\n trace: '\\x1b[37m', // White\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n} as const;\n\nexport const DEFAULT_BUFFER_SIZE = 100;\nexport const DEFAULT_FLUSH_INTERVAL = 5000; // 5 seconds\nexport const DEFAULT_MAX_FILE_SIZE = '10m';\nexport const DEFAULT_MAX_FILES = 10;\nexport const DEFAULT_DATE_PATTERN = 'YYYY-MM-DD';\n\nexport const SIZE_UNITS: Record<string, number> = {\n b: 1,\n k: 1024,\n m: 1024 * 1024,\n g: 1024 * 1024 * 1024,\n} as const;\n",
|
|
6
|
+
"// ============================================\n// Base Transport\n// ============================================\n\nimport type { BaseLogMeta, LogLevel, TransportConfig } from '../../types/logger.js';\nimport { LOG_LEVELS } from '../constants.js';\nimport type { Formatter } from '../formatters/index.js';\n\nexport abstract class BaseTransport {\n protected config: TransportConfig;\n protected formatter?: Formatter;\n\n constructor(config: TransportConfig) {\n this.config = config;\n }\n\n setFormatter(formatter: Formatter): void {\n this.formatter = formatter;\n }\n\n shouldLog(level: LogLevel): boolean {\n if (!this.config.enabled) return false;\n \n const transportLevel = this.config.level || 'trace';\n return LOG_LEVELS[level] <= LOG_LEVELS[transportLevel];\n }\n\n abstract log(message: string, meta: BaseLogMeta): void | Promise<void>;\n abstract flush(): Promise<void>;\n abstract close(): Promise<void>;\n}\n",
|
|
7
|
+
"// ============================================\n// Console Transport\n// ============================================\n\nimport type { BaseLogMeta } from '../../types/logger.js';\nimport { BaseTransport } from './base.js';\n\nexport class ConsoleTransport extends BaseTransport {\n log(message: string, meta: BaseLogMeta): void {\n if (!this.shouldLog(meta.level)) return;\n\n const formatted = this.formatter\n ? this.formatter.format(message, meta)\n : JSON.stringify({ message, ...meta });\n\n // Use appropriate console method based on level\n switch (meta.level) {\n case 'fatal':\n case 'error':\n console.error(formatted);\n break;\n case 'warn':\n console.warn(formatted);\n break;\n case 'debug':\n console.debug(formatted);\n break;\n case 'trace':\n console.trace(formatted);\n break;\n default:\n console.log(formatted);\n }\n }\n\n async flush(): Promise<void> {\n // Console writes are synchronous, nothing to flush\n }\n\n async close(): Promise<void> {\n // Nothing to close for console\n }\n}\n",
|
|
8
|
+
"// ============================================\n// Utility Helper Functions\n// ============================================\n\nimport { SIZE_UNITS } from '../constants.js';\nimport os from 'node:os';\n\n/**\n * Parse size string (e.g., \"10m\", \"1g\") to bytes\n */\nexport function parseSize(size: string): number {\n const match = size.toLowerCase().match(/^(\\d+)([bkmg]?)$/);\n if (!match) {\n throw new Error(`Invalid size format: ${size}`);\n }\n \n const value = parseInt(match[1]!, 10);\n const unit = match[2] || 'b';\n \n return value * (SIZE_UNITS[unit] ?? 1);\n}\n\n/**\n * Format bytes to human-readable string\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n \n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return `${(bytes / Math.pow(k, i)).toFixed(2)} ${units[i]}`;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1) return `${ms.toFixed(3)}ms`;\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\n if (ms < 3600000) return `${(ms / 60000).toFixed(2)}m`;\n return `${(ms / 3600000).toFixed(2)}h`;\n}\n\n/**\n * Get hostname\n */\nexport function getHostname(): string {\n return os.hostname();\n}\n\n/**\n * Get process ID\n */\nexport function getPid(): number {\n return process.pid;\n}\n\n/**\n * Generate unique ID\n */\nexport function generateId(prefix = ''): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 9);\n return prefix ? `${prefix}_${timestamp}${random}` : `${timestamp}${random}`;\n}\n\n/**\n * Sanitize sensitive data from objects\n */\nexport function sanitize(\n obj: unknown,\n fields: string[] = ['password', 'token', 'apiKey', 'secret', 'authorization'],\n replacement = '[REDACTED]'\n): unknown {\n if (obj === null || obj === undefined) return obj;\n \n if (typeof obj !== 'object') return obj;\n \n if (Array.isArray(obj)) {\n return obj.map(item => sanitize(item, fields, replacement));\n }\n \n const sanitized: Record<string, unknown> = {};\n \n for (const [key, value] of Object.entries(obj)) {\n const lowerKey = key.toLowerCase();\n const shouldRedact = fields.some(field => lowerKey.includes(field.toLowerCase()));\n \n if (shouldRedact) {\n sanitized[key] = replacement;\n } else if (typeof value === 'object' && value !== null) {\n sanitized[key] = sanitize(value, fields, replacement);\n } else {\n sanitized[key] = value;\n }\n }\n \n return sanitized;\n}\n\n/**\n * Deep merge objects\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T,\n ...sources: Partial<T>[]\n): T {\n if (!sources.length) return target;\n \n const source = sources.shift();\n if (!source) return target;\n \n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n \n if (isObject(sourceValue) && isObject(targetValue)) {\n target[key] = deepMerge(\n { ...targetValue } as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n ) as T[Extract<keyof T, string>];\n } else if (sourceValue !== undefined) {\n target[key] = sourceValue as T[Extract<keyof T, string>];\n }\n }\n \n return deepMerge(target, ...sources);\n}\n\nfunction isObject(item: unknown): item is Record<string, unknown> {\n return item !== null && typeof item === 'object' && !Array.isArray(item);\n}\n\n/**\n * Format date for file names\n */\nexport function formatDateForFile(date: Date, pattern: string): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hour = String(date.getHours()).padStart(2, '0');\n const minute = String(date.getMinutes()).padStart(2, '0');\n \n return pattern\n .replace('YYYY', String(year))\n .replace('MM', month)\n .replace('DD', day)\n .replace('HH', hour)\n .replace('mm', minute);\n}\n\n/**\n * Safe JSON stringify with circular reference handling\n */\nexport function safeStringify(obj: unknown, space?: number): string {\n const seen = new WeakSet();\n \n return JSON.stringify(\n obj,\n (key, value) => {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) {\n return '[Circular]';\n }\n seen.add(value);\n }\n \n // Handle special types\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n };\n }\n \n if (typeof value === 'bigint') {\n return value.toString();\n }\n \n if (typeof value === 'function') {\n return '[Function]';\n }\n \n return value;\n },\n space\n );\n}\n\n/**\n * Ensure directory exists\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n const fs = await import('node:fs/promises');\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n // Directory might already exist, ignore error\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n}\n\n/**\n * Check if running in production\n */\nexport function isProduction(): boolean {\n return process.env.NODE_ENV === 'production';\n}\n\n/**\n * Check if running in development\n */\nexport function isDevelopment(): boolean {\n return process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;\n}\n",
|
|
9
|
+
"// ============================================\n// File Transport with Rotation\n// ============================================\n\nimport type { BaseLogMeta } from '../../types/logger.js';\nimport { BaseTransport } from './base.js';\nimport { parseSize, formatDateForFile, ensureDir } from '../utils/helpers.js';\nimport { DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_FILES, DEFAULT_DATE_PATTERN } from '../constants.js';\nimport path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { createWriteStream, type WriteStream } from 'node:fs';\nimport { gzip } from 'node:zlib';\nimport { promisify } from 'node:util';\n\nconst gzipAsync = promisify(gzip);\n\nexport class FileTransport extends BaseTransport {\n private writeStream?: WriteStream;\n private currentSize = 0;\n private currentDate = '';\n private writeQueue: string[] = [];\n private isWriting = false;\n private isClosed = false;\n\n async log(message: string, meta: BaseLogMeta): Promise<void> {\n if (!this.shouldLog(meta.level) || this.isClosed) return;\n\n const formatted = this.formatter\n ? this.formatter.format(message, meta)\n : JSON.stringify({ message, ...meta });\n\n this.writeQueue.push(formatted + '\\n');\n await this.processQueue();\n }\n\n private async processQueue(): Promise<void> {\n if (this.isWriting || this.writeQueue.length === 0) return;\n\n this.isWriting = true;\n\n try {\n while (this.writeQueue.length > 0) {\n const entry = this.writeQueue.shift();\n if (!entry) continue;\n\n await this.ensureStream();\n await this.writeToStream(entry);\n }\n } finally {\n this.isWriting = false;\n }\n }\n\n private async ensureStream(): Promise<void> {\n const fileConfig = this.config.file;\n if (!fileConfig) {\n throw new Error('File transport requires file configuration');\n }\n\n const maxSize = parseSize(fileConfig.maxSize || DEFAULT_MAX_FILE_SIZE);\n const datePattern = fileConfig.datePattern || DEFAULT_DATE_PATTERN;\n const currentDate = formatDateForFile(new Date(), datePattern);\n\n // Check if we need to rotate based on size or date\n const needsRotation =\n this.currentSize >= maxSize ||\n (this.currentDate && this.currentDate !== currentDate);\n\n if (needsRotation || !this.writeStream) {\n await this.rotate();\n }\n\n this.currentDate = currentDate;\n }\n\n private async writeToStream(data: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.writeStream) {\n reject(new Error('Write stream not initialized'));\n return;\n }\n\n const canWrite = this.writeStream.write(data);\n this.currentSize += Buffer.byteLength(data);\n\n if (canWrite) {\n resolve();\n } else {\n this.writeStream.once('drain', () => resolve());\n }\n });\n }\n\n private async rotate(): Promise<void> {\n // Close current stream\n if (this.writeStream) {\n await this.closeStream();\n }\n\n const fileConfig = this.config.file!;\n const logDir = path.dirname(fileConfig.path);\n const logName = path.basename(fileConfig.path, path.extname(fileConfig.path));\n const logExt = path.extname(fileConfig.path);\n\n // Ensure directory exists\n await ensureDir(logDir);\n\n // Get current log file path\n const datePattern = fileConfig.datePattern || DEFAULT_DATE_PATTERN;\n const dateStr = formatDateForFile(new Date(), datePattern);\n const currentLogPath = path.join(logDir, `${logName}-${dateStr}${logExt}`);\n\n // Rotate old files if current file exists and exceeds max size\n try {\n const stats = await fs.stat(currentLogPath);\n const maxSize = parseSize(fileConfig.maxSize || DEFAULT_MAX_FILE_SIZE);\n\n if (stats.size >= maxSize) {\n await this.rotateFiles(logDir, logName, logExt);\n }\n } catch {\n // File doesn't exist, no rotation needed\n }\n\n // Create new write stream\n this.writeStream = createWriteStream(currentLogPath, { flags: 'a' });\n this.currentSize = 0;\n\n // Handle stream errors\n this.writeStream.on('error', (error) => {\n console.error('File transport write error:', error);\n });\n }\n\n private async rotateFiles(\n logDir: string,\n logName: string,\n logExt: string\n ): Promise<void> {\n const fileConfig = this.config.file!;\n const maxFiles = fileConfig.maxFiles || DEFAULT_MAX_FILES;\n\n try {\n // Get all log files\n const files = await fs.readdir(logDir);\n const logFiles = files\n .filter((f) => f.startsWith(logName) && f.endsWith(logExt))\n .sort()\n .reverse();\n\n // Delete old files if exceeding max\n if (logFiles.length >= maxFiles) {\n const filesToDelete = logFiles.slice(maxFiles - 1);\n await Promise.all(\n filesToDelete.map((f) => fs.unlink(path.join(logDir, f)).catch(() => {}))\n );\n }\n\n // Compress old files if enabled\n if (fileConfig.compress) {\n const filesToCompress = logFiles.slice(1, maxFiles - 1);\n await Promise.all(\n filesToCompress.map((f) => this.compressFile(path.join(logDir, f)))\n );\n }\n } catch (error) {\n console.error('Error rotating files:', error);\n }\n }\n\n private async compressFile(filePath: string): Promise<void> {\n // Skip if already compressed\n if (filePath.endsWith('.gz')) return;\n\n try {\n const content = await fs.readFile(filePath);\n const compressed = await gzipAsync(content);\n await fs.writeFile(`${filePath}.gz`, compressed);\n await fs.unlink(filePath);\n } catch (error) {\n console.error(`Error compressing file ${filePath}:`, error);\n }\n }\n\n private async closeStream(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.writeStream) {\n resolve();\n return;\n }\n\n this.writeStream.end(() => {\n this.writeStream = undefined;\n resolve();\n });\n });\n }\n\n async flush(): Promise<void> {\n // Wait for queue to be processed\n while (this.writeQueue.length > 0 || this.isWriting) {\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n\n // Flush the stream\n if (this.writeStream) {\n await new Promise<void>((resolve) => {\n this.writeStream!.write('', () => resolve());\n });\n }\n }\n\n async close(): Promise<void> {\n this.isClosed = true;\n await this.flush();\n await this.closeStream();\n }\n}\n",
|
|
10
|
+
"// ============================================\n// HTTP Transport with Batching\n// ============================================\n\nimport type { BaseLogMeta, TransportConfig } from '../../types/logger.js';\nimport { BaseTransport } from './base.js';\n\ninterface LogBatch {\n logs: Array<{ message: string; meta: BaseLogMeta }>;\n timestamp: number;\n}\n\nexport class HTTPTransport extends BaseTransport {\n private batch: LogBatch = { logs: [], timestamp: Date.now() };\n private flushTimer?: ReturnType<typeof setInterval>;\n private isClosed = false;\n\n constructor(config: TransportConfig) {\n super(config);\n this.startFlushTimer();\n }\n\n async log(message: string, meta: BaseLogMeta): Promise<void> {\n if (!this.shouldLog(meta.level) || this.isClosed) return;\n\n const httpConfig = this.config.http;\n if (!httpConfig) {\n throw new Error('HTTP transport requires http configuration');\n }\n\n this.batch.logs.push({ message, meta });\n\n // Flush if batch size reached\n const batchSize = httpConfig.batchSize || 10;\n if (this.batch.logs.length >= batchSize) {\n await this.flush();\n }\n }\n\n private startFlushTimer(): void {\n const httpConfig = this.config.http;\n if (!httpConfig) return;\n\n const flushInterval = httpConfig.flushInterval || 5000;\n \n this.flushTimer = setInterval(() => {\n if (this.batch.logs.length > 0) {\n this.flush().catch((error) => {\n console.error('HTTP transport flush error:', error);\n });\n }\n }, flushInterval);\n }\n\n async flush(): Promise<void> {\n if (this.batch.logs.length === 0) return;\n\n const httpConfig = this.config.http;\n if (!httpConfig) return;\n\n const logsToSend = [...this.batch.logs];\n this.batch = { logs: [], timestamp: Date.now() };\n\n const payload = logsToSend.map((log) => ({\n message: log.message,\n ...log.meta,\n }));\n\n await this.sendWithRetry(httpConfig.url, payload, httpConfig.retry);\n }\n\n private async sendWithRetry(\n url: string,\n payload: unknown[],\n retryConfig?: { attempts: number; delay: number }\n ): Promise<void> {\n const httpConfig = this.config.http!;\n const maxAttempts = retryConfig?.attempts || 3;\n const retryDelay = retryConfig?.delay || 1000;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const response = await fetch(url, {\n method: httpConfig.method || 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...httpConfig.headers,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return; // Success\n } catch (error) {\n if (attempt === maxAttempts) {\n console.error(`HTTP transport failed after ${maxAttempts} attempts:`, error);\n throw error;\n }\n\n // Wait before retry\n await new Promise((resolve) => setTimeout(resolve, retryDelay * attempt));\n }\n }\n }\n\n async close(): Promise<void> {\n this.isClosed = true;\n\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = undefined;\n }\n\n await this.flush();\n }\n}\n",
|
|
11
|
+
"// ============================================\n// Log Formatters\n// ============================================\n\nimport type { BaseLogMeta, LogFormat } from '../../types/logger.js';\nimport { COLORS } from '../constants.js';\nimport { safeStringify } from '../utils/helpers.js';\n\nexport interface FormatterOptions {\n colorize?: boolean;\n prettyPrint?: boolean;\n includeTimestamp?: boolean;\n}\n\nexport interface Formatter {\n format(message: string, meta: BaseLogMeta): string;\n}\n\n/**\n * JSON Formatter - Structured JSON output\n */\nexport class JSONFormatter implements Formatter {\n constructor(private options: FormatterOptions = {}) {}\n\n format(message: string, meta: BaseLogMeta): string {\n const logEntry = {\n ...meta,\n message,\n };\n\n return this.options.prettyPrint\n ? safeStringify(logEntry, 2)\n : safeStringify(logEntry);\n }\n}\n\n/**\n * Pretty Formatter - Human-readable colored output\n */\nexport class PrettyFormatter implements Formatter {\n constructor(private options: FormatterOptions = {}) {}\n\n format(message: string, meta: BaseLogMeta): string {\n const { colorize = true, includeTimestamp = true } = this.options;\n const { level, service, timestamp } = meta;\n\n const parts: string[] = [];\n\n // Timestamp\n if (includeTimestamp) {\n const time = new Date(timestamp).toISOString();\n parts.push(colorize ? `${COLORS.dim}${time}${COLORS.reset}` : time);\n }\n\n // Level\n const levelStr = level.toUpperCase().padEnd(5);\n if (colorize) {\n const color = COLORS[level] || COLORS.reset;\n parts.push(`${color}${COLORS.bold}${levelStr}${COLORS.reset}`);\n } else {\n parts.push(levelStr);\n }\n\n // Service\n parts.push(`[${service}]`);\n\n // Message\n parts.push(message);\n\n // Additional metadata\n const additionalMeta = this.extractAdditionalMeta(meta);\n if (Object.keys(additionalMeta).length > 0) {\n const metaStr = safeStringify(additionalMeta);\n parts.push(colorize ? `${COLORS.dim}${metaStr}${COLORS.reset}` : metaStr);\n }\n\n return parts.join(' ');\n }\n\n private extractAdditionalMeta(meta: BaseLogMeta): Record<string, unknown> {\n const {\n timestamp,\n level,\n service,\n hostname,\n pid,\n version,\n environment,\n ...additional\n } = meta;\n\n return additional;\n }\n}\n\n/**\n * Compact Formatter - Single-line compact output\n */\nexport class CompactFormatter implements Formatter {\n constructor(private options: FormatterOptions = {}) {}\n\n format(message: string, meta: BaseLogMeta): string {\n const { level, service, timestamp } = meta;\n const time = new Date(timestamp).toISOString().split('T')[1]?.split('.')[0] || '';\n \n return `${time} ${level.charAt(0).toUpperCase()} [${service}] ${message}`;\n }\n}\n\n/**\n * ECS Formatter - Elastic Common Schema format\n */\nexport class ECSFormatter implements Formatter {\n constructor(private options: FormatterOptions = {}) {}\n\n format(message: string, meta: BaseLogMeta): string {\n const ecsLog = {\n '@timestamp': meta.timestamp,\n 'log.level': meta.level,\n message,\n service: {\n name: meta.service,\n version: meta.version,\n environment: meta.environment,\n },\n host: {\n hostname: meta.hostname,\n },\n process: {\n pid: meta.pid,\n },\n labels: this.extractLabels(meta),\n ...this.extractECSFields(meta),\n };\n\n return safeStringify(ecsLog);\n }\n\n private extractLabels(meta: BaseLogMeta): Record<string, string> {\n const labels: Record<string, string> = {};\n\n if (meta.correlation?.traceId) {\n labels.trace_id = meta.correlation.traceId;\n }\n if (meta.correlation?.spanId) {\n labels.span_id = meta.correlation.spanId;\n }\n if (meta.user?.userId) {\n labels.user_id = meta.user.userId;\n }\n if (meta.workflow?.workflowId) {\n labels.workflow_id = meta.workflow.workflowId;\n }\n\n return labels;\n }\n\n private extractECSFields(meta: BaseLogMeta): Record<string, unknown> {\n const fields: Record<string, unknown> = {};\n\n // HTTP request fields\n if (meta.request) {\n fields.http = {\n request: {\n method: meta.request.method,\n id: meta.request.requestId,\n },\n url: {\n path: meta.request.path,\n query: meta.request.query,\n },\n };\n fields.client = {\n ip: meta.request.ip,\n user_agent: meta.request.userAgent,\n };\n }\n\n // User fields\n if (meta.user) {\n fields.user = {\n id: meta.user.userId,\n name: meta.user.username,\n email: meta.user.email,\n roles: meta.user.roles,\n };\n fields.organization = {\n id: meta.user.organizationId,\n };\n }\n\n return fields;\n }\n}\n\n/**\n * Create formatter based on format type\n */\nexport function createFormatter(\n format: LogFormat,\n options: FormatterOptions = {}\n): Formatter {\n switch (format) {\n case 'json':\n return new JSONFormatter(options);\n case 'pretty':\n return new PrettyFormatter(options);\n case 'compact':\n return new CompactFormatter(options);\n case 'ecs':\n return new ECSFormatter(options);\n default:\n return new JSONFormatter(options);\n }\n}\n",
|
|
12
|
+
"// ============================================\n// Context Manager using AsyncLocalStorage\n// ============================================\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { BaseLogMeta } from '../../types/logger.js';\n\nexport class ContextManager {\n private storage = new AsyncLocalStorage<Partial<BaseLogMeta>>();\n\n /**\n * Run a function with a specific context\n */\n run<T>(context: Partial<BaseLogMeta>, fn: () => T): T {\n return this.storage.run(context, fn);\n }\n\n /**\n * Get the current context\n */\n getContext(): Partial<BaseLogMeta> {\n return this.storage.getStore() || {};\n }\n\n /**\n * Set context for the current async scope\n */\n setContext(context: Partial<BaseLogMeta>): void {\n const current = this.getContext();\n const merged = { ...current, ...context };\n \n // We need to run with the new context\n this.storage.enterWith(merged);\n }\n\n /**\n * Clear the current context\n */\n clearContext(): void {\n this.storage.enterWith({});\n }\n\n /**\n * Merge context with existing context\n */\n mergeContext(context: Partial<BaseLogMeta>): Partial<BaseLogMeta> {\n const current = this.getContext();\n return { ...current, ...context };\n }\n}\n\n// Global context manager instance\nexport const contextManager = new ContextManager();\n",
|
|
13
|
+
"// ============================================\n// Core Logger Implementation\n// ============================================\n\nimport type {\n Logger as ILogger,\n LoggerConfig,\n BaseLogMeta,\n LogLevel,\n ErrorLogMeta,\n AuditLogMeta,\n SecurityLogMeta,\n PerformanceLogMeta,\n MetricsLogMeta,\n WorkflowContext,\n RequestContext,\n WorkflowLogMeta,\n} from '../types/logger.js';\nimport { LOG_LEVELS } from './constants.js';\nimport { BaseTransport, ConsoleTransport, FileTransport, HTTPTransport } from './transports/index.js';\nimport { createFormatter } from './formatters/index.js';\nimport { contextManager } from './context/manager.js';\nimport { getHostname, getPid, generateId, sanitize, formatDuration } from './utils/helpers.js';\n\nexport class Logger implements ILogger {\n private config: LoggerConfig;\n private transports: BaseTransport[] = [];\n private timers = new Map<string, number>();\n private childContext: Partial<BaseLogMeta> = {};\n\n constructor(config: LoggerConfig) {\n this.config = config;\n this.initializeTransports();\n this.setupErrorHandlers();\n }\n\n private initializeTransports(): void {\n for (const transportConfig of this.config.transports) {\n let transport: BaseTransport;\n\n switch (transportConfig.type) {\n case 'console':\n transport = new ConsoleTransport(transportConfig);\n break;\n case 'file':\n transport = new FileTransport(transportConfig);\n break;\n case 'http':\n transport = new HTTPTransport(transportConfig);\n break;\n default:\n console.warn(`Unknown transport type: ${transportConfig.type}`);\n continue;\n }\n\n // Set formatter\n const format = transportConfig.format || this.config.format;\n const formatter = createFormatter(format, {\n colorize: this.config.colorize,\n prettyPrint: this.config.prettyPrint,\n includeTimestamp: this.config.timestamps,\n });\n transport.setFormatter(formatter);\n\n this.transports.push(transport);\n }\n }\n\n private setupErrorHandlers(): void {\n if (this.config.handleExceptions) {\n process.on('uncaughtException', (error: Error) => {\n this.error('Uncaught exception', {\n type: 'error',\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n },\n handled: false,\n } as Partial<ErrorLogMeta>);\n\n if (this.config.exitOnError) {\n this.close().then(() => process.exit(1));\n }\n });\n }\n\n if (this.config.handleRejections) {\n process.on('unhandledRejection', (reason: unknown) => {\n const error = reason instanceof Error ? reason : new Error(String(reason));\n this.error('Unhandled rejection', {\n type: 'error',\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n },\n handled: false,\n } as Partial<ErrorLogMeta>);\n\n if (this.config.exitOnError) {\n this.close().then(() => process.exit(1));\n }\n });\n }\n }\n\n private shouldLog(level: LogLevel): boolean {\n return LOG_LEVELS[level] <= LOG_LEVELS[this.config.level];\n }\n\n private buildMeta(level: LogLevel, meta: Partial<BaseLogMeta> = {}): BaseLogMeta {\n // Get context from AsyncLocalStorage\n const asyncContext = contextManager.getContext();\n\n // Merge all contexts\n const mergedMeta: BaseLogMeta = {\n timestamp: new Date().toISOString(),\n level,\n service: this.config.service,\n hostname: this.config.hostname || getHostname(),\n pid: getPid(),\n version: this.config.version,\n environment: this.config.environment,\n ...this.config.defaultMeta,\n ...asyncContext,\n ...this.childContext,\n ...meta,\n };\n\n // Apply sanitization if enabled\n if (this.config.sanitize?.enabled) {\n return sanitize(\n mergedMeta,\n this.config.sanitize.fields,\n this.config.sanitize.replacement\n ) as BaseLogMeta;\n }\n\n return mergedMeta;\n }\n\n private log(level: LogLevel, message: string, meta: Partial<BaseLogMeta> = {}): void {\n if (!this.shouldLog(level)) return;\n\n const fullMeta = this.buildMeta(level, meta);\n\n // Apply sampling if configured\n if (this.config.sampling?.enabled && !this.shouldSample(fullMeta)) {\n return;\n }\n\n // Apply filters if configured\n if (this.config.filters?.enabled && this.shouldFilter(fullMeta)) {\n return;\n }\n\n // Send to all transports\n for (const transport of this.transports) {\n try {\n transport.log(message, fullMeta);\n } catch (error) {\n console.error('Transport error:', error);\n }\n }\n }\n\n private shouldSample(meta: BaseLogMeta): boolean {\n if (!this.config.sampling?.enabled) return true;\n\n for (const rule of this.config.sampling.rules) {\n // Check if rule applies\n if (rule.level && meta.level !== rule.level) continue;\n if (rule.service && meta.service !== rule.service) continue;\n if (rule.condition && !rule.condition(meta)) continue;\n\n // Apply sampling rate\n return Math.random() < rule.rate;\n }\n\n return true;\n }\n\n private shouldFilter(meta: BaseLogMeta): boolean {\n if (!this.config.filters?.enabled) return false;\n\n for (const rule of this.config.filters.rules) {\n const value = this.getNestedValue(meta, rule.field);\n if (value === undefined) continue;\n\n const matches =\n typeof rule.pattern === 'string'\n ? String(value).includes(rule.pattern)\n : rule.pattern.test(String(value));\n\n if (rule.type === 'exclude' && matches) {\n return true; // Filter out\n }\n if (rule.type === 'include' && !matches) {\n return true; // Filter out\n }\n }\n\n return false;\n }\n\n private getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n return path.split('.').reduce((current, key) => {\n return current && typeof current === 'object' ? (current as Record<string, unknown>)[key] : undefined;\n }, obj as unknown);\n }\n\n // ============================================\n // Basic Logging Methods\n // ============================================\n\n fatal(message: string, meta?: Partial<BaseLogMeta>): void {\n this.log('fatal', message, meta);\n }\n\n error(message: string, meta?: Partial<ErrorLogMeta>): void {\n this.log('error', message, meta);\n }\n\n warn(message: string, meta?: Partial<BaseLogMeta>): void {\n this.log('warn', message, meta);\n }\n\n info(message: string, meta?: Partial<BaseLogMeta>): void {\n this.log('info', message, meta);\n }\n\n debug(message: string, meta?: Partial<BaseLogMeta>): void {\n this.log('debug', message, meta);\n }\n\n trace(message: string, meta?: Partial<BaseLogMeta>): void {\n this.log('trace', message, meta);\n }\n\n // ============================================\n // Specialized Logging Methods\n // ============================================\n\n audit(action: string, meta: Omit<AuditLogMeta, 'type' | 'level'>): void {\n this.info(`Audit: ${action}`, {\n ...meta,\n type: 'audit',\n } as Partial<AuditLogMeta>);\n }\n\n security(event: SecurityLogMeta['event'], meta: Omit<SecurityLogMeta, 'type' | 'level'>): void {\n const level = meta.severity === 'critical' || meta.severity === 'high' ? 'error' : 'warn';\n this.log(level, `Security: ${event}`, {\n ...meta,\n type: 'security',\n event,\n } as Partial<SecurityLogMeta>);\n }\n\n performance(operation: string, duration: number, meta?: Partial<PerformanceLogMeta>): void {\n this.info(`Performance: ${operation}`, {\n ...meta,\n type: 'performance',\n operation,\n duration: {\n ms: duration,\n human: formatDuration(duration),\n },\n } as Partial<PerformanceLogMeta>);\n }\n\n metric(name: string, value: number, meta?: Partial<MetricsLogMeta>): void {\n this.info(`Metric: ${name}`, {\n ...meta,\n type: 'metrics',\n metrics: {\n counters: { [name]: value },\n },\n } as Partial<MetricsLogMeta>);\n }\n\n // ============================================\n // Context Management\n // ============================================\n\n child(context: Partial<BaseLogMeta>): Logger {\n const childLogger = new Logger(this.config);\n childLogger.childContext = { ...this.childContext, ...context };\n childLogger.transports = this.transports;\n return childLogger;\n }\n\n setContext(context: Partial<BaseLogMeta>): void {\n contextManager.setContext(context);\n }\n\n clearContext(): void {\n contextManager.clearContext();\n }\n\n // ============================================\n // Workflow Logging\n // ============================================\n\n startWorkflow(workflow: WorkflowContext): void {\n this.setContext({ workflow });\n this.info('Workflow started', {\n type: 'workflow',\n event: 'started',\n });\n }\n\n endWorkflow(success: boolean, meta?: Partial<WorkflowLogMeta>): void {\n const event = success ? 'completed' : 'failed';\n const logMeta: Partial<BaseLogMeta> = {\n type: 'workflow',\n event,\n ...(meta as Partial<BaseLogMeta>),\n };\n this.info(`Workflow ${event}`, logMeta);\n this.clearContext();\n }\n\n // ============================================\n // Request Logging\n // ============================================\n\n startRequest(request: RequestContext): void {\n this.setContext({ request });\n this.info('Request started', {\n type: 'api',\n direction: 'inbound',\n });\n }\n\n endRequest(statusCode: number, duration: number): void {\n this.info('Request completed', {\n type: 'api',\n direction: 'inbound',\n statusCode,\n duration,\n });\n this.clearContext();\n }\n\n // ============================================\n // Utilities\n // ============================================\n\n profile(id: string): void {\n if (this.timers.has(id)) {\n const start = this.timers.get(id)!;\n const duration = Date.now() - start;\n this.timers.delete(id);\n this.performance(id, duration);\n } else {\n this.timers.set(id, Date.now());\n }\n }\n\n startTimer(): () => number {\n const start = Date.now();\n return () => Date.now() - start;\n }\n\n async flush(): Promise<void> {\n await Promise.all(this.transports.map((t) => t.flush()));\n }\n\n async close(): Promise<void> {\n await Promise.all(this.transports.map((t) => t.close()));\n }\n}\n"
|
|
14
|
+
],
|
|
15
|
+
"mappings": "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",
|
|
16
|
+
"debugId": "9A6A570B482B62D864756E2164756E21",
|
|
17
|
+
"names": []
|
|
18
|
+
}
|