60

I have many console.log (or any other console calls) in my code and I would like to use them only when my app is in some kind of "debug mode".

I can't seem to use some kind of logger function and internally use console.log because then I wouldn't know what line fired it. Maybe only with a try/catch, but my logs are very general and I don't want try/catch in my code.

What would you recommend?

5
  • 4
    Production code shouldn't be logging to the console. Commented Sep 21, 2011 at 13:56
  • I came across this: ariya.ofilabs.com/2013/04/… Commented Apr 14, 2013 at 17:01
  • I think logging to console is fine if you're in a very lightweight node.js docker container Commented Jan 13, 2017 at 21:45
  • I believe a simple regex during the build process that removes any console.* is the pretty good solution, is that regex is robust enough Commented Sep 19, 2018 at 7:22
  • Try this github.com/jchnxu/guard-with-debug. Disclaimer, I am the author. Commented Jan 6, 2023 at 13:42

11 Answers 11

61

I would probably abuse the short-circuiting nature of JavaScript's logical AND operator and replace instances of:

console.log("Foo.");

With:

DEBUG && console.log("Foo.");

Assuming DEBUG is a global variable that evaluates to true if debugging is enabled.

This strategy avoids neutering console.log(), so you can still call it in release mode if you really have to (e.g. to trace an issue that doesn't occur in debug mode).

Sign up to request clarification or add additional context in comments.

5 Comments

yeah but I'll have to add this everywhere...it's lots of code :)
@vsync: Find & replace is your friend. Find 'console.log', replace with 'DEBUG && console.log'. But overriding console if debug is enabled (like in bjornd's answer), or replacing calls to console.log with a method you can easily override / replace is a neater method that requires less or no existing code edits.
if (DEBUG) console.log("Foo."); only two characters longer and much more readable.
const altConsole = { ...console }; console.log = (...data) => !environment.production && altConsole.log(...data);
@shrys, what's that?!!!
52

Just replace the console.log with an empty function for production.

if (!DEBUG_MODE_ON) {
    console = console || {};
    console.log = function(){};
}

9 Comments

That's a hack. Your wasting computation in production
@Raynos: No, as I said I agree about it being a hack. Just wanted to point that out :)
@Raynos Be real, calling an empty function several times is nothing in compare to the rest of the application, it's just a quick way to solve the problem.
Yeah I see a lot of knee-jerk reactions to any extra processing from the mathematically-impaired. If you're doing 10^6 console.logs, there may still be a problem calling an empty function. Otherwise, a few hundred client-side calls to an empty function is nearly negligible.
@Raynos, "premature optimization is the root of all evil." Do you actually know any real case when this solution would noticeably degrade the performance? Have you done any benchmarks? I bet that the time spent on writing a batch script that removes all the logging (and never messes up the code) could be better invested...
|
34

Clobbering global functions is generally a bad idea.

Instead, you could replace all instances of console.log in your code with LOG, and at the beginning of your code:

var LOG = debug ? console.log.bind(console) : function () {};

This will still show correct line numbers and also preserve the expected console.log function for third party stuff if needed.

2 Comments

You can avoid polluting the global namespace by adding such a log function to your site's namespace. For instance myNamespace.log = myNamespace.DEBUG ? console.log : function(){};.
@NickG. -- you need to use Function::bind like I do in my example for console.log to work -- otherwise you'll get a permissions exception when you try to execute it.
16

Since 2014, I simply use GULP (and recommend everyone to, it's an amazing tool), and I have a package installed which is called stripDebug which does that for you.

(I also use uglify and closureCompiler in production)


Update (June 20, 2019)

There's a Babel Macro that automatically removes all console statements:

https://www.npmjs.com/package/dev-console.macro

4 Comments

Noone will use the whole new building system just to deal with "console.log in production" problem.
true, but a website that doesn't use any task manager such as GULP or GRUNT is probably far behind best-practices for web development. I want to encourage people to develop for the web in the proper way, which I truly believe that without task runner will most certainly be slower to maintain.
you can also run an NPM which just does that for you if you refuse to use GRUNT or GULP...
Anyone doing serious JS code for production should use some task runner to process the JS code, making it readable for development, and optimised for production - including stripping console.logs, comments etc. GULP and GRUNT are life savers. I'm up-voting this answer because it provides a solid solution that works in production and development.
6

One more way to disable console.log in production and keep it in development.

// overriding console.log in production
if(window.location.host.indexOf('localhost:9000') < 0) {
    console.log = function(){};
}

You can change your development settings like localhost and port.

Comments

3

This Tiny wrapper override will wrap the original console.log method with a function that has a check inside it, which you can control from the outside, deepening if you want to see console logs and not.

I chose window.allowConsole just as an example flag but in real-life use it would probably be something else. depending on your framework.

(function(cl){
  console.log = function(){
    if( window.allowConsole )
      cl(...arguments); 
  }
})(console.log)

Usage:

// in development (allow logging)
window.allowConsole = true;
console.log(1,[1,2,3],{a:1});

// in production (disallow logging)
window.allowConsole = false;
console.log(1,[1,2,3],{a:1});

This override should be implement as "high" as possible in the code hierarchy so it would "catch" all logs before then happen. This could be expanded to all the other console methods such as warn, time, dir and so on.

Comments

0

Simple.

Add a little bash script that finds all references to console.log and deletes them.

Make sure that this batch script runs as part of your deployment to production.

Don't shim out console.log as an empty function, that's a waste of computation and space.

3 Comments

Parsing JavaScript with batch file? Good joke!
Something like sed -i "/console\.log/d" <filename> would do it (GNU sed example), provided you keep all the console.logs on their own lines and don't have any in if blocks without braces.
this can be counter productive. Lots of things can go wrong here.
0

This code works for me:

if(console=='undefined' || !console || console==null) {
  var console = {
    log : function (string) {
        // nothing to do here!!
    }
  }
}

Comments

0

enter image description here

The newest versions of chrome show which line of code in which file fired console.log. If you are looking for a log management system, you can try out logeek it allows you to control which groups of logs you want to see.

Comments

0
// In Development:
var debugMode = true

// In Prod:
var debugMode = false

// This function logs console messages when debugMode is true .
function debugLog(logMessage) {
    if (debugMode) {
        console.log(logMessage);
    }
}

// Use the function instead of console.log
debugLog("This is a debug message");

1 Comment

it can't handler logs as console.log(logMessage1, log2, log3, ...)
0

console can out put not just log but errors warnings etc. Here is a function to override all console outputs

(function () {
    var method;
    var noop = function noop() { };
    var methods = [
    'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
    'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
    'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
    'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];
        console[method] = noop;
    }
}());

Refer to detailed post here https://stapp.space/disable-javascript-console-on-production/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.