UNPKG

@catbee/utils

Version:

A modular, production-grade utility toolkit for Node.js and TypeScript, designed for robust, scalable applications (including Express-based services). All utilities are tree-shakable and can be imported independently.

141 lines 5.47 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports._globalThis = void 0; exports.getLogger = getLogger; exports.createChildLogger = createChildLogger; exports.createRequestLogger = createRequestLogger; exports.logError = logError; const pino_1 = __importStar(require("pino")); const config_1 = require("../config"); const context_store_utils_1 = require("./context-store.utils"); /** * Symbol used to store the root logger in the Node.js global object. */ const GLOBAL_LOGGER_KEY = Symbol.for("logger"); /** * Use an object compatible with either modern or legacy global scopes. */ exports._globalThis = typeof globalThis === "object" ? globalThis : global; const _global = exports._globalThis; /** * Initializes the global root logger according to app configuration. * * - Sets log name, level, timestamp, and redaction for sensitive fields. * - Uses singleton in global symbol registry. */ function setupLogger() { const logParams = { name: config_1.Config.Logger.name, level: config_1.Config.Logger.level, redact: { paths: ["req.authorization", "url"], censor(value, path) { if (path[0] === "url") { return value.replace(/access_token=[a-zA-Z0-9_-]*/, "access_token=***"); } else if (path[1] === "authorization") { return value.replace(/\s+(\S+)$/, " ***"); } return "***"; }, }, }; if (config_1.Config.Logger.isoTimestamp) { logParams.timestamp = pino_1.stdTimeFunctions.isoTime; } _global[GLOBAL_LOGGER_KEY] = (0, pino_1.default)(logParams); _global[GLOBAL_LOGGER_KEY].debug("Logger initialized"); } /** * Retrieves the current logger instance: * - Returns a request-scoped logger from AsyncLocalStorage if available * - Falls back to the global (singleton) logger * - Initializes the global logger if not created yet * * @returns {Logger} The logger instance (request-bound or global root logger) */ function getLogger() { const logger = context_store_utils_1.ContextStore.get(context_store_utils_1.StoreKeys.LOGGER); if (logger) return logger; if (!_global[GLOBAL_LOGGER_KEY]) { setupLogger(); } return _global[GLOBAL_LOGGER_KEY]; } /** * Creates a child logger with additional context. * * @param {Record<string, any>} bindings - Properties to attach to all log records * @param {Logger} [parentLogger] - Parent logger (defaults to current context logger or global) * @returns {Logger} Child logger with merged context */ function createChildLogger(bindings, parentLogger) { const logger = parentLogger || getLogger(); return logger.child(bindings); } /** * Creates a request-scoped logger with request ID and stores it in context * * @param {string} requestId - Unique request identifier * @param {object} [additionalContext] - Additional context to include in logs * @returns {Logger} Request-scoped logger instance */ function createRequestLogger(requestId, additionalContext = {}) { const logger = createChildLogger(Object.assign({ requestId }, additionalContext)); try { context_store_utils_1.ContextStore.set(context_store_utils_1.StoreKeys.LOGGER, logger); } catch (_a) { // Context not initialized, can't store logger logger.debug("Failed to store logger in context - AsyncLocalStorage not initialized"); } return logger; } /** * Utility to safely log errors with proper stack trace extraction * * @param {Error|unknown} error - Error object to log * @param {string} [message] - Optional message to include * @param {Record<string, any>} [context] - Additional context properties */ function logError(error, message, context) { const logger = getLogger(); const errObj = error instanceof Error ? error : new Error(String(error)); const logContext = Object.assign(Object.assign({}, context), { err: errObj }); logger.error(logContext, message || errObj.message); } //# sourceMappingURL=logger.utils.js.map