Fine tune logging capabilities of `json-prune` scriptlet

This extends logging capabilities of `json-prune` scriptlet as
follow:

  ...##+js(json-prune, a, b, stackNeedle, log, [logneedle], logstack, 1)

Whereas before, the only way to log `json-prune` usage was to skip
providing the property chain:

  ...##+js(json-prune, , b)

Where `b` was the expression to filter out logging output.

With the extended logging capabilities, the logging output can
be filtered out with `logneedle`, which can be a regex literal.

Additionally, to log the stack trace the `stackNeedle` argument
must be set to non-empty string. You can use `/.^/` to log the
stack trace without matching it.
This commit is contained in:
Raymond Hill 2023-07-29 10:22:52 -04:00
parent b9f3523c95
commit 81b2fcee5d
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 27 additions and 10 deletions

View File

@ -621,6 +621,7 @@ builtinScriptlets.push({
name: 'object-prune.fn', name: 'object-prune.fn',
fn: objectPrune, fn: objectPrune,
dependencies: [ dependencies: [
'get-extra-args.fn',
'matches-stack-trace.fn', 'matches-stack-trace.fn',
'pattern-to-regex.fn', 'pattern-to-regex.fn',
], ],
@ -641,18 +642,24 @@ function objectPrune(
const prunePaths = rawPrunePaths !== '' const prunePaths = rawPrunePaths !== ''
? rawPrunePaths.split(/ +/) ? rawPrunePaths.split(/ +/)
: []; : [];
const extraArgs = getExtraArgs(Array.from(arguments), 4);
let needlePaths; let needlePaths;
let log, reLogNeedle; let log, reLogNeedle;
if ( prunePaths.length !== 0 ) { if ( prunePaths.length !== 0 ) {
needlePaths = prunePaths.length !== 0 && rawNeedlePaths !== '' needlePaths = prunePaths.length !== 0 && rawNeedlePaths !== ''
? rawNeedlePaths.split(/ +/) ? rawNeedlePaths.split(/ +/)
: []; : [];
if ( extraArgs.log !== undefined ) {
log = console.log.bind(console);
reLogNeedle = patternToRegex(extraArgs.log);
}
} else { } else {
log = console.log.bind(console); log = console.log.bind(console);
reLogNeedle = patternToRegex(rawNeedlePaths); reLogNeedle = patternToRegex(rawNeedlePaths);
} }
if ( stackNeedle !== '' ) { if ( stackNeedle !== '' ) {
if ( matchesStackTrace(patternToRegex(stackNeedle), log ? '1' : 0) === false ) { const reStackNeedle = patternToRegex(stackNeedle);
if ( matchesStackTrace(reStackNeedle, extraArgs.logstack) === false ) {
return obj; return obj;
} }
} }
@ -816,6 +823,7 @@ builtinScriptlets.push({
name: 'matches-stack-trace.fn', name: 'matches-stack-trace.fn',
fn: matchesStackTrace, fn: matchesStackTrace,
dependencies: [ dependencies: [
'get-exception-token.fn',
'safe-self.fn', 'safe-self.fn',
], ],
}); });
@ -855,9 +863,9 @@ function matchesStackTrace(
const stack = lines.join('\t'); const stack = lines.join('\t');
const r = safe.RegExp_test.call(reNeedle, stack); const r = safe.RegExp_test.call(reNeedle, stack);
if ( if (
logLevel === '1' || logLevel === 1 ||
logLevel === '2' && r || logLevel === 2 && r ||
logLevel === '3' && !r logLevel === 3 && !r
) { ) {
safe.uboLog(stack.replace(/\t/g, '\n')); safe.uboLog(stack.replace(/\t/g, '\n'));
} }
@ -993,6 +1001,7 @@ builtinScriptlets.push({
fn: abortOnStackTrace, fn: abortOnStackTrace,
dependencies: [ dependencies: [
'get-exception-token.fn', 'get-exception-token.fn',
'get-extra-args.fn',
'matches-stack-trace.fn', 'matches-stack-trace.fn',
'pattern-to-regex.fn', 'pattern-to-regex.fn',
], ],
@ -1000,24 +1009,24 @@ builtinScriptlets.push({
// Status is currently experimental // Status is currently experimental
function abortOnStackTrace( function abortOnStackTrace(
chain = '', chain = '',
needle = '', needle = ''
logLevel = ''
) { ) {
if ( typeof chain !== 'string' ) { return; } if ( typeof chain !== 'string' ) { return; }
const reNeedle = patternToRegex(needle); const reNeedle = patternToRegex(needle);
const extraArgs = getExtraArgs(Array.from(arguments), 2);
const makeProxy = function(owner, chain) { const makeProxy = function(owner, chain) {
const pos = chain.indexOf('.'); const pos = chain.indexOf('.');
if ( pos === -1 ) { if ( pos === -1 ) {
let v = owner[chain]; let v = owner[chain];
Object.defineProperty(owner, chain, { Object.defineProperty(owner, chain, {
get: function() { get: function() {
if ( matchesStackTrace(reNeedle, logLevel) ) { if ( matchesStackTrace(reNeedle, extraArgs.log) ) {
throw new ReferenceError(getExceptionToken()); throw new ReferenceError(getExceptionToken());
} }
return v; return v;
}, },
set: function(a) { set: function(a) {
if ( matchesStackTrace(reNeedle, logLevel) ) { if ( matchesStackTrace(reNeedle, extraArgs.log) ) {
throw new ReferenceError(getExceptionToken()); throw new ReferenceError(getExceptionToken());
} }
v = a; v = a;
@ -1136,20 +1145,28 @@ function jsonPrune(
rawNeedlePaths = '', rawNeedlePaths = '',
stackNeedle = '' stackNeedle = ''
) { ) {
const extraArgs = Array.from(arguments).slice(3);
JSON.parse = new Proxy(JSON.parse, { JSON.parse = new Proxy(JSON.parse, {
apply: function(target, thisArg, args) { apply: function(target, thisArg, args) {
return objectPrune( return objectPrune(
Reflect.apply(target, thisArg, args), Reflect.apply(target, thisArg, args),
rawPrunePaths, rawPrunePaths,
rawNeedlePaths, rawNeedlePaths,
stackNeedle stackNeedle,
...extraArgs
); );
}, },
}); });
Response.prototype.json = new Proxy(Response.prototype.json, { Response.prototype.json = new Proxy(Response.prototype.json, {
apply: function(target, thisArg, args) { apply: function(target, thisArg, args) {
return Reflect.apply(target, thisArg, args).then(o => return Reflect.apply(target, thisArg, args).then(o =>
objectPrune(o, rawPrunePaths, rawNeedlePaths, stackNeedle) objectPrune(
o,
rawPrunePaths,
rawNeedlePaths,
stackNeedle,
...extraArgs
)
); );
}, },
}); });