notetron/node_modules/roarr/dist/factories/createLogger.js.flow
2022-03-22 13:49:52 +07:00

197 lines
4.6 KiB
Text

// @flow
import environmentIsNode from 'detect-node';
import createGlobalThis from 'globalthis';
import stringify from 'json-stringify-safe';
import {
sprintf,
} from 'sprintf-js';
import {
logLevels,
} from '../constants';
import type {
LoggerType,
MessageContextType,
MessageEventHandlerType,
TranslateMessageFunctionType,
} from '../types';
const globalThis = createGlobalThis();
let domain;
if (environmentIsNode) {
// eslint-disable-next-line global-require
domain = require('domain');
}
const getParentDomainContext = () => {
if (!domain) {
return {};
}
const parentRoarrContexts = [];
let currentDomain = process.domain;
// $FlowFixMe
if (!currentDomain || !currentDomain.parentDomain) {
return {};
}
while (currentDomain && currentDomain.parentDomain) {
currentDomain = currentDomain.parentDomain;
if (currentDomain.roarr && currentDomain.roarr.context) {
parentRoarrContexts.push(currentDomain.roarr.context);
}
}
let domainContext = {};
for (const parentRoarrContext of parentRoarrContexts) {
domainContext = {
...domainContext,
...parentRoarrContext,
};
}
return domainContext;
};
const getFirstParentDomainContext = () => {
if (!domain) {
return {};
}
let currentDomain = process.domain;
// $FlowFixMe
if (currentDomain && currentDomain.roarr && currentDomain.roarr.context) {
return currentDomain.roarr.context;
}
// $FlowFixMe
if (!currentDomain || !currentDomain.parentDomain) {
return {};
}
while (currentDomain && currentDomain.parentDomain) {
currentDomain = currentDomain.parentDomain;
if (currentDomain.roarr && currentDomain.roarr.context) {
return currentDomain.roarr.context;
}
}
return {};
};
const createLogger = (onMessage: MessageEventHandlerType, parentContext?: MessageContextType): LoggerType => {
// eslint-disable-next-line id-length, unicorn/prevent-abbreviations
const log = (a, b, c, d, e, f, g, h, i, k) => {
const time = Date.now();
const sequence = globalThis.ROARR.sequence++;
let context;
let message;
if (typeof a === 'string') {
context = {
...getFirstParentDomainContext(),
...parentContext || {},
};
// eslint-disable-next-line id-length, object-property-newline
const {...args} = {a, b, c, d, e, f, g, h, i, k};
const values = Object.keys(args).map((key) => {
return args[key];
});
// eslint-disable-next-line unicorn/no-reduce
const hasOnlyOneParameterValued = 1 === values.reduce((accumulator, value) => {
// eslint-disable-next-line no-return-assign, no-param-reassign
return accumulator += typeof value === 'undefined' ? 0 : 1;
}, 0);
message = hasOnlyOneParameterValued ? sprintf('%s', a) : sprintf(a, b, c, d, e, f, g, h, i, k);
} else {
if (typeof b !== 'string') {
throw new TypeError('Message must be a string.');
}
context = JSON.parse(stringify({
...getFirstParentDomainContext(),
...parentContext || {},
...a,
}));
message = sprintf(b, c, d, e, f, g, h, i, k);
}
onMessage({
context,
message,
sequence,
time,
version: '1.0.0',
});
};
log.child = (context: TranslateMessageFunctionType | MessageContextType): LoggerType => {
if (typeof context === 'function') {
return createLogger((message) => {
if (typeof context !== 'function') {
throw new TypeError('Unexpected state.');
}
onMessage(context(message));
}, parentContext);
}
return createLogger(onMessage, {
...getFirstParentDomainContext(),
...parentContext,
...context,
});
};
log.getContext = (): MessageContextType => {
return {
...getFirstParentDomainContext(),
...parentContext || {},
};
};
log.adopt = async (routine, context) => {
if (!domain) {
return routine();
}
const adoptedDomain = domain.create();
return adoptedDomain
.run(() => {
// $FlowFixMe
adoptedDomain.roarr = {
context: {
...getParentDomainContext(),
...context,
},
};
return routine();
});
};
for (const logLevel of Object.keys(logLevels)) {
// eslint-disable-next-line id-length, unicorn/prevent-abbreviations
log[logLevel] = (a, b, c, d, e, f, g, h, i, k) => {
return log.child({
logLevel: logLevels[logLevel],
})(a, b, c, d, e, f, g, h, i, k);
};
}
// @see https://github.com/facebook/flow/issues/6705
// $FlowFixMe
return log;
};
export default createLogger;