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.

113 lines 4.17 kB
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); }; import pino, { stdTimeFunctions } from "pino"; import { Config } from "../config"; import { ContextStore, StoreKeys } from "./context-store.utils"; /** * Symbol used to store the root logger in the Node.js global object. */ var GLOBAL_LOGGER_KEY = Symbol.for("logger"); /** * Use an object compatible with either modern or legacy global scopes. */ export var _globalThis = typeof globalThis === "object" ? globalThis : global; var _global = _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() { var logParams = { name: Config.Logger.name, level: Config.Logger.level, redact: { paths: ["req.authorization", "url"], censor: function (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.Logger.isoTimestamp) { logParams.timestamp = stdTimeFunctions.isoTime; } _global[GLOBAL_LOGGER_KEY] = pino(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) */ export function getLogger() { var logger = ContextStore.get(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 */ export function createChildLogger(bindings, parentLogger) { var 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 */ export function createRequestLogger(requestId, additionalContext) { if (additionalContext === void 0) { additionalContext = {}; } var logger = createChildLogger(__assign({ requestId: requestId }, additionalContext)); try { ContextStore.set(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 */ export function logError(error, message, context) { var logger = getLogger(); var errObj = error instanceof Error ? error : new Error(String(error)); var logContext = __assign(__assign({}, context), { err: errObj }); logger.error(logContext, message || errObj.message); } //# sourceMappingURL=logger.utils.js.map