feat: use data Error for callStack information

use the first data value if an Error to get callstack info. Only 1 line will be stripped from it by default

Refs: #1268
This commit is contained in:
Zachary Haber 2022-06-17 14:31:54 -05:00 committed by Lam Wei Li
parent 22c7d224de
commit 89b8a58f3f
No known key found for this signature in database
GPG Key ID: 90F6ABECF080D7BF

View File

@ -8,10 +8,32 @@ const categories = require('./categories');
const configuration = require('./configuration');
const stackReg = /at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;
/**
* The top entry is the Error
*/
const baseCallStackSkip = 1;
/**
* The _log function is 3 levels deep, we need to skip those to make it to the callSite
*/
const defaultErrorCallStackSkip = 3;
function defaultParseCallStack(data, skipIdx = 4) {
/**
*
* @param {Error} data
* @param {number} skipIdx
* @returns {import('../types/log4js').CallStack | null}
*/
function defaultParseCallStack(
data,
skipIdx = defaultErrorCallStackSkip + baseCallStackSkip
) {
try {
const stacklines = data.stack.split('\n').slice(skipIdx);
if (!stacklines.length) {
// There's no stack in this stack
// Should we try a previous index if skipIdx was set?
return null;
}
const lineMatch = stackReg.exec(stacklines[0]);
/* istanbul ignore else: failsafe */
if (lineMatch && lineMatch.length === 6) {
@ -71,6 +93,7 @@ class Logger {
}
this.category = name;
this.context = {};
/** @private */
this.parseCallStack = defaultParseCallStack;
debug(`Logger created (${this.category}, ${this.level})`);
}
@ -123,12 +146,28 @@ class Logger {
_log(level, data) {
debug(`sending log data (${level}) to appenders`);
let callStack;
if (this.useCallStack) {
try {
if (data[0] instanceof Error) {
callStack = this.parseCallStack(data[0], baseCallStackSkip);
}
} catch (_err) {
// Ignore Error
}
callStack =
callStack ||
this.parseCallStack(
new Error(),
defaultErrorCallStackSkip + baseCallStackSkip
);
}
const loggingEvent = new LoggingEvent(
this.category,
level,
data,
this.context,
this.useCallStack && this.parseCallStack(new Error())
callStack
);
clustering.send(loggingEvent);
}