UNPKG

@rudderstack/integrations-lib

Version:

A comprehensive TypeScript library providing shared utilities, SDKs, and tools for RudderStack integrations and destinations.

122 lines 14.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.structuredLogger = void 0; const winston_1 = require("winston"); const constants_1 = require("./constants"); const { timestamp, combine, metadata, errors, json, splat } = winston_1.format; const metadataKey = 'logMetadata'; const fillExceptFields = [ 'destinationId', 'sourceId', 'destinationType', 'workspaceId', 'module', 'implementation', 'feature', ]; const getLogLevel = (level) => { if (constants_1.LOGLEVELS[level] === undefined || constants_1.LOGLEVELS[level] === null) { return 'error'; // when loglevel is invalid } return level; }; /** * Structured logger powered by winston * We are trying to create structured logging methods. * Whenever someone would like to log something using structured logging, they can use these methods to do so. * Structured logger methods: * - debugw * - infow * - warnw * - errorw * Note: While using levels option, we need to make sure that lowest level(debug) has a value higher than higher level(warn) * * @example * const logger = structuredLogger(); * logger.setLogLevel('warn') * logger.warn('my warning', {...}) * @example * const logger = structuredLogger({level: 'info'}); * * @example * logger.infow("my error message", { destinationId: "destId", workspaceId: "wspId", destinationType: "dest_type" }) // preferred * logger.infow({ message: "my error message-2", destinationId: "destId", workspaceId: "wspId", destinationType: "dest_type" }) * * @example * const logger = structuredLogger({levels: {error:0,warn:1,info:2,debug:3}}) * * @param opts * @returns */ const structuredLogger = (opts) => { let levels = opts?.levels ?? {}; if (Object.keys(levels).length === 0) { levels = constants_1.LOGLEVELS; } // Doc: https://github.com/winstonjs/winston?tab=readme-ov-file#creating-your-own-logger const logger = (0, winston_1.createLogger)({ level: getLogLevel(opts?.level || 'error'), levels, format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ssZ', }), errors({ stack: true }), splat(), metadata({ key: metadataKey, fillExcept: [ 'timestamp', 'level', 'message', 'stack', 'destinationResponse', 'authErrorCategory', ...(opts?.fillExcept || fillExceptFields), ], }), json()), transports: [new winston_1.transports.Console()], }); /** * Logically below method puts structured logger methods into logger instance with required labels such as * - destinationId * - workspaceId * - module * - implementation * - sourceId * - destinationType * * **Note**: presence of anyone of them is supported at this point */ const objectLogger = Object.entries({ debugw: 'debug', infow: 'info', warnw: 'warning', errorw: 'error', }).reduce((agg, curr) => { const [custLogMethod, winstonLogLevel] = curr; const method = (msg, ex) => { const loggableExtraData = { ...(ex?.destinationId && { destinationId: ex.destinationId }), ...(ex?.workspaceId && { workspaceId: ex.workspaceId }), ...(ex?.destinationType && { destinationType: ex.destinationType }), ...(ex?.sourceId && { sourceId: ex.sourceId }), ...(ex?.module && { module: ex.module }), ...(ex?.implementation && { implementation: ex.implementation }), ...(ex?.feature && { implementation: ex.feature }), }; if (typeof msg === 'object') { const { message, ...others } = msg; logger.log(winstonLogLevel, message, { ...others, ...loggableExtraData }); return; } logger.log(winstonLogLevel, msg, loggableExtraData); }; return { ...agg, [custLogMethod]: method }; }, { errorw: () => { }, infow: () => { }, debugw: () => { }, warnw: () => { } }); const setLogLevel = (level) => { logger.level = getLogLevel(level); }; return Object.assign(logger, objectLogger, { setLogLevel, getLogLevel, }); }; exports.structuredLogger = structuredLogger; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RydWN0dXJlZC1sb2dnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3RydWN0dXJlZC1sb2dnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUNBQTJEO0FBRTNELDJDQUF3QztBQUV4QyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxnQkFBTSxDQUFDO0FBRXJFLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQztBQUNsQyxNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCLGVBQWU7SUFDZixVQUFVO0lBQ1YsaUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixRQUFRO0lBQ1IsZ0JBQWdCO0lBQ2hCLFNBQVM7Q0FDVixDQUFDO0FBRUYsTUFBTSxXQUFXLEdBQUcsQ0FBQyxLQUFhLEVBQUUsRUFBRTtJQUNwQyxJQUFJLHFCQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssU0FBUyxJQUFJLHFCQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDaEUsT0FBTyxPQUFPLENBQUMsQ0FBQywyQkFBMkI7SUFDN0MsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyxDQUFDO0FBbUJGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyQkc7QUFDSSxNQUFNLGdCQUFnQixHQUFHLENBQUMsSUFBYyxFQUFFLEVBQUU7SUFDakQsSUFBSSxNQUFNLEdBQUcsSUFBSSxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUM7SUFDaEMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNyQyxNQUFNLEdBQUcscUJBQVMsQ0FBQztJQUNyQixDQUFDO0lBQ0Qsd0ZBQXdGO0lBQ3hGLE1BQU0sTUFBTSxHQUFHLElBQUEsc0JBQVksRUFBQztRQUMxQixLQUFLLEVBQUUsV0FB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QUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQyxFQUFFLENBQ3pFLENBQUM7SUFFRixNQUFNLFdBQVcsR0FBRyxDQUFDLEtBQWEsRUFBRSxFQUFFO1FBQ3BDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUMsQ0FBQztJQUVGLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFO1FBQ3pDLFdBQVc7UUFDWCxXQUFXO0tBQ1osQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBckZXLFFBQUEsZ0JBQWdCLG9CQXFGM0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVMb2dnZXIsIHRyYW5zcG9ydHMsIGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0IHsgTG9nZ2FibGVFeHRyYURhdGEgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IExPR0xFVkVMUyB9IGZyb20gJy4vY29uc3RhbnRzJztcblxuY29uc3QgeyB0aW1lc3RhbXAsIGNvbWJpbmUsIG1ldGFkYXRhLCBlcnJvcnMsIGpzb24sIHNwbGF0IH0gPSBmb3JtYXQ7XG5cbmNvbnN0IG1ldGFkYXRhS2V5ID0gJ2xvZ01ldGFkYXRhJztcbmNvbnN0IGZpbGxFeGNlcHRGaWVsZHMgPSBbXG4gICdkZXN0aW5hdGlvbklkJyxcbiAgJ3NvdXJjZUlkJyxcbiAgJ2Rlc3RpbmF0aW9uVHlwZScsXG4gICd3b3Jrc3BhY2VJZCcsXG4gICdtb2R1bGUnLFxuICAnaW1wbGVtZW50YXRpb24nLFxuICAnZmVhdHVyZScsXG5dO1xuXG5jb25zdCBnZXRMb2dMZXZlbCA9IChsZXZlbDogc3RyaW5nKSA9PiB7XG4gIGlmIChMT0dMRVZFTFNbbGV2ZWxdID09PSB1bmRlZmluZWQgfHwgTE9HTEVWRUxTW2xldmVsXSA9PT0gbnVsbCkge1xuICAgIHJldHVybiAnZXJyb3InOyAvLyB3aGVuIGxvZ2xldmVsIGlzIGludmFsaWRcbiAgfVxuICByZXR1cm4gbGV2ZWw7XG59O1xuXG5pbnRlcmZhY2UgTGV2ZWxlZExvZ01ldGhvZCB7XG4gIChtZXNzYWdlOiBzdHJpbmcsIGV4dHJhRGF0YT86IFBhcnRpYWw8TG9nZ2FibGVFeHRyYURhdGE+KTogdm9pZDtcbiAgKGluZm9PYmplY3Q6IHsgbWVzc2FnZTogc3RyaW5nIH0gJiBQYXJ0aWFsPExvZ2dhYmxlRXh0cmFEYXRhPik6IHZvaWQ7XG59XG5cbmludGVyZmFjZSBDdXN0TG9nZ2VyIHtcbiAgZXJyb3J3OiBMZXZlbGVkTG9nTWV0aG9kO1xuICBpbmZvdzogTGV2ZWxlZExvZ01ldGhvZDtcbiAgZGVidWd3OiBMZXZlbGVkTG9nTWV0aG9kO1xuICB3YXJudzogTGV2ZWxlZExvZ01ldGhvZDtcbn1cblxuZXhwb3J0IHR5cGUgTG9nT3B0cyA9IHtcbiAgbGV2ZWw/OiBzdHJpbmc7XG4gIGZpbGxFeGNlcHQ/OiBzdHJpbmdbXTtcbiAgbGV2ZWxzPzogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbn07XG4vKipcbiAqIFN0cnVjdHVyZWQgbG9nZ2VyIHBvd2VyZWQgYnkgd2luc3RvblxuICogV2UgYXJlIHRyeWluZyB0byBjcmVhdGUgc3RydWN0dXJlZCBsb2dnaW5nIG1ldGhvZHMuXG4gKiBXaGVuZXZlciBzb21lb25lIHdvdWxkIGxpa2UgdG8gbG9nIHNvbWV0aGluZyB1c2luZyBzdHJ1Y3R1cmVkIGxvZ2dpbmcsIHRoZXkgY2FuIHVzZSB0aGVzZSBtZXRob2RzIHRvIGRvIHNvLlxuICogU3RydWN0dXJlZCBsb2dnZXIgbWV0aG9kczpcbiAqIC0gZGVidWd3XG4gKiAtIGluZm93XG4gKiAtIHdhcm53XG4gKiAtIGVycm9yd1xuICogTm90ZTogV2hpbGUgdXNpbmcgbGV2ZWxzIG9wdGlvbiwgd2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCBsb3dlc3QgbGV2ZWwoZGVidWcpIGhhcyBhIHZhbHVlIGhpZ2hlciB0aGFuIGhpZ2hlciBsZXZlbCh3YXJuKVxuICpcbiAqIEBleGFtcGxlXG4gKiAgY29uc3QgbG9nZ2VyID0gc3RydWN0dXJlZExvZ2dlcigpO1xuICogIGxvZ2dlci5zZXRMb2dMZXZlbCgnd2FybicpXG4gKiAgbG9nZ2VyLndhcm4oJ215IHdhcm5pbmcnLCB7Li4ufSlcbiAqIEBleGFtcGxlXG4gKiAgY29uc3QgbG9nZ2VyID0gc3RydWN0dXJlZExvZ2dlcih7bGV2ZWw6ICdpbmZvJ30pO1xuICpcbiAqICBAZXhhbXBsZVxuICogIGxvZ2dlci5pbmZvdyhcIm15IGVycm9yIG1lc3NhZ2VcIiwgeyBkZXN0aW5hdGlvbklkOiBcImRlc3RJZFwiLCB3b3Jrc3BhY2VJZDogXCJ3c3BJZFwiLCBkZXN0aW5hdGlvblR5cGU6IFwiZGVzdF90eXBlXCIgfSkgLy8gcHJlZmVycmVkXG4gKiAgbG9nZ2VyLmluZm93KHsgbWVzc2FnZTogXCJteSBlcnJvciBtZXNzYWdlLTJcIiwgZGVzdGluYXRpb25JZDogXCJkZXN0SWRcIiwgd29ya3NwYWNlSWQ6IFwid3NwSWRcIiwgIGRlc3RpbmF0aW9uVHlwZTogXCJkZXN0X3R5cGVcIiB9KVxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBsb2dnZXIgPSBzdHJ1Y3R1cmVkTG9nZ2VyKHtsZXZlbHM6IHtlcnJvcjowLHdhcm46MSxpbmZvOjIsZGVidWc6M319KVxuICpcbiAqIEBwYXJhbSBvcHRzXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgY29uc3Qgc3RydWN0dXJlZExvZ2dlciA9IChvcHRzPzogTG9nT3B0cykgPT4ge1xuICBsZXQgbGV2ZWxzID0gb3B0cz8ubGV2ZWxzID8/IHt9O1xuICBpZiAoT2JqZWN0LmtleXMobGV2ZWxzKS5sZW5ndGggPT09IDApIHtcbiAgICBsZXZlbHMgPSBMT0dMRVZFTFM7XG4gIH1cbiAgLy8gRG9jOiBodHRwczovL2dpdGh1Yi5jb20vd2luc3RvbmpzL3dpbnN0b24/dGFiPXJlYWRtZS1vdi1maWxlI2NyZWF0aW5nLXlvdXItb3duLWxvZ2dlclxuICBjb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoe1xuICAgIGxldmVsOiBnZXRMb2dMZXZlbChvcHRzPy5sZXZlbCB8fCAnZXJyb3InKSxcbiAgICBsZXZlbHMsXG4gICAgZm9ybWF0OiBjb21iaW5lKFxuICAgICAgdGltZXN0YW1wKHtcbiAgICAgICAgZm9ybWF0OiAnWVlZWS1NTS1ERCBISDptbTpzc1onLFxuICAgICAgfSksXG4gICAgICBlcnJvcnMoeyBzdGFjazogdHJ1ZSB9KSxcbiAgICAgIHNwbGF0KCksXG4gICAgICBtZXRhZGF0YSh7XG4gICAgICAgIGtleTogbWV0YWRhdGFLZXksXG4gICAgICAgIGZpbGxFeGNlcHQ6IFtcbiAgICAgICAgICAndGltZXN0YW1wJyxcbiAgICAgICAgICAnbGV2ZWwnLFxuICAgICAgICAgICdtZXNzYWdlJyxcbiAgICAgICAgICAnc3RhY2snLFxuICAgICAgICAgICdkZXN0aW5hdGlvblJlc3BvbnNlJyxcbiAgICAgICAgICAnYXV0aEVycm9yQ2F0ZWdvcnknLFxuICAgICAgICAgIC4uLihvcHRzPy5maWxsRXhjZXB0IHx8IGZpbGxFeGNlcHRGaWVsZHMpLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgICBqc29uKCksXG4gICAgKSxcbiAgICB0cmFuc3BvcnRzOiBbbmV3IHRyYW5zcG9ydHMuQ29uc29sZSgpXSxcbiAgfSk7XG5cbiAgLyoqXG4gICAqIExvZ2ljYWxseSBiZWxvdyBtZXRob2QgcHV0cyBzdHJ1Y3R1cmVkIGxvZ2dlciBtZXRob2RzIGludG8gbG9nZ2VyIGluc3RhbmNlIHdpdGggcmVxdWlyZWQgbGFiZWxzIHN1Y2ggYXNcbiAgICogLSBkZXN0aW5hdGlvbklkXG4gICAqIC0gd29ya3NwYWNlSWRcbiAgICogLSBtb2R1bGVcbiAgICogLSBpbXBsZW1lbnRhdGlvblxuICAgKiAtIHNvdXJjZUlkXG4gICAqIC0gZGVzdGluYXRpb25UeXBlXG4gICAqXG4gICAqICoqTm90ZSoqOiBwcmVzZW5jZSBvZiBhbnlvbmUgb2YgdGhlbSBpcyBzdXBwb3J0ZWQgYXQgdGhpcyBwb2ludFxuICAgKi9cbiAgY29uc3Qgb2JqZWN0TG9nZ2VyOiBDdXN0TG9nZ2VyID0gT2JqZWN0LmVudHJpZXMoe1xuICAgIGRlYnVndzogJ2RlYnVnJyxcbiAgICBpbmZvdzogJ2luZm8nLFxuICAgIHdhcm53OiAnd2FybmluZycsXG4gICAgZXJyb3J3OiAnZXJyb3InLFxuICB9KS5yZWR1Y2UoXG4gICAgKGFnZywgY3VycikgPT4ge1xuICAgICAgY29uc3QgW2N1c3RMb2dNZXRob2QsIHdpbnN0b25Mb2dMZXZlbF0gPSBjdXJyO1xuXG4gICAgICBjb25zdCBtZXRob2QgPSAoXG4gICAgICAgIG1zZzogc3RyaW5nIHwgKHsgbWVzc2FnZTogc3RyaW5nIH0gJiBQYXJ0aWFsPExvZ2dhYmxlRXh0cmFEYXRhPiksXG4gICAgICAgIGV4PzogUGFydGlhbDxMb2dnYWJsZUV4dHJhRGF0YT4sXG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgbG9nZ2FibGVFeHRyYURhdGE6IFBhcnRpYWw8TG9nZ2FibGVFeHRyYURhdGE+ID0ge1xuICAgICAgICAgIC4uLihleD8uZGVzdGluYXRpb25JZCAmJiB7IGRlc3RpbmF0aW9uSWQ6IGV4LmRlc3RpbmF0aW9uSWQgfSksXG4gICAgICAgICAgLi4uKGV4Py53b3Jrc3BhY2VJZCAmJiB7IHdvcmtzcGFjZUlkOiBleC53b3Jrc3BhY2VJZCB9KSxcbiAgICAgICAgICAuLi4oZXg/LmRlc3RpbmF0aW9uVHlwZSAmJiB7IGRlc3RpbmF0aW9uVHlwZTogZXguZGVzdGluYXRpb25UeXBlIH0pLFxuICAgICAgICAgIC4uLihleD8uc291cmNlSWQgJiYgeyBzb3VyY2VJZDogZXguc291cmNlSWQgfSksXG4gICAgICAgICAgLi4uKGV4Py5tb2R1bGUgJiYgeyBtb2R1bGU6IGV4Lm1vZHVsZSB9KSxcbiAgICAgICAgICAuLi4oZXg/LmltcGxlbWVudGF0aW9uICYmIHsgaW1wbGVtZW50YXRpb246IGV4LmltcGxlbWVudGF0aW9uIH0pLFxuICAgICAgICAgIC4uLihleD8uZmVhdHVyZSAmJiB7IGltcGxlbWVudGF0aW9uOiBleC5mZWF0dXJlIH0pLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodHlwZW9mIG1zZyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBjb25zdCB7IG1lc3NhZ2UsIC4uLm90aGVycyB9ID0gbXNnO1xuICAgICAgICAgIGxvZ2dlci5sb2cod2luc3RvbkxvZ0xldmVsLCBtZXNzYWdlLCB7IC4uLm90aGVycywgLi4ubG9nZ2FibGVFeHRyYURhdGEgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci5sb2cod2luc3RvbkxvZ0xldmVsLCBtc2csIGxvZ2dhYmxlRXh0cmFEYXRhKTtcbiAgICAgIH07XG4gICAgICByZXR1cm4geyAuLi5hZ2csIFtjdXN0TG9nTWV0aG9kXTogbWV0aG9kIH07XG4gICAgfSxcbiAgICB7IGVycm9ydzogKCkgPT4ge30sIGluZm93OiAoKSA9PiB7fSwgZGVidWd3OiAoKSA9PiB7fSwgd2Fybnc6ICgpID0+IHt9IH0sXG4gICk7XG5cbiAgY29uc3Qgc2V0TG9nTGV2ZWwgPSAobGV2ZWw6IHN0cmluZykgPT4ge1xuICAgIGxvZ2dlci5sZXZlbCA9IGdldExvZ0xldmVsKGxldmVsKTtcbiAgfTtcblxuICByZXR1cm4gT2JqZWN0LmFzc2lnbihsb2dnZXIsIG9iamVjdExvZ2dlciwge1xuICAgIHNldExvZ0xldmVsLFxuICAgIGdldExvZ0xldmVsLFxuICB9KTtcbn07XG4iXX0=