logpipes
Version:
Console.log transformation pipes
116 lines • 5.95 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateUuidSimple = exports.createJsonPipe = exports.getDefaultJsonPipeOptions = void 0;
const JsonSimplifier_1 = require("./JsonSimplifier");
/** Returns default properties used by 'createJsonPipe'. */
function getDefaultJsonPipeOptions() {
return Object.assign(Object.assign({}, (0, JsonSimplifier_1.getDefaultJsonSimplifierOptions)()), { messagePropertyName: 'message', levelPropertyName: 'level', levelPropertyFormatter: level => level, timestampPropertyName: 'timestamp', timestampPropertyFormatter: timeInMillis => new Date(timeInMillis).toISOString(), messageIdPropertyName: 'message_id', messageIdPropertyProvider: generateUuidSimple, isIgnoredProperty: () => false, getObjectMessageToken: argumentIndex => `$${argumentIndex + 1}`, pickFieldNameAsObjectMessageTokenForSingleFieldObjects: false, undefinedMessageValue: undefined });
}
exports.getDefaultJsonPipeOptions = getDefaultJsonPipeOptions;
/**
* Creates a pipe that converts console arguments into a serializable JSON object.
*/
function createJsonPipe(inputOptions = {}) {
const defaultJsonPipeOptions = getDefaultJsonPipeOptions();
const options = Object.assign(Object.assign({}, defaultJsonPipeOptions), inputOptions);
let lastMessageId = '';
let nextMessageId;
const logPipe = (level, ...args) => {
const resultJson = {};
let message = undefined;
resultJson[options.messagePropertyName] = undefined; // Set it first, so it will be the first property in JSON.
let messageArgIndex = 0;
for (let argIndex = 0; argIndex < args.length; argIndex++) {
const arg = (0, JsonSimplifier_1.simplifyValue)(args[argIndex]);
let messageToken = arg;
if (typeof arg === 'object' && arg !== null) {
let childValue = (0, JsonSimplifier_1.simplifyJson)(arg, options);
if (options.pickFieldNameAsObjectMessageTokenForSingleFieldObjects
&& typeof childValue === 'object'
&& childValue !== null) {
const childValueEntries = Object.entries(childValue);
if (childValueEntries.length === 1) {
const [childFieldName, childFieldValue] = childValueEntries[0];
const newMessageToken = `$${childFieldName}`;
if (resultJson[newMessageToken] === undefined) {
messageToken = newMessageToken;
if (isInlinedObjectMessageTokenValue(childFieldValue)) {
const quote = typeof childFieldValue === 'string' ? '\'' : '';
messageToken += `:[${quote}${childFieldValue}${quote}]`;
childValue = undefined;
}
else {
childValue = childFieldValue;
}
}
}
}
if (typeof messageToken !== 'string') {
messageToken = options.getObjectMessageToken(messageArgIndex, arg, argIndex);
messageArgIndex++;
}
resultJson[messageToken] = childValue;
}
else if (arg === undefined) {
if (options.undefinedMessageValue !== undefined) {
messageToken += options.undefinedMessageValue;
}
}
else {
messageToken = arg;
}
message = message === undefined ? `${messageToken}` : `${message} ${messageToken}`;
}
if (message) {
resultJson[options.messagePropertyName] = message;
}
if (options.levelPropertyName) {
resultJson[options.levelPropertyName] = options.levelPropertyFormatter(level);
}
if (options.timestampPropertyName) {
resultJson[options.timestampPropertyName] = options.timestampPropertyFormatter(Date.now());
}
if (options.messageIdPropertyName) {
let messageId = nextMessageId || options.messageIdPropertyProvider(level, ...args);
if (messageId === undefined) {
messageId = defaultJsonPipeOptions.messageIdPropertyProvider();
}
lastMessageId = messageId;
resultJson[options.messageIdPropertyName] = lastMessageId;
nextMessageId = undefined;
}
return [resultJson];
};
const jsonPipe = logPipe;
jsonPipe.getLastMessageId = () => lastMessageId;
jsonPipe.setNextMessageId = (messageId) => { nextMessageId = messageId; };
return jsonPipe;
}
exports.createJsonPipe = createJsonPipe;
/**
* Returns 'true' if the value can be inlined as a part of the
* 'pickFieldNameAsObjectMessageTokenForSingleFieldObjects' transformation.
*/
function isInlinedObjectMessageTokenValue(value) {
return value === null ||
typeof value === 'string' ||
typeof value === 'undefined' ||
typeof value === 'number' ||
typeof value === 'boolean';
}
/**
* Generates a random uuid-like string.
* The method does not provide the same level of randomness like 'crypto' based UUID generators.
* but it is good for most logging purposes were message id uniqueness is required only on some time-local period.
*/
function generateUuidSimple() {
let datePart = Date.now();
// noinspection SpellCheckingInspection
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const randomPart = (datePart + Math.floor(Math.random() * 16)) % 16;
datePart = Math.floor(datePart / 16);
return (c == 'x' ? randomPart : (randomPart & 0x3 | 0x8)).toString(16);
});
}
exports.generateUuidSimple = generateUuidSimple;
//# sourceMappingURL=JsonPipe.js.map