@rudderstack/integrations-lib
Version:
A comprehensive TypeScript library providing shared utilities, SDKs, and tools for RudderStack integrations and destinations.
122 lines • 14.9 kB
JavaScript
;
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=