Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabling console access for specific Javascript files

Tags:

javascript

In my current project with lots of dependencies I need a way to disable console access for specific libraries so that those files can't use any of the console functionality.

I could of course disable console functionality by simply finding and replacing it in the library bundle, but as this project has a lot of dependencies that would make updating libraries a huge hassle.

I'm aware that I can disable console functionality by overwriting it with an empty function block:

console.log = function(){};

But that disables the console functionality for the entire project. So im looking for an implementation, or a line of code with which I can disable console functionality for a specific file or code block.

like image 718
KoenvE Avatar asked Feb 08 '19 14:02

KoenvE


People also ask

How do I close the console in Javascript?

exit() method to exit from the Node console. or even simpler you can just type . exit . and even simpler type ctrlc, twice.

How do I disable the browser console?

To disable Javascript console, we need to throw an exception in the get accessor by checking if the property attached by chrome developer tool exists. With this script above, user won't be allowed to enter Javascript in the console. It also blocks auto-complete in console too.

Can Javascript read the console?

You can't. What's in the console can't be read from JavaScript. console. logs contains all what was logged.


1 Answers

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

like image 88
molamk Avatar answered Oct 20 '22 21:10

molamk