@log4js2/core
Version:
log4js2 is a fast and lightweight logging library that enables logging flexibility within JavaScript/TypeScript applications, similar to Apache's [Log4j2 library](https://logging.apache.org/log4j/2.x/). It can also serve as a drop-in replacement for log4
426 lines (425 loc) • 10.1 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
var log_level_1 = require("../const/log.level");
var utility_1 = require("../util/utility");
var date_formatter_1 = require("./date.formatter");
/**
* @function
* @memberOf formatter
*
* @param {string} layout
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function format(layout, logEvent) {
return _formatLogEvent(_getCompiledLayout(layout), logEvent);
}
exports.format = format;
/** @type {Map} */
var _compiledLayouts = new Map();
var _formatters = {
'c|logger': _formatLogger,
'd|date': _formatDate,
'ex|exception|throwable': _formatException,
'F|file': _formatFile,
'K|map|MAP': _formatMapMessage,
'L|line': _formatLineNumber,
'column': _formatColumn,
'm|msg|message': _formatLogMessage,
'M|method': _formatMethodName,
'marker': _formatMarker,
'markerSimpleName': _formatMarkerSimple,
'n': _formatLineSeparator,
'p|level': _formatLevel,
'r|relative': _formatRelative,
'sn|sequenceNumber': _formatSequenceNumber
};
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatLogger(logEvent) {
return logEvent.logger;
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
* @param {Array.<string>} params
*
* @return {string}
*/
function _formatDate(logEvent, params) {
return date_formatter_1.formatDate(logEvent.date, date_formatter_1.DateTimeFormat[params[0]] || params[0]);
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatException(logEvent) {
var message = '';
if (logEvent.error != null) {
if (logEvent.error.stack) {
var stacks = logEvent.error.stack.split(/\n/g);
message += stacks.reduce(function (accumulator, value) { return accumulator + ("\t" + value + "\n"); });
}
else if (logEvent.error.message != null && logEvent.error.message !== '') {
message += "\t" + logEvent.error.name + ": " + logEvent.error.message + "\n";
}
}
return message;
}
/**
* Formats the file (e.g. test.js) to the file
*
* @private
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*/
function _formatFile(logEvent) {
if (!logEvent.file) {
_getFileDetails(logEvent);
}
return logEvent.file;
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatLineNumber(logEvent) {
if (!logEvent.lineNumber) {
_getFileDetails(logEvent);
}
return "" + logEvent.lineNumber;
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatColumn(logEvent) {
if (!logEvent.column) {
_getFileDetails(logEvent);
}
return "" + logEvent.column;
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
* @param {Array.<string>} params
*
* @return {string}
*/
function _formatMapMessage(logEvent, params) {
var message = null;
if (logEvent.properties) {
message = [];
for (var key in logEvent.properties) {
if (params[0]) {
if (params[0] === key) {
message.push(logEvent.properties[key]);
}
}
else {
message.push('{' + key + ',' + logEvent.properties[key] + '}');
}
}
return '{' + message.join(',') + '}';
}
return message;
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatLogMessage(logEvent) {
return logEvent.message;
}
function _formatMarkerFromEvent(marker) {
if (marker.hasParents()) {
var formatted = marker.getParents().map(function (parent) { return _formatMarkerFromEvent(parent); });
return marker.name + "[ " + formatted + " ]";
}
else {
return "" + marker.name;
}
}
/**
*
* @private
*
* @param {ILogEvent} logEvent
* @return {string}
*/
function _formatMarker(logEvent) {
return (logEvent.marker) ? _formatMarkerFromEvent(logEvent.marker) : '';
}
/**
* Formats just the marker name (no parents)
*
* @private
*
* @param {ILogEvent} logEvent
* @return {string}
*/
function _formatMarkerSimple(logEvent) {
return (logEvent.marker) ? logEvent.marker.name : '';
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatMethodName(logEvent) {
return utility_1.getFunctionName(logEvent.method);
}
/**
* @private
* @function
* @memberOf formatter
*/
function _formatLineSeparator() {
return '\n';
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatLevel(logEvent) {
switch (logEvent.level) {
case log_level_1.LogLevel.FATAL:
return 'FATAL';
case log_level_1.LogLevel.ERROR:
return 'ERROR';
case log_level_1.LogLevel.WARN:
return 'WARN';
case log_level_1.LogLevel.INFO:
return 'INFO';
case log_level_1.LogLevel.DEBUG:
return 'DEBUG';
case log_level_1.LogLevel.TRACE:
default:
return 'TRACE';
}
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatRelative(logEvent) {
return '' + logEvent.relative;
}
/**
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatSequenceNumber(logEvent) {
return '' + logEvent.sequence;
}
/**
* Get the compiled layout for the specified layout string. If the compiled layout does not
* exist, then we want to create it.
*
* @function
* @memberOf formatter
*
* @param {string} layout
*
* @return {Array.<string|function>}
*/
function _getCompiledLayout(layout) {
if (_compiledLayouts.has(layout)) {
return _compiledLayouts.get(layout);
}
return _compileLayout(layout);
}
/**
* Compiles a layout into an array. The array contains functions
*
* @function
* @memberOf formatter
*
* @param {string} layout
*
* @return {Array.<string|function>}
*/
function _compileLayout(layout) {
var formatArray = layout.match(/(%\w+({[\w-]+}|)|.)/g)
.map(function (value) { return _getFormatterObject(value); });
// set the format array to the specified compiled layout
_compiledLayouts.set(layout, formatArray);
return formatArray;
}
/**
* @function
* @memberOf formatter
*
* @param {string} formatString
*
* @return {Object|string}
*/
function _getFormatterObject(formatString) {
var result = /%(\w+)(?:{([\w-]+)})*/g.exec(formatString);
if (result == null) {
return formatString;
}
else if (result.length < 3) {
return {
formatter: _getFormatterFunction(result[1]),
params: []
};
}
else {
var formatter = _getFormatterFunction(result[1]);
if (!formatter) {
return null;
}
var params = _getLayoutTagParams(result[2]);
return {
formatter: formatter,
params: params
};
}
}
/**
* Determines what formatter function has been configured
*
* @function
* @memberOf formatter
*
* @param {string} command
*
* @return {?string}
*/
function _getFormatterFunction(command) {
var regex;
for (var key in _formatters) {
if (_formatters.hasOwnProperty(key)) {
regex = new RegExp('^(' + key + ')$');
if (regex.exec(command)) {
return _formatters[key];
}
}
}
return null;
}
/**
* Gets the layout tag params associated with the layout tag. So, for example, '%d{yyyy-MM-dd}`
* would output an array of ['yyyy-MM-dd']
*
* @private
* @function
*
* @param {string} command
*
* @return {Array.<string>}
*/
function _getLayoutTagParams(command) {
return (command) ? command.split(',') : [];
}
/**
* Handles formatting the log event using the specified formatter array
*
* @private
* @function
*
* @param {Array.<function|string>} formatter
* @param {ILogEvent} logEvent
*
* @return {string}
*/
function _formatLogEvent(formatter, logEvent) {
var response;
var message = '';
var count = formatter.length;
for (var i = 0; i < count; i++) {
if (formatter[i] !== null) {
if (formatter[i] instanceof Object) {
response = formatter[i].formatter(logEvent, formatter[i].params);
if (response != null) {
message += response;
}
}
else {
message += formatter[i];
}
}
}
return message.trim();
}
/**
*
* @private
* @function
* @memberOf formatter
*
* @param {ILogEvent} logEvent
*/
function _getFileDetails(logEvent) {
if (logEvent.logErrorStack) {
var parts = logEvent.logErrorStack.stack.split(/\n/g);
var file = parts[3];
file = file.replace(/at (.*\(|)(file|http|https|)(:|)(\/|)*/, '');
file = file.replace(')', '');
file = file.replace((typeof location !== 'undefined') ? location.host : '', '').trim();
var fileParts = file.split(/:/g);
logEvent.column = fileParts.pop();
logEvent.lineNumber = fileParts.pop();
if (typeof define !== 'undefined') {
var path = require('path');
var appDir = path.dirname(require.main.filename);
if (!fileParts[0] || !fileParts[0].startsWith(appDir)) {
appDir = '';
}
logEvent.filename = fileParts.join(':').replace(appDir, '').replace(/^([\\\/])/, '');
}
else {
logEvent.filename = fileParts.join(':');
}
}
else {
logEvent.column = '?';
logEvent.filename = 'anonymous';
logEvent.lineNumber = '?';
}
logEvent.file = logEvent.filename;
}