357

Is there any way to turn off all console.log statements in my JavaScript code, for testing purposes?

Sebastian Zartner
  • 18,808
  • 10
  • 90
  • 132
Zack Burt
  • 8,257
  • 10
  • 53
  • 81
  • 14
    use a text editor that supports "replace all" and replace "console.log" with "//console.log" – helloandre Aug 01 '09 at 00:13
  • 8
    @helloandre - that gets a little tiresome though if you use log, info, warn debug and error – UpTheCreek Jun 03 '12 at 09:11
  • Hopefully we'll reach a point where browser implementations automatically bypass console statements unless the browser's debugging tool is enabled. – faintsignal Nov 05 '15 at 22:22
  • 3
    The answers below are great, but you don't have to reinvent the wheel on this one. Have a look at [picolog](https://www.npmjs.com/package/picolog). It has an API compatible with (NodeJS's) console, so you can use it as a drop-in replacement. It supports logging levels out of the box, works in the browser, on NodeJS and on Nashorn, can be easily configured from the querystring (browser) or environment variable `PICOLOG_LEVEL` (node) and it's *super* small. Less then 900 bytes minified and zipped. Disclaimer: I am the author. – Stijn de Witt Jan 03 '16 at 09:10
  • There is a simple way to override all `console` functions. Just look at http://stapp.space/disable-javascript-console-on-production/ – Piotr Stapp Jan 12 '16 at 12:25
  • no that's a horrible idea. – stackers Dec 05 '20 at 23:50
  • 1
    Why don't you make a simple wrapper (class, function, object) and use that everywhere instead, rather than using only `console.log` directly? – Matt Jul 12 '22 at 14:36

38 Answers38

531

Redefine the console.log function in your script.

console.log = function() {}

That's it, no more messages to console.

EDIT:

Expanding on Cide's idea. A custom logger which you can use to toggle logging on/off from your code.

From my Firefox console:

var logger = function()
{
    var oldConsoleLog = null;
    var pub = {};

    pub.enableLogger =  function enableLogger() 
                        {
                            if(oldConsoleLog == null)
                                return;

                            window['console']['log'] = oldConsoleLog;
                        };

    pub.disableLogger = function disableLogger()
                        {
                            oldConsoleLog = console.log;
                            window['console']['log'] = function() {};
                        };

    return pub;
}();

$(document).ready(
    function()
    {
        console.log('hello');

        logger.disableLogger();
        console.log('hi', 'hiya');
        console.log('this wont show up in console');

        logger.enableLogger();
        console.log('This will show up!');
    }
 );

How to use the above 'logger'? In your ready event, call logger.disableLogger so that console messages are not logged. Add calls to logger.enableLogger and logger.disableLogger inside the method for which you want to log messages to the console.

gunwin
  • 4,578
  • 5
  • 37
  • 59
SolutionYogi
  • 31,807
  • 12
  • 70
  • 78
99

The following is more thorough:

var DEBUG = false;
if(!DEBUG){
    if(!window.console) window.console = {};
    var methods = ["log", "debug", "warn", "info"];
    for(var i=0;i<methods.length;i++){
        console[methods[i]] = function(){};
    }
}

This will zero out the common methods in the console if it exists, and they can be called without error and virtually no performance overhead. In the case of a browser like IE6 with no console, the dummy methods will be created to prevent errors. Of course there are many more functions in Firebug, like trace, profile, time, etc. They can be added to the list if you use them in your code.

You can also check if the debugger has those special methods or not (ie, IE) and zero out the ones it does not support:

if(window.console && !console.dir){
var methods = ["dir", "dirxml", "trace", "profile"]; //etc etc
    for(var i=0;i<methods.length;i++){
        console[methods[i]] = function(){};
    }
}
mwilcox
  • 4,065
  • 23
  • 20
  • This worked for me perfectly, although I tweaked it a little bit, I checked for environment(I only want it disabled in production) – Punter Bad Mar 20 '20 at 13:20
37

As far as I can tell from the documentation, Firebug doesn't supply any variable to toggle debug state. Instead, wrap console.log() in a wrapper that conditionally calls it, i.e.:

DEBUG = true; // set to false to disable debugging
function debug_log() {
    if ( DEBUG ) {
        console.log.apply(this, arguments);
    }
}

To not have to change all the existing calls, you can use this instead:

DEBUG = true; // set to false to disable debugging
old_console_log = console.log;
console.log = function() {
    if ( DEBUG ) {
        old_console_log.apply(this, arguments);
    }
}
André Eriksson
  • 4,296
  • 2
  • 19
  • 16
  • 1
    Thanks, although this means I need to rewrite all my console.log statements as debug.log. – Zack Burt Aug 01 '09 at 00:05
  • This is the right way to do it - ofcourse if you are starting from scratch. – OpenSource Aug 01 '09 at 00:13
  • 3
    It is also the right way to do it if you have a good find/replace function in your editor. – BaroqueBobcat Aug 01 '09 at 00:34
  • 2
    No need to write your own wrapper, btw, at least if you're using jQuery. The jQuery Debugging Plugin works great. As a bonus it provides emulation of console.log on browsers without it. http://trainofthoughts.org/blog/2007/03/16/jquery-plugin-debug/ – Nelson Aug 01 '09 at 00:40
  • The only [minor] problem, of course, being that you need to install a plugin. :) Good to know, though - thanks! – André Eriksson Aug 01 '09 at 00:41
  • well not install, rather include the plugin on your page – redsquare Aug 01 '09 at 00:54
  • Good idea, but it doesn't work everywhere: IE8 defines console.log, but doesn't define console.log.apply. Bummer. – Eugene Lazutkin Aug 01 '09 at 01:53
  • Doesn't look like that second option works in <=IE7. You get a 'console is not defined' error in those browsers. – DA. Feb 05 '10 at 01:07
  • To make it work in IE7 etc please have a look at 'Chris S.' answer. – GuruM Feb 11 '13 at 06:54
  • Having been there and done that; wrapping it prevents you from using the Firebug feature that allows you to click directly to the line that caused the log message, as it will always jump to your wrapper method. – Gabriël Dec 04 '14 at 15:30
30

You should not!

It is not a good practice to overwrite built-in functions. There is also no guarantee that you will suppress all output, other libraries you use may conflict with your changes and there are other functions that may write to the console; .dir(), .warning(), .error(), .debug(), .assert() etc.

As some suggested, you could define a DEBUG_MODE variable and log conditionally. Depending on the complexity and nature of your code, it may be a good idea to write your own logger object/function that wraps around the console object and has this capability built-in. That would be the right place to do deal with instrumentation.

That said, for 'testing' purposes you can write tests instead of printing to the console. If you are not doing any testing, and those console.log() lines were just an aid to write your code, simply delete them.

istepaniuk
  • 4,016
  • 2
  • 32
  • 60
  • 12
    `"other libraries you use may revert your changes"`: if I disable `console.log` at the very start, they can't revert to the old function. Well, they can rewrite the `console.log` source code, but why? `"it may be a good idea to write your own logger object/function that wraps around the console object"`: I've done this in past and it's a bad idea. The trace of the console output refers to the wrapper and not to the line that invokes it, making debugging more difficult. – Marco Sulla Aug 07 '15 at 10:54
  • 3
    @LucasMalor "at the very start" implies the code is coupled to that infrastructure thus limiting its reusability. It is difficult to generalized though; A game, some DOM animations are not the same as domain logic inside a complex SPA, the later shouldn't be browser-aware, let alone knowing about something called "console". In that case you should have a proper testing strategy instead of hacking some `console.log('Look ma, it reaches this point');` in your code, when everything else fails you can indeed use the `debugger;` instruction. – istepaniuk Aug 10 '15 at 21:19
  • `"the code is coupled to that infrastructure"`: the code probably, but the pattern not. If you create a common basic template for your pages where logging functions are disabled, it's a logic that you can apply everywhere. `"the later shouldn't be browser-aware"`: well, so you shouldn't use JS :P – Marco Sulla Aug 12 '15 at 10:15
  • 4
    @MarcoSulla I think he's getting at writing cleaner code. Saying "....you shouldn't use JS" is a bit heavy handed. Ideally, as a programmer, no matter what your environment is, you should modularize as much as possible; if it doesn't care about browsers, then you can deploy it in more places: that's one less dependency to worry about breaking your stuff. So, IMHO yeah, he's actually right. Keep in mind that you started by saying "If you create a common basic template..." which in and of itself introduces a dependency. This kind of thinking is what complicates software. Food for thought. – dudewad Aug 31 '15 at 21:57
  • 1
    Adobe SiteCatalyics throws a lot of junk in my console and makes a hassle of debugging in some cases. So being able to temporarily disable console.log when I execute a third-party call would be pretty useful for me – spinn Mar 09 '18 at 10:54
  • Browsers aren't the only applications these days which use JS (e.g. electron, nodejs). And in any deployment you may have a really noisy console that you want to dampen it down by replacing the console object with something else.. – locka May 15 '20 at 10:46
23

I realize this is an old post but it still pops up at the top of Google results, so here is a more elegant non-jQuery solution that works in the latest Chrome, FF, and IE.

(function (original) {
    console.enableLogging = function () {
        console.log = original;
    };
    console.disableLogging = function () {
        console.log = function () {};
    };
})(console.log);
Joey Schooley
  • 431
  • 3
  • 7
14

Just change the flag DEBUG to override the console.log function. This should do the trick.

var DEBUG = false;
// ENABLE/DISABLE Console Logs
if(!DEBUG){
  console.log = function() {}
}
Swanidhi
  • 2,029
  • 1
  • 20
  • 21
  • 2
    I'd go one step further and wrap this in a logger function/class. Something like this: `function myLog(msg) { if (debug) { console.log(msg); } }` – sleblanc Apr 14 '15 at 19:44
  • If using Angular, you can use it as a global configuration in your application.js file and use it as a global property to switch the logs on /off. Remember, console will not be undefined if you have the developers toolbar open in IE. – Swanidhi May 01 '15 at 21:37
12

I am surprised that of all those answers no one combines:

  • No jquery
  • Anonymous function to not pollute global namespace
  • Handle case where window.console not defined
  • Just modify the .log function of the console

I'd go for this:

(function () {

    var debug = false

    if (debug === false) {
        if ( typeof(window.console) === 'undefined') { window.console = {}; }
        window.console.log = function () {};
    }
})()
Xavier13
  • 771
  • 7
  • 16
12

I know you asked how to disable console.log, but this might be what you're really after. This way you don't have to explicitly enable or disable the console. It simply prevents those pesky console errors for people who don't have it open or installed.

if(typeof(console) === 'undefined') {
    var console = {};
    console.log = console.error = console.info = console.debug = console.warn = console.trace = console.dir = console.dirxml = console.group = console.groupEnd = console.time = console.timeEnd = console.assert = console.profile = function() {};
}
Scott Greenfield
  • 2,788
  • 2
  • 22
  • 21
11

After I searched for this issue aswell and tried it within my cordova app, I just want to warn every developer for windows phone to not overwrite

    console.log

because the app will crash on startup.

It won't crash if you're developing local if you're lucky, but submitting in store it will result in crashing the app.

Just overwrite

    window.console.log 

if you need to.

This works in my app:

   try {
        if (typeof(window.console) != "undefined") {
            window.console = {};
            window.console.log = function () {
            };
            window.console.debug = function () {
            };
            window.console.info = function () {
            };
            window.console.warn = function () {
            };
            window.console.error = function () {
            };
        }

        if (typeof(alert) !== "undefined") {
            alert = function ()
            {

            }
        }

    } catch (ex) {

    }
Mel
  • 625
  • 9
  • 25
graphefruit
  • 364
  • 4
  • 15
  • Thanks for the "warning". HOWEVER, I had my cordova-based app released onto GooglePlay store, tested it with phone devices and all were fine. I may assume your warning was limited to "windows-based" app store? ... HOWEVER, it is good advise to put the ops within try-catch bracket just in case it blow up. Hence the thumbs-up. – Panini Luncher Oct 27 '19 at 20:04
8

If you're using IE7, console won't be defined. So a more IE friendly version would be:

if (typeof console == "undefined" || typeof console.log == "undefined") 
{
   var console = { log: function() {} }; 
}
Chris S
  • 64,770
  • 52
  • 221
  • 239
6

This a hybrid of answers from SolutionYogi and Chris S. It maintains the console.log line numbers and file name. Example jsFiddle.

// Avoid global functions via a self calling anonymous one (uses jQuery)
(function(MYAPP, $, undefined) {
    // Prevent errors in browsers without console.log
    if (!window.console) window.console = {};
    if (!window.console.log) window.console.log = function(){};

    //Private var
    var console_log = console.log;  

    //Public methods
    MYAPP.enableLog = function enableLogger() { console.log = console_log; };   
    MYAPP.disableLog = function disableLogger() { console.log = function() {}; };

}(window.MYAPP = window.MYAPP || {}, jQuery));


// Example Usage:
$(function() {    
    MYAPP.disableLog();    
    console.log('this should not show');

    MYAPP.enableLog();
    console.log('This will show');
});
Justin
  • 26,443
  • 16
  • 111
  • 128
6

If you use Webpack you could use the Terser plugin to completely exclude the console.log function calls.

This way you can have a clean production app package that will not expose unnecessary information but still have all this info in your debug build.

https://github.com/terser/terser#compress-options

drop_console (default: false) -- Pass true to discard calls to console.* functions. If you wish to drop a specific function call such as console.info and/or retain side effects from function arguments after dropping the function call then use pure_funcs instead.

minimizer: [
    new TerserPlugin({
        terserOptions: {
            compress: {
                pure_funcs: [ 'console.log' ]
            }
        }
    }),
]

Alternatively you can use drop_console: true to exclude all console calls.

Vedran
  • 10,369
  • 5
  • 50
  • 57
6

Here is a solution I just worked on that is fairly exhaustive. I covered all the fully supported console methods from https://developer.mozilla.org/en-US/docs/Web/API/console

1. Create js file "logger.js" and put in the following code in it

logger = {
    assert: function() {
        if(logger.active && logger.doAssert) {
            console.assert.apply(null,arguments);
        }
    },
    clear: function() {
        if(logger.active && logger.doClear) {
            console.clear();
        }
    },
    count: function() {
        if(logger.active && logger.doCount) {
            console.count.apply(null,arguments);
        }
    },
    countReset: function() {
        if(logger.active && logger.doCountReset) {
            console.countReset.apply(null,arguments);
        }
    },
    debug: function() {
        if(logger.active && logger.doDebug) {
            console.debug.apply(null,arguments);
        }
    },
    dir: function() {
        if(logger.active && logger.doDir) {
            console.dir.apply(null,arguments);
        }
    },
    dirxml: function() {
        if(logger.active && logger.doDirxml) {
            console.dirxml.apply(null,arguments);
        }
    },
    error: function() {
        if(logger.active && logger.doError) {
            console.error.apply(null,arguments);
        }
    },
    group: function() {
        if(logger.active && logger.doGroup) {
            console.group.apply(null,arguments);
        }
    },
    groupCollapsed: function() {
        if(logger.active && logger.doGroup) {
            console.groupCollapsed.apply(null,arguments);
        }
    },
    groupEnd: function() {
        if(logger.active && logger.doGroup) {
            console.groupEnd.apply(null,arguments);
        }
    },
    info: function() {
        if(logger.active && logger.doInfo) {
            console.info.apply(null,arguments);
        }
    },
    log: function() {
        if(logger.active && logger.doLog) {
            console.log.apply(null,arguments);
        }
    },
    table: function() {
        if(logger.active && logger.doTable) {
            console.table.apply(null,arguments);
        }
    },
    time: function() {
        if(logger.active && logger.doTime) {
            console.time.apply(null,arguments);
        }
    },
    timeEnd: function() {
        if(logger.active && logger.doTime) {
            console.timeEnd.apply(null,arguments);
        }
    },
    timeLog: function() {
        if(logger.active && logger.doTime) {
            console.timeLog.apply(null,arguments);
        }
    },
    trace: function() {
        if(logger.active && logger.doTrace) {
            console.trace.apply(null,arguments);
        }
    },
    warn: function() {
        if(logger.active && logger.doWarn) {
            console.warn.apply(null,arguments);
        }
    },
    active: true,
    doAssert: true,
    doClear: true,
    doCount: true,
    doCountReset: true,
    doDebug: true,
    doDir: true,
    doDirxml: true,
    doError: true,
    doGroup: true,
    doInfo: true,
    doLog: true,
    doTable: true,
    doTime: true,
    doTrace: true,
    doWarn: true
};

2. Include before all your scripts with logs in all pages

3. Replace all "console." with "logger." in your scripts

4. Usage

Used just like "console." but with "logger."

logger.clear();
logger.log("abc");

Finally disable some or all logs

//disable/enable all logs
logger.active = false; //disable
logger.active = true; //enable

//disable some logs
logger.doLog = false; //disable
logger.doInfo = false; //disable

logger.doLog = true; //enable
logger.doInfo = true; //enable

logger.doClear = false; //log clearing code will no longer clear the console.

EDIT

After using my solution for sometime in my latest project I realized that it's difficult to remember that I'm supposed to use logger. instead of console.. So for this reason I decided to override console. This is my updated solution:

const consoleSubstitute = console;
console = {
    assert: function() {
        if(console.active && console.doAssert) {
            consoleSubstitute.assert.apply(null,arguments);
        }
    },
    clear: function() {
        if(console.active && console.doClear) {
            consoleSubstitute.clear();
        }
    },
    count: function() {
        if(console.active && console.doCount) {
            consoleSubstitute.count.apply(null,arguments);
        }
    },
    countReset: function() {
        if(console.active && console.doCountReset) {
            consoleSubstitute.countReset.apply(null,arguments);
        }
    },
    debug: function() {
        if(console.active && console.doDebug) {
            consoleSubstitute.debug.apply(null,arguments);
        }
    },
    dir: function() {
        if(console.active && console.doDir) {
            consoleSubstitute.dir.apply(null,arguments);
        }
    },
    dirxml: function() {
        if(console.active && console.doDirxml) {
            consoleSubstitute.dirxml.apply(null,arguments);
        }
    },
    error: function() {
        if(console.active && console.doError) {
            consoleSubstitute.error.apply(null,arguments);
        }
    },
    group: function() {
        if(console.active && console.doGroup) {
            consoleSubstitute.group.apply(null,arguments);
        }
    },
    groupCollapsed: function() {
        if(console.active && console.doGroup) {
            consoleSubstitute.groupCollapsed.apply(null,arguments);
        }
    },
    groupEnd: function() {
        if(console.active && console.doGroup) {
            consoleSubstitute.groupEnd.apply(null,arguments);
        }
    },
    info: function() {
        if(console.active && console.doInfo) {
            consoleSubstitute.info.apply(null,arguments);
        }
    },
    log: function() {
        if(console.active && console.doLog) {
            if(console.doLogTrace) {
                console.groupCollapsed(arguments);
                consoleSubstitute.trace.apply(null,arguments);
                console.groupEnd();
            } else {
                consoleSubstitute.log.apply(null,arguments);
            }
        }
    },
    table: function() {
        if(console.active && console.doTable) {
            consoleSubstitute.table.apply(null,arguments);
        }
    },
    time: function() {
        if(console.active && console.doTime) {
            consoleSubstitute.time.apply(null,arguments);
        }
    },
    timeEnd: function() {
        if(console.active && console.doTime) {
            consoleSubstitute.timeEnd.apply(null,arguments);
        }
    },
    timeLog: function() {
        if(console.active && console.doTime) {
            consoleSubstitute.timeLog.apply(null,arguments);
        }
    },
    trace: function() {
        if(console.active && console.doTrace) {
            consoleSubstitute.trace.apply(null,arguments);
        }
    },
    warn: function() {
        if(console.active && console.doWarn) {
            consoleSubstitute.warn.apply(null,arguments);
        }
    },
    active: true,
    doAssert: true,
    doClear: true,
    doCount: true,
    doCountReset: true,
    doDebug: true,
    doDir: true,
    doDirxml: true,
    doError: true,
    doGroup: true,
    doInfo: true,
    doLog: true,
    doLogTrace: false,
    doTable: true,
    doTime: true,
    doTrace: true,
    doWarn: true
};

Now you can just use console. as usual.

Zuks
  • 1,247
  • 13
  • 20
4

If you use Grunt you can add a task in order to remove/comment the console.log statements. Therefore the console.log are no longer called.

https://www.npmjs.org/package/grunt-remove-logging-calls

jdborowy
  • 61
  • 2
4

I have used winston logger earlier.

Nowadays I am using below simpler code from experience:

  1. Set the environment variable from cmd/ command line (on Windows):

    cmd
    setx LOG_LEVEL info
    

Or, you could have a variable in your code if you like, but above is better.

  1. Restart cmd/ command line, or, IDE/ editor like Netbeans

  2. Have below like code:

    console.debug = console.log;   // define debug function
    console.silly = console.log;   // define silly function
    
    switch (process.env.LOG_LEVEL) {
        case 'debug':
        case 'silly':
            // print everything
            break;
    
        case 'dir':
        case 'log':
            console.debug = function () {};
            console.silly = function () {};
            break;
    
        case 'info':
            console.debug = function () {};
            console.silly = function () {};
            console.dir = function () {};
            console.log = function () {};
            break;
    
        case 'trace':   // similar to error, both may print stack trace/ frames
        case 'warn':    // since warn() function is an alias for error()
        case 'error':
            console.debug = function () {};
            console.silly = function () {};
            console.dir = function () {};
            console.log = function () {};
            console.info = function () {};
            break;
    }
    
  3. Now use all console.* as below:

    console.error(' this is a error message '); // will print
    console.warn(' this is a warn message '); // will print
    console.trace(' this is a trace message '); // will print
    console.info(' this is a info message '); // will print, LOG_LEVEL is set to this
    
    console.log(' this is a log message '); // will NOT print
    console.dir(' this is a dir message '); // will NOT print
    console.silly(' this is a silly message '); // will NOT print
    console.debug(' this is a debug message '); // will NOT print
    

Now, based on your LOG_LEVEL settings made in the point 1 (like, setx LOG_LEVEL log and restart command line), some of the above will print, others won't print

Hope that helped.

Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
4

To disable console.log only:

console.log = function() {};

To disable all functions that write to the console:

for (let func in console) {
   console[func] = function() {};
}

Xavier Mukodi
  • 166
  • 1
  • 10
3

Ive been using the following to deal with he problem:-

var debug = 1;
var logger = function(a,b){ if ( debug == 1 ) console.log(a, b || "");};

Set debug to 1 to enable debugging. Then use the logger function when outputting debug text. It's also set up to accept two parameters.

So, instead of

console.log("my","log");

use

logger("my","log");
3

My comprehensive solution to disable/override all console.* functions is here.

Of course, please make sure you are including it after checking necessary context. For example, only including in production release, it's not bombing any other crucial components etc.

Quoting it here:

"use strict";
(() => {
  var console = (window.console = window.console || {});
  [
    "assert", "clear", "count", "debug", "dir", "dirxml",
    "error", "exception", "group", "groupCollapsed", "groupEnd",
    "info", "log", "markTimeline", "profile", "profileEnd", "table",
    "time", "timeEnd", "timeStamp", "trace", "warn"
  ].forEach(method => {
    console[method] = () => {};
  });
  console.log("This message shouldn't be visible in console log");
})();
kmonsoor
  • 7,600
  • 7
  • 41
  • 55
3

globalThis was introduced in JS 2020. On browsers globalThis same as window, on nodejs - same as global etc. On any environement it will point directly to the global object, so this code will work on any env which supports JS2020 Learn more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis

With any modern browser & nodejs v12 or newer you should use this:

globalThis.console.log = () => null;
globalThis.console.warn = () => null;
globalThis.console.info = () => null;
globalThis.console.error = () => null;
Lukas Liesis
  • 24,652
  • 10
  • 111
  • 109
2

I found a little more advanced piece of code in this url JavaScript Tip: Bust and Disable console.log:

var DEBUG_MODE = true; // Set this value to false for production

if(typeof(console) === 'undefined') {
   console = {}
}

if(!DEBUG_MODE || typeof(console.log) === 'undefined') {
   // FYI: Firebug might get cranky...
   console.log = console.error = console.info = console.debug = console.warn = console.trace = console.dir = console.dirxml = console.group = console.groupEnd = console.time =    console.timeEnd = console.assert = console.profile = function() {};
}
kikeenrique
  • 2,589
  • 2
  • 25
  • 46
2

I developed a library for this usecase: https://github.com/sunnykgupta/jsLogger

Features:

  1. It safely overrides the console.log.
  2. Takes care if the console is not available (oh yes, you need to factor that too.)
  3. Stores all logs (even if they are suppressed) for later retrieval.
  4. Handles major console functions like log, warn, error, info.

Is open for modifications and will be updated whenever new suggestions come up.

Sunny R Gupta
  • 5,026
  • 1
  • 31
  • 40
2

This should override all methods of window.console. You can put it on the very top of your scripts section, and if you are on a PHP framework you can only print this code when your app environment is production, or if some kind of debug flag is disabled. Then you would have all your logs in your code working on development environments or in debug mode.

window.console = (function(originalConsole){
    var api = {};
    var props = Object.keys(originalConsole);
    for (var i=0; i<props.length; i++) {
        api[props[i]] = function(){};
    }
    return api;
})(window.console);
agm-dev
  • 29
  • 2
2

A simplification of https://stackoverflow.com/a/46189791/871166

switch (process.env.LOG_LEVEL) {
  case 'ERROR':
    console.warn = function() {};
  case 'WARN':
    console.info = function() {};
  case 'INFO':
    console.log = function() {};
  case 'LOG':
    console.debug = function() {};
    console.dir = function() {};
}

7ynk3r
  • 958
  • 13
  • 17
2

Warning: Shameless plug!

You could also use something like my JsTrace object to have modular tracing with module-level "switching" capability to only turn on what you want to see at the time.

http://jstrace.codeplex.com

(Also has a NuGet package, for those who care)

All levels default to "error", though you can shut them "off". Though, I can't think of why you would NOT want to see errors

You can change them like this:

Trace.traceLevel('ModuleName1', Trace.Levels.log);
Trace.traceLevel('ModuleName2', Trace.Levels.info);

Fore more docs, check out the Documentation

T

Tom McKearney
  • 315
  • 2
  • 11
1

I wrote this:

//Make a copy of the old console.
var oldConsole = Object.assign({}, console);

//This function redefine the caller with the original one. (well, at least i expect this to work in chrome, not tested in others)
function setEnabled(bool) {
    if (bool) {
        //Rewrites the disable function with the original one.
        console[this.name] = oldConsole[this.name];
        //Make sure the setEnable will be callable from original one.
        console[this.name].setEnabled = setEnabled;
    } else {
        //Rewrites the original.
        var fn = function () {/*function disabled, to enable call console.fn.setEnabled(true)*/};
        //Defines the name, to remember.
        Object.defineProperty(fn, "name", {value: this.name});
        //replace the original with the empty one.
        console[this.name] = fn;
        //set the enable function
        console[this.name].setEnabled = setEnabled

    }
}

Unfortunately it doesn't work on use strict mode.

So using console.fn.setEnabled = setEnabled and then console.fn.setEnabled(false) where fn could be almost any console function. For your case would be:

console.log.setEnabled = setEnabled;
console.log.setEnabled(false);

I wrote this too:

var FLAGS = {};
    FLAGS.DEBUG = true;
    FLAGS.INFO = false;
    FLAGS.LOG = false;
    //Adding dir, table, or other would put the setEnabled on the respective console functions.

function makeThemSwitchable(opt) {
    var keysArr = Object.keys(opt);
    //its better use this type of for.
    for (var x = 0; x < keysArr.length; x++) {
        var key = keysArr[x];
        var lowerKey = key.toLowerCase();
        //Only if the key exists
        if (console[lowerKey]) {
            //define the function
            console[lowerKey].setEnabled = setEnabled;
            //Make it enabled/disabled by key.
            console[lowerKey].setEnabled(opt[key]);
        }
    }
}
//Put the set enabled function on the original console using the defined flags and set them.
makeThemSwitchable(FLAGS);

so then you just need to put in the FLAGS the default value (before execute the above code), like FLAGS.LOG = false and the log function would be disabled by default, and still you could enabled it calling console.log.setEnabled(true)

Gabriel Rohden
  • 1,307
  • 9
  • 19
  • do you think that this could be used to enable the console.log in production environment on the fly? like open Chrome console, run `console.log.setEnabled(true)` and start seeing logs – Rodrigo Assis Sep 15 '17 at 18:28
  • 1
    @RodrigoAssis yes, it will work. I've created this just to do not lose the caller line and enable anywhere, but this isn't the best way to do it. The best way for logs is use the short circuit way like: `var debug = false; debug && console.log(1/3)` because you don't need to evaluate the log content if it isn't enabled (in this case `1/3` will not be evaluated), don't lose the caller line and can enable it easily too (if don't vars as consts). – Gabriel Rohden Sep 18 '17 at 17:06
1

If you're using gulp, then you can use this plugin:

Install this plugin with the command:

npm install gulp-remove-logging

Next, add this line to your gulpfile:

var gulp_remove_logging = require("gulp-remove-logging");

Lastly, add the configuration settings (see below) to your gulpfile.

Task Configuration

gulp.task("remove_logging", function() {
     return gulp.src("src/javascripts/**/*.js")
    .pipe(
      gulp_remove_logging()
    )
    .pipe(
      gulp.dest(
        "build/javascripts/"
      )
    ); });
Andrew Nessin
  • 1,206
  • 2
  • 15
  • 22
1

One liner just set devMode true/false;

console.log = devMode ? console.log : () => { };

Dharman
  • 30,962
  • 25
  • 85
  • 135
kunj choksi
  • 381
  • 3
  • 9
1

To add a bit on top of the other answers, I personally wanted to turn off only specific parts of my code (ES6 modules, but simple separate scripts should work as well).


// old console to restore functionality
const consoleHolder = window.console;

// arbitrary strings, for which the console stays on (files which you aim to debug)
const debuggedHandlers = ["someScript", "anotherScript"];

// get console methods and create a dummy with all of them empty
const consoleMethodKeys = Object.getOwnPropertyNames(window.console).filter(item => typeof window.console[item] === 'function');
const consoleDummy = {};
consoleMethodKeys.forEach(method => consoleDummy[method] = () => {});

export function enableConsoleRedirect(handler) {
  if (!debuggedHandlers.includes(handler)) {
    window.console = consoleDummy;
  }
}

export function disableConsoleRedirect() {
  window.console = consoleHolder;
}

Then, just import this module into any file where you want to be able to switch debug mode, call the enable function at the top of the file, and the disable function at the bottom.

If you want to use it in simple scripts, you may want to wrap the top in anonymous functions and/or reorganize it a bit to minimize the namespace pollution.

Additionally, you may want to use just true/false instead of string handler and switch the debug mode in file which you're currently working with.

Samuel Novelinka
  • 328
  • 3
  • 10
1

Hey~ Let's do in a modern 2022 way~

Proxy and Reflect are introduced in ES6. These are the tools we are looking for to make the console.log being "disabled" with condition.

In the traditional way, you have to create another function like this:

    let console_disabled = true;

    function console_log() {
      if (!console_disabled) {
        console.log.apply(console, arguments); //Dev Tools will mark the coding line here
      }
    }

However, this will create another function and you cannot log the message with the coding line shown in Dev Tools.

Here is the 2022 way.

// Disable Console Log without altering debug coding line.
// No override original `console` object
  let console_disabled = false;

  const nullFunc = function(){};
  const _console = new Proxy(console, {
    get(target, prop, receiver){
      if(prop==='log' && console_disabled){
        return nullFunc;
      }
      return Reflect.get(...arguments)
    }
  });

  console_disabled = true;
  _console.log('you cannot see me');
  console_disabled = false;
  _console.log('you can see me @ line 18');
  console_disabled = true;
  _console.log('you cannot see me');
  console_disabled = false;
  _console.log('you can see me @ line 22');

You might also override the original console object.

// Disable Console Log without altering debug coding line.
// Override original `console` object
  let console_disabled = false;

  const nullFunc = function(){};
  console = new Proxy(console, {
    get(target, prop, receiver){
      if(prop==='log' && console_disabled){
        return nullFunc;
      }
      return Reflect.get(...arguments)
    }
  });

  console_disabled = true;
  console.log('you cannot see me');
  console_disabled = false;
  console.log('you can see me @ line 18');
  console_disabled = true;
  console.log('you cannot see me');
  console_disabled = false;
  console.log('you can see me @ line 22');

Remarks: Local Override

You do not need to change any coding and variable.


(function () {

  const console = (() => {
    const nullFunc = function () { };
    let console_disabled = false;
    const console = new Proxy(window.console, {
      get(target, prop, receiver) {
        if (prop === 'log' && console_disabled) {
          return nullFunc;
        }
        return Reflect.get(...arguments)
      },
      set(target, prop, value, receiver) {
        if (prop === 'disabled') {
          console_disabled = value;
          return true;
        }
        return Reflect.set(...arguments);
      }
    });
    return console;
  })();

  console.disabled = true;
  console.log('you cannot see me');
  console.disabled = false;
  console.log('you can see me');
  console.disabled = true;
  console.log('you cannot see me');
  console.disabled = false;
  console.log('you can see me');


})();

For details of Proxy and Reflect, please visit https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Chester Fung
  • 182
  • 1
  • 10
0

You could use javascript AOP (e.g. jquery-aop) to intercept all calls to console.debug/log (around) and do not proceed with the actual invocation if some global variable is set to false.

You could even do an ajax call (now and then) so you can change the log enabled/disabled behavior on the server which can be very interesting to enable debugging when facing an issue in a staging environment or such.

Stijn Geukens
  • 15,454
  • 8
  • 66
  • 101
0

After doing some research and development for this problem, I came across this solution which will hide warnings/Errors/Logs as per your choice.

    (function () {
    var origOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function () {        
        console.warn = function () { };
        window['console']['warn'] = function () { };
        this.addEventListener('load', function () {                        
            console.warn('Something bad happened.');
            window['console']['warn'] = function () { };
        });        
    };
})();

Add this code before JQuery plugin (e.g /../jquery.min.js) even as this is JavaScript code that does not require JQuery. Because some warnings are in JQuery itself.

Thanks!!

Sunny_Sid
  • 401
  • 4
  • 13
0

I wrote a ES2015 solution ( use only with Webpack ).

class logger {
  static isEnabled = true;

  static enable () {
    if(this.constructor.isEnabled === true){ return; }

    this.constructor.isEnabled = true;
  }

  static disable () {
    if(this.constructor.isEnabled === false){ return; }

    this.constructor.isEnabled = false;
  }

  static log () {
    if(this.constructor.isEnabled === false ) { return; }

    const copy = [].slice.call(arguments);

    window['console']['log'].apply(this, copy);
  }

  static warn () {
    if(this.constructor.isEnabled === false ) { return; }

    const copy = [].slice.call(arguments);

    window['console']['warn'].apply(this, copy);
  }

  static error () {
    if(this.constructor.isEnabled === false ) { return; }

    const copy = [].slice.call(arguments);

    window['console']['error'].apply(this, copy);
  }
}

Description:

  1. Along with logger.enable and logger.disable you can use console.['log','warn','error'] methods as well using logger class.
  2. By using logger class for displaying, enabling or disabling messages makes the code much cleaner and maintainable.
  3. The code below shows you how to use the logger class:
    • logger.disable() - disable all console messages
    • logger.enable() - enable all console messages
    • logger.log('message1', 'message2') - works exactly like console.log.
    • logger.warn('message1', 'message2') - works exactly like console.warn.
    • logger.error('message1', 'message2') - works exactly like console.error. Happy coding..
Jaskaran Singh
  • 914
  • 8
  • 8
0

I think that the easiest and most understandable method in 2020 is to just create a global function like log() and you can pick one of the following methods:

const debugging = true;

function log(toLog) {
  if (debugging) {
    console.log(toLog);
  }
}
function log(toLog) {
  if (true) { // You could manually change it (Annoying, though)
    console.log(toLog);
  }
}

You could say that the downside of these features is that:

  1. You are still calling the functions on runtime
  2. You have to remember to change the debugging variable or the if statement in the second option
  3. You need to make sure you have the function loaded before all of your other files

And my retorts to these statements is that this is the only method that won't completely remove the console or console.log function which I think is bad programming because other developers who are working on the website would have to realize that you ignorantly removed them. Also, you can't edit JavaScript source code in JavaScript, so if you really want something to just wipe all of those from the code you could use a minifier that minifies your code and removes all console.logs. Now, the choice is yours, what will you do?

sno2
  • 3,274
  • 11
  • 37
0
console.log('pre');
/* pre content */ 
// define a new console
let preconsole = Object.assign({}, window.console);
let aftconsole = Object.assign({}, window.console, {
    log: function(text){
        preconsole.log(text);
        preconsole.log('log');
    }
});
console = aftconsole;
/* content */

console.log('content');

/* end of content */
console = preconsole;
console.log('aft');
Weilory
  • 2,621
  • 19
  • 35
0

When using React you can utilize hooks to manage it so it's limited to the scope of your component

import { useEffect, useRef } from "react";

type LoggingReplacements = {
  debug?: typeof console["debug"];
  error?: typeof console["error"];
  info?: typeof console["info"];
  log?: typeof console["log"];
  warn?: typeof console["warn"];
};
/**
 * This replaces console.XXX loggers with custom implementations.  It will restore console log on unmount of the component.
 * @param replacements a map of replacement loggers.  They're all optional and only the functions defined will be replaced.
 */
export function useReplaceLogging({
  debug,
  error,
  info,
  log,
  warn,
}: LoggingReplacements): void {
  const originalConsoleDebug = useRef(console.debug);
  const originalConsoleError = useRef(console.error);
  const originalConsoleInfo = useRef(console.info);
  const originalConsoleLog = useRef(console.log);
  const originalConsoleWarn = useRef(console.warn);
  if (debug) {
    console.debug = debug;
  }
  if (error) {
    console.error = error;
  }
  if (info) {
    console.info = info;
  }
  if (log) {
    console.log = log;
  }
  if (warn) {
    console.warn = warn;
  }
  useEffect(() => {
    return function restoreConsoleLog() {
      console.debug = originalConsoleDebug.current;
      console.error = originalConsoleError.current;
      console.info = originalConsoleInfo.current;
      console.log = originalConsoleLog.current;
      console.warn = originalConsoleWarn.current;
    };
  }, []);
}

Code with tests at https://github.com/trajano/react-hooks/tree/master/src/useReplaceLogging

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265
0

This is my approach. https://github.com/jchnxu/guard-with-debug Disclaimer: I am the author of this tiny utility

localStorage.debug = [
    'enable/console/log/in/this/file.ts',
    'enable/console/log/in/this/folder/*',
    '-disable/console/log/in/this/file.ts',
    '-disable/console/log/in/this/folder/*',
    
    // enable all
    '*',
].join(',');

The benefit of this approach is we can enable / disable based on file names, especially useful when

  • debugging across multiple complex module
  • the output content is large and visually disturbing
  • quickly turn on / off logging with touching the codebase, safer when you are simply deploying to production with more logs.

Why touch console.log? Is it dangerous?

This is somehow opinionated. I found myself writing a lot of console.logs instead of the more standard way of import logger from 'xxx' && logger.info(...). I guess the reason is that console.log is js-native and it feels a lot more natural.

This plugin only adds a guard to console.log instead of monkey-patching. It's safe.

And you can safely remove all the console.logs in production with this plugin, or keep the ones you want using the same configuration as above.

addlistener
  • 871
  • 1
  • 12
  • 20
-1

You can use logeek, It allows you to control your log messages visibility. Here is how you do that:

<script src="bower_components/dist/logeek.js"></script>

logeek.show('security');

logeek('some message').at('copy');       //this won't be logged
logeek('other message').at('secturity'); //this would be logged

You can also logeek.show('nothing') to totally disable every log message.

Iman Mohamadi
  • 6,552
  • 3
  • 34
  • 33
-1

I found this thread after figuring it out myself. Here's my solution:

const testArray = {
  a: 1,
  b: 2
};
const verbose = true; //change this to false to turn off all comments
const consoleLog = (...message) => {
  return verbose ? console.log(...message) : null;
};

console.log("from console.log", testArray);
consoleLog("from consoleLog", testArray);
// use consoleLog() for the comments you want to be able to toggle.
Victor Lazaro
  • 545
  • 2
  • 6
  • 16