Disabling console access for specific Javascript files

Write a white-listing "middleware" for console.log

// Preserve the old console.log
const log = console.log;

// Used a dictionary because it's faster than lists for lookups
const whiteListedFunctions = {"hello": true};

// Whitelisting "middleware". We used the function's name "funcName"
// as a criteria, but it's adaptable
const isWhitelisted = callerData => callerData.funcName in whiteListedFunctions;

// Replacing the default "console.log"
console.log = arg => {
  const stack = new Error().stack.split("at")[2].trim().split(' ');
  const fileParts = stack[1].substr(1, stack[1].length - 2).split(':');

  const callerData = {
    funcName: stack[0],
    file: fileParts.slice(0, fileParts.length - 2).join(':'),
    lineColNumber: fileParts.slice(fileParts.length - 2).join(':')
  };
  
  if (isWhitelisted(callerData)) {      // Filtering happens here
    log(arg);
  }
};

// Define the calling functions
function hello() { console.log("hello"); }
function world() { console.log("world"); }

hello(); // => Prints hello
world(); // => Doesn't print anything

Method explanation

  • You can do this by creating a whitelist (or blacklist) that will contain your filtering criteria. For example it may contain the name of the functions that call console.log or maybe the file name, or even the line and column numbers.
  • After that you create your whitelisting "middleware". This will take the caller function data and decide if it can log stuff or not. This will be done based on the previously defined whitelist. You can choose your preferred criteria in this "middleware".
  • Then you actually replace console.log by overriding with your new logger. This logger will take as an argument the message to log (maybe multiple arguments?). In this function you also need to find the data relating to the caller function (which wanted to call console.log).
  • Once you have the caller data, you can then use your whitelisting middleware to decide if it can log stuff

Getting information about the caller function

This part is a little "hacky" (but it got the job done in this case). We basically create an Error and check its stack attribute like this new Error().stack. Which will give us this trace

Error at console.log.arg [as log] (https://stacksnippets.net/js:25:7) at hello (https://stacksnippets.net/js:41:11) at https://stacksnippets.net/js:48:1

After processing (split, map, etc...) the trace we get the caller function data. For example here we have

  • The caller function's name: hello
  • The file name: https://stacksnippets.net/js
  • The line and column number: 41:11 (watch out for minifiers)

This bit was inspired by VLAZ's answer in How to disable console.log messages based on criteria from specific javascript source (method, file) or message contents, so make sure to check it out. Really good and thorough post.

Note

To make sense of the trace we can do new Error().stack.split("at")[INDEX].trim().split(' ') where INDEX is the position of the function call you want to target in the stack trace. So if you want to get a different "level" that the one used in this example, try changing INDEX

Tags:

Javascript