155

I'm fairly new to Javascript development so this might be a real newbie question.

I've got a application riddled with console.log(); for debugging purposes.

I've got doing all of my build time combining. It outputs a app.debug.js for debugging as well as a app.min.js for production

Now I could go through all of my code files looking for console.log(); and delete it manually when I'm ready to go to production, but I'm wondering if there's a way to override the method.

Basically, whenever the console.log(); method is called, DO NOTHING.

That way, I can put the override code file in my production config, and NOT in my debug config.

Is this possible?

Charles
  • 50,943
  • 13
  • 104
  • 142
Chase Florell
  • 46,378
  • 57
  • 186
  • 376
  • 3
    create your own object with the name `console` with `log` function that does nothing/only function definition. – Sarfraz Aug 12 '11 at 15:43
  • 8
    Here is a great way to override the `console.log` function, Yet preserve the original functionality of the function... http://udidu.blogspot.co.il/2012/12/override-console-functions.html – udidu Dec 17 '12 at 10:47
  • Chase -- can you let me know if my duplicate close is wrong or not? (then I can reverse) – Naftali Oct 20 '15 at 13:34
  • May I recommend [picolog](https://www.npmjs.com/package/picolog)? It's super-small, works in the browser, nodejs and Nashorn, supports the Nodejs console API (so can be easily dropped in to replace the normal console) and accepts logging levels from the querystring (browser) or environment variable `PICOLOG_LEVEL`. Disclaimer: I am the author. I wrote it specifically because I got sick of the having to choose whether to include some big logging library, or write tests around accesses to the console etc. I ended up re-implementing the same stuff in each project and so I created this library. – Stijn de Witt Jan 03 '16 at 09:06

13 Answers13

242

Put this at the top of the file:

var console = {};
console.log = function(){};

For some browsers and minifiers, you may need to apply this onto the window object.

window.console = console;
SleepyCal
  • 5,739
  • 5
  • 33
  • 47
Naftali
  • 144,921
  • 39
  • 244
  • 303
  • 88
    Don't forget to override `console.info`, `console.warn` and `console.error` too, if you use those – Flambino Aug 12 '11 at 15:44
  • @Flambino, I've never used `console.info` before. Looking at the output of each of them, they "appear" to be the same... what would you say the difference is between `log` and `info`? – Chase Florell Aug 12 '11 at 15:52
  • @rockinthesixstring: As neal says, they're basically the same; they all just print stuff to the console. At most, you get different little icons next to the printed line (e.g. a warning icon for something printed by `warn`), and that's it. But that's actually quite useful, to quickly tell a bunch of console messages apart – Flambino Aug 12 '11 at 16:04
  • it "appears" as though the console.info is supposed to add a blue exclamation mark to the beginning of the line, but it is not supported in Google Chrome (as far as I can tell). – Chase Florell Aug 12 '11 at 16:04
  • @rockinthesixstring: Yeah, it's the same as `log` in Chrome/Safari. But in Firebug you do get the little icon :) – Flambino Aug 12 '11 at 16:10
  • 16
    FWIW, there are a bunch of other functions on console's prototype, though many of them rarely used. As of Chrome 38: `assert`, `clear`, `constructor`, `count`, `debug`, `dir`, `dirxml`, `error`, `group`, `groupCollapsed`, `groupEnd`, `info`, `log`, `markTimeline`, `profile`, `profileEnd`, `table`, `time`, `timeEnd`, `timeStamp`, `timeline`, `timelineEnd`, `trace`, `warn`. – tomekwi Nov 12 '14 at 10:25
  • 13
    Though this is a highly voted answer, i dont recommend it, it overrides the entire console object, rather than overriding only the log function. – Sharjeel Ahmed Aug 14 '17 at 14:11
  • 1
    My answer below addresses the issue of nuking the whole console object as opposed to overriding each method. It's also flexible since it doesn't actually know what methods are available. It just replaces all methods on the console object. It's future proof. – posit labs Oct 10 '17 at 18:35
  • incomplete answer. how do you handle arguments? – Bahadir Balban Mar 29 '21 at 02:19
  • 3
    ```var console = console || {}; console.log = function(){}; ``` is a way better way to only override log – Xiaojiba Jul 30 '21 at 13:30
90

Or if you just want to redefine the behavior of the console (in order to add logs for example) You can do something like that:

// define a new console
var console=(function(oldCons){
    return {
        log: function(text){
            oldCons.log(text);
            // Your code
        },
        info: function (text) {
            oldCons.info(text);
            // Your code
        },
        warn: function (text) {
            oldCons.warn(text);
            // Your code
        },
        error: function (text) {
            oldCons.error(text);
            // Your code
        }
    };
}(window.console));

//Then redefine the old console
window.console = console;
Alain
  • 1,450
  • 3
  • 20
  • 37
Ludovic Feltz
  • 11,416
  • 4
  • 47
  • 63
  • 17
    Very nice... since these console methods accept multiple arguments, at the cost of a little extra complexity we could support that by calling `oldCons.log.apply(arguments)` – pythonjsgeo Jan 28 '18 at 12:46
  • 3
    @python1981, or we can use ES6 spread operator. – Den Kison Oct 11 '19 at 09:14
  • 4
    there are SO MANY more methods on the `console` object than this. beware that if you do just this and someone's code tries to use any of those other methods, you're going to get lots of `undefined is not a function` errors! https://developer.mozilla.org/en-US/docs/Web/API/Console_API – Chris Calo Apr 29 '22 at 18:40
58

It would be super useful to be able to toggle logging in the production build. The code below turns the logger off by default.

When I need to see logs, I just type debug(true) into the console.

var consoleHolder = console;
function debug(bool){
    if(!bool){
        consoleHolder = console;
        console = {};
        Object.keys(consoleHolder).forEach(function(key){
            console[key] = function(){};
        })
    }else{
        console = consoleHolder;
    }
}
debug(false);

To be thorough, this overrides ALL of the console methods, not just console.log.

posit labs
  • 8,951
  • 4
  • 36
  • 66
  • 2
    It is workink fine but remove line consoleHolder = console; when bool = false on line no. 4. Because this line disable this function when calling debug(false) two time continusly. We can't call again debug(true) if we have already called debug(false);debug(false); means two time – Harendra Chauhan Jun 07 '20 at 08:55
11

I use something similar to what posit labs does. Save the console in a closure and you have it all in one portable function.

var GlobalDebug = (function () {
    var savedConsole = console;
    return function(debugOn,suppressAll){
        var suppress = suppressAll || false;
        if (debugOn === false) {
            console = {};
            console.log = function () { };
            if(suppress) {
                console.info = function () { };
                console.warn = function () { };
                console.error = function () { };
            } else {
                console.info = savedConsole.info;
                console.warn = savedConsole.warn;
                console.error = savedConsole.error;              
            }
        } else {
            console = savedConsole;
        }
    }
})();

Just do globalDebug(false) to toggle log messages off or globalDebug(false,true) to remove all console messages.

Ryan
  • 827
  • 9
  • 26
  • 1
    Exactly what I was looking for, to not only disable the logs but a way to enable it also from the browser itself. – Harry Jul 21 '16 at 19:00
7

I would recommend using: 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.

Disclaimer: I am the author of the plugin.

Sunny R Gupta
  • 5,026
  • 1
  • 31
  • 40
  • 1
    That looks really nice! I like the idea of having the list of logs for later. Just as a suggestion (though simple enough), some more docs might be useful in your README – Andrew McOlash Jul 31 '17 at 15:44
7
console.log = function(){};

Override it like any other thing.

Zirak
  • 38,920
  • 13
  • 81
  • 92
  • 20
    -1. Do not do this! The line here will both throw a `ReferenceError` and leave `console.log` undefined on browsers where the `console` object does not exist, which is an issue for at least some versions of IE. If your objective is to make your web app production-ready, like the OP, then this is almost *not* the solution you need. Do what Neal wrote instead. – Mark Amery Apr 16 '13 at 22:56
  • 6
    @MarkAmery You're correct. I took the literal meaning of "override", as in "replace", so of course I assumed an original existed. – Zirak Apr 17 '13 at 03:54
5

You could also use regex to delete all the console.log() calls in your code if they're no longer required. Any decent IDE will allow you to search and replace these across an entire project, and allow you to preview the matches before committing the change.

\s*console\.log\([^)]+\);
Pappa
  • 1,593
  • 14
  • 20
  • 1
    Thanks for the downvote. I was responding to this part of the question. "I could go through all of my code files looking for console.log(); and delete it manually when I'm ready to go to production" – Pappa Oct 16 '13 at 21:20
  • 1
    will it match `console.log("update() function called");`? – Bodzio Jun 02 '16 at 11:21
  • 1
    No, unfortunately not. If you're not expecting the logs to be followed by any other code, the following could be used: \s*console\.log\(.+\); But that's more risky. – Pappa Jun 03 '16 at 07:47
  • What I meant is that it will fail whent there is `)` somewhere in message. – Bodzio Jun 03 '16 at 08:00
4

After read a lot of posts, I made my own solution as follow:

SCRIPT:

function extendConsole() {
    "use strict";
    try {
        var disabledConsoles = {};

        console.enable = function (level, enabled) {
            // Prevent errors in browsers without console[level]
            if (window.console === 'undefined' || !window.console || window.console === null) {
                window.console = {};
            }
            if (window.console[level] === 'undefined' || !window.console[level] || window.console[level] == null) {
                window.console[level] = function() {};
            }

            if (enabled) {
                if (disabledConsoles[level]) {
                    window.console[level] = disabledConsoles[level];
                }
                console.info("console." + level + "() was enabled.");
            } else {
                disabledConsoles[level] = window.console[level];
                window.console[level] = function () { };
                console.info("console." + level + "() was disabled.");
            }
        };
    } catch (exception) {
        console.error("extendConsole() threw an exception.");
        console.debug(exception);
    }
}

USAGE:

extendConsole();
console.enable("debug", window.debugMode);

EXAMPLE:

http://jsfiddle.net/rodolphobrock/2rzxb5bo/10/

Rodolpho Brock
  • 8,027
  • 2
  • 28
  • 27
4

This will override console.log function when the url does not contain localhost. You can replace the localhost with your own development settings.

// overriding console.log in production
if(window.location.host.indexOf('localhost:9000') < 0) {
    console.log = function(){};
}
vinesh
  • 4,745
  • 6
  • 41
  • 45
  • 1
    clever, but there's a lot of additional overhead with this approach. It's a much better solution to alter your script during a deployment process. Use some sort of automated deployment tool to inject the code found in the [accepted answer](http://stackoverflow.com/a/7042634/124069), so that there are zero if checks. – Chase Florell Apr 20 '15 at 14:34
3

Theres no a reason to let all that console.log all over your project in prod enviroment... If you want to do it on the proper way, add UglifyJS2 to your deployment process using "drop_console" option.

neiker
  • 8,887
  • 4
  • 29
  • 32
  • 1
    Discarding console calls rather than keeping them for error context isn't really great. Although I can see why you'd want to do this, if you didn't have proper error and log management – SleepyCal May 10 '14 at 17:10
  • If I set a particular cookie/header, debug mode is enabled and unminified js is loaded (also server statics are logged on browser console). – neiker Jul 15 '14 at 16:01
  • just a remark, uglify2 in requirejs doesn't have this option :o – TecHunter Nov 04 '15 at 15:32
3

Here is what I did

    var domainNames =["fiddle.jshell.net"]; // we replace this by our production domain.

var logger = {
    force:false,
    original:null,
    log:function(obj)
    {
        var hostName = window.location.hostname;
        if(domainNames.indexOf(hostName) > -1)
        {
            if(window.myLogger.force === true)
            {
                window.myLogger.original.apply(this,arguments);
            }
        }else {
            window.myLogger.original.apply(this,arguments);
        }
    },
    forceLogging:function(force){
        window.myLogger.force = force;
    },
    original:function(){
        return window.myLogger.original;
    },
    init:function(){
        window.myLogger.original = console.log;
        console.log = window.myLogger.log;
    }
}

window.myLogger = logger;
console.log("this should print like normal");
window.myLogger.init();
console.log("this should not print");
window.myLogger.forceLogging(true);
console.log("this should print now");

Also posted about it here. http://bhavinsurela.com/naive-way-of-overriding-console-log/

Bhavin
  • 427
  • 3
  • 15
3

Just remember that with this method each console.log call will still do a call to a (empty) function causing overhead, if there are 100 console.log commands, you are still doing 100 calls to a blank function.

Not sure how much overhead this would cause, but there will be some, it would be preferable to have a flag to turn debug on then use something along the lines of:

var debug=true; if (debug) console.log('blah')
Kayem
  • 47
  • 1
  • 4
    that would involve going through all of the code and adding those if statements -- which is tedious. – Naftali Sep 08 '11 at 16:28
  • 1
    It does require more code, but this technique has its advantages: `debug` can be toggled at runtime; and when `debug` is false, there is no inefficient building of strings which will be immediately discarded. So developers can write *heavy* logging without hurting production performance, but still get that information from clients if they really need it. – joeytwiddle Jul 15 '14 at 20:40
  • The runtime toggle is useful. – jozecuervo May 07 '15 at 23:54
  • 1
    Good advice, though not technically an answer to the question. Still I think this answer should get more votes as just overriding native objects is not a recommended practice in Javascript. Other scripts may use the console. It actually has a lot of functionality that you are discarding when you replace it. – Stijn de Witt Jul 10 '15 at 08:17
  • actually it would be a real answer if you combine this with uglify --compress. Also use `DEBUG && console.log(...` quicker. pro is that the code will be removed (dead code), cons: tedious – TecHunter Nov 04 '15 at 15:32
1

You can look into UglifyJS: http://jstarrdewar.com/blog/2013/02/28/use-uglify-to-automatically-strip-debug-messages-from-your-javascript/, https://github.com/mishoo/UglifyJS I haven't tried it yet.

Quoting,

 if (typeof DEBUG === 'undefined') DEBUG = true; // will be removed

 function doSomethingCool() {
     DEBUG && console.log("something cool just happened"); // will be removed }

...The log message line will be removed by Uglify's dead-code remover (since it will erase any conditional that will always evaluate to false). So will that first conditional. But when you are testing as uncompressed code, DEBUG will start out undefined, the first conditional will set it to true, and all your console.log() messages will work.

Sergey Orshanskiy
  • 6,794
  • 1
  • 46
  • 50