console-log-json icon indicating copy to clipboard operation
console-log-json copied to clipboard

Add an option to avoid pulling object properties to the top level

Open mfursov opened this issue 2 years ago • 1 comments

Today console-log-json pulls object properties passed as args to the top level. Example:

 console.log('Hello', {a: 1}, {a: 2}, {a: 3}, 'World', {a: 4});

results to

{"level":"info","message":"Hello - World","___a":4,"__a":3,"_a":2,"a":1,"@timestamp":"2023-06-28T22:40:29.491Z"}

The behavior I suggest:

  1. Add a configuration option: CONSOLE_LOG_TOP_LEVEL_PROPERTIES_FIELD = 'topLevelPropsFieldName'
  2. When this option is set for the input above produce the following output:
{"level":"info","message":"Hello [0], [1], [2] World [3]",  "[0]":{"a":1},  "[1]":{"a":2}, "[2]":{"a":3},  "[3]":{"a":4},  "@timestamp":"2023-06-28T22:40:29.491Z"}

and use only properties from the {"topLevelPropsFieldName": {...}} to populate the top level.

Why this is needed: Without this manual and explicit control 'random' properties go to the top level and this may affect other tools (like DataDog filters)

mfursov avatar Jun 28 '23 23:06 mfursov

Here is an example how it can be implemented (not tested)

/**
 * It takes the arguments passed to the console.log function and logs them using Winston
 * @param {any[]} args - any[] - the arguments passed to the console.log function
 * @param {LOG_LEVEL} level - LOG_LEVEL
 * @param topLevelFieldName - when defined only object properties under this field are moved to the top level.
 */
export function logUsingWinston(args: any[], level: LOG_LEVEL, topLevelFieldName: string|undefined) {
  if (packageName.length === 0) {
    args.push({ '@packageName': '<not-yet-set> Please await the call LoggerAdaptToConsole() on startup' });
  } else {
    args.push({ '@packageName': packageName });
  }
  if (topLevelFieldName) {
      for (let i = 0; i < args.length; i++) {
          if (typeof args[i] === 'object') {
              let wrappedArg: Record<string, any> = {};
              wrappedArg[`[${i}]`] = {...args[i]};
              if (typeof wrappedArg[topLevelFieldName] === 'object') {
                  const topLevelFieldSet = wrappedArg[topLevelFieldName];
                  delete wrappedArg[topLevelFieldName];
                  wrappedArg = {...wrappedArg, ...topLevelFieldSet};
              }
              args[i] = wrappedArg;
          }
      }
  }
...

mfursov avatar Jun 28 '23 23:06 mfursov