UNPKG

@vepler/logger

Version:

A lightweight, type-safe logging wrapper around Pino, built by Vepler for modern TypeScript applications.

298 lines 10.4 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var pino_1 = __importDefault(require("pino")); /** * Default logger options */ var DEFAULT_OPTIONS = { formatters: { level: function (label) { return ({ level: label.toUpperCase() }); }, }, timestamp: pino_1.default.stdTimeFunctions.isoTime, redact: { paths: ['password', 'token', 'authorization', 'secret'], remove: true } }; /** * A lightweight, type-safe logging wrapper around Pino */ var PinoWrapper = /** @class */ (function () { function PinoWrapper(logger) { this.context = {}; this.logger = logger; } /** * Initialize the logger with optional configuration */ PinoWrapper.initialize = function (options) { if (!PinoWrapper.instance) { var mergedOptions = __assign(__assign({}, DEFAULT_OPTIONS), options); var logger = (0, pino_1.default)(mergedOptions); PinoWrapper.instance = new PinoWrapper(logger); } }; /** * Ensure the logger is initialized */ PinoWrapper.ensureInitialized = function () { if (!PinoWrapper.instance) { PinoWrapper.initialize(); } }; /** * Set global context that will be included in all subsequent logs */ PinoWrapper.setContext = function (context) { PinoWrapper.ensureInitialized(); PinoWrapper.instance.context = __assign(__assign({}, PinoWrapper.instance.context), context); }; /** * Clear all global context */ PinoWrapper.clearContext = function () { PinoWrapper.ensureInitialized(); PinoWrapper.instance.context = {}; }; /** * Helper to merge context with additional fields */ PinoWrapper.mergeContext = function (additionalContext) { return __assign(__assign({}, PinoWrapper.instance.context), additionalContext); }; /** * Format error objects for structured logging */ PinoWrapper.formatError = function (error) { if (!(error instanceof Error)) { if (error === null || error === undefined) { return { message: 'Unknown error' }; } if (typeof error === 'string') { return { message: error }; } if (typeof error === 'object') { return __assign({}, error); } return { message: String(error) }; } // Extract all enumerable properties from the error var errorProperties = Object.getOwnPropertyNames(error).reduce(function (acc, key) { if (key !== 'message' && key !== 'stack' && key !== 'name') { acc[key] = error[key]; } return acc; }, {}); return __assign({ type: error.name, message: error.message, stack: error.stack }, errorProperties); }; /** * Core log method that all other methods use */ PinoWrapper.log = function (level, args) { PinoWrapper.ensureInitialized(); // Handle different argument patterns if (args.length === 0) { // No arguments, just log empty message PinoWrapper.instance.logger[level](PinoWrapper.instance.context, ''); return; } var first = args[0]; // Case 1: Just a message string if (typeof first === 'string' && args.length === 1) { PinoWrapper.instance.logger[level](PinoWrapper.instance.context, first); return; } // Case 2: Error object (for error and fatal levels) if (level === 'error' || level === 'fatal') { if (first instanceof Error && args.length === 1) { var errorData = this.formatError(first); var context_1 = __assign(__assign({}, PinoWrapper.instance.context), { error: errorData }); PinoWrapper.instance.logger[level](context_1, first.message); return; } if (first instanceof Error && args.length >= 2 && typeof args[1] === 'string') { var errorData = this.formatError(first); var message_1 = args[1]; var context_2 = __assign(__assign({}, PinoWrapper.instance.context), { error: errorData }); // Add additional context if provided if (args.length > 2 && typeof args[2] === 'object' && args[2] !== null) { context_2 = __assign(__assign({}, context_2), args[2]); } PinoWrapper.instance.logger[level](context_2, message_1); return; } } // Case 3: Message with context object if (typeof first === 'string' && args.length >= 2 && typeof args[1] === 'object' && args[1] !== null) { var message_2 = first; var context_3 = args[1]; // Special handling for error contexts if ((level === 'error' || level === 'fatal') && 'error' in context_3) { var errorData = this.formatError(context_3.error); var _error = context_3.error, restContext = __rest(context_3, ["error"]); var mergedContext_1 = __assign(__assign(__assign({}, PinoWrapper.instance.context), restContext), { error: errorData }); PinoWrapper.instance.logger[level](mergedContext_1, message_2); return; } var mergedContext = __assign(__assign({}, PinoWrapper.instance.context), context_3); PinoWrapper.instance.logger[level](mergedContext, message_2); return; } // Case 4: Just an object (no message) if (typeof first === 'object' && first !== null && args.length === 1) { var context_4 = __assign(__assign({}, PinoWrapper.instance.context), first); PinoWrapper.instance.logger[level](context_4, ''); return; } // Fallback: Treat first arg as message, everything else as JSON var message = String(first); var context = PinoWrapper.instance.context; PinoWrapper.instance.logger[level](context, message); }; /** * Log at INFO level * Supports: * - info(message) * - info(message, context) * - info(context) */ PinoWrapper.info = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.log('info', args); }; /** * Log at ERROR level * Supports: * - error(message) * - error(error) * - error(message, context) * - error(context) * - error(error, message) * - error(error, message, context) * - error(message, { error }) */ PinoWrapper.error = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.log('error', args); }; /** * Log at DEBUG level * Supports: * - debug(message) * - debug(message, context) * - debug(context) */ PinoWrapper.debug = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.log('debug', args); }; /** * Log at WARN level * Supports: * - warn(message) * - warn(message, context) * - warn(context) */ PinoWrapper.warn = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.log('warn', args); }; /** * Log at FATAL level * Supports: * - fatal(message) * - fatal(error) * - fatal(message, context) * - fatal(context) * - fatal(error, message) * - fatal(error, message, context) * - fatal(message, { error }) */ PinoWrapper.fatal = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.log('fatal', args); }; /** * Log at TRACE level * Supports: * - trace(message) * - trace(message, context) * - trace(context) */ PinoWrapper.trace = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.log('trace', args); }; /** * Create a child logger with bound context */ PinoWrapper.child = function (bindings) { PinoWrapper.ensureInitialized(); var childLogger = PinoWrapper.instance.logger.child(bindings); return new PinoWrapper(childLogger); }; /** * Get the underlying Pino logger instance */ PinoWrapper.getRawLogger = function () { PinoWrapper.ensureInitialized(); return PinoWrapper.instance.logger; }; /** * Flush all buffered logs */ PinoWrapper.flush = function () { PinoWrapper.ensureInitialized(); return new Promise(function (resolve) { PinoWrapper.instance.logger.flush(function () { resolve(); }); }); }; return PinoWrapper; }()); exports.default = PinoWrapper; //# sourceMappingURL=index.js.map