DEV Community

loading...
Cover image for console.log(x): The way out

console.log(x): The way out

princetegaton profile image Prince Tegaton ・2 min read

Logging is a critical technique developers need to trace code problems and bugs irrespective of the language. Logs can be written to flat files (text), database tables, IDE/web browser consoles and many more.

Web developers will always find a way to forget cleaning up the console.log(x) used in JavaScript codes. To me, this smells untidiness: leaving debug data to the eyes of the public is not clean for a professional (when left intentionally).

2 years ago I came up with a technique that allow me to ignore removing logs from every single portion of my JavaScript code. Same can be implemented for any language. This is done by creating a custom log class and methods. Instead of calling console.log(x), you can do logger.log(x). On the logger class, there is a boolean variable named 'is_active =true'. On production environment, this value is set to is_active =false and all log lines will be bypassed from not being printed to console.

View code on Github Repository

The snippet is shown below. The overloads can be ignored.

logger.js

let is_active = true;

const logtype = {
    "default": 1,
    "info": 2,
    "warning": 3,
    "error": 4,
    "exception": 5,
    "debug": 6,
    "table": 7
};

function log(data, type = logtype.default) {
    if (!is_active) return;

    try {
        switch (type) {
            case logtype.default:
                return console.log(data);
            case logtype.info:
                return console.info(data);
            case logtype.warning:
                return console.warn(data);
            case logtype.error:
                return console.error(data);
            case logtype.exception:
                return console.exception(data);
            case logtype.debug:
                return console.debug(data);
            case logtype.table:
                return console.table(data);
        }
    } catch (ex) {
        console.log(data);
    }
}

function info(data) {
    if (is_active) console.info(data);
}

function warning(data) {
    if (is_active) console.warn(data);
}

function error(data) {
    if (is_active) console.error(data);
}

function exception(data) {
    if (is_active) console.exception(data);
}

function debug(data) {
    if (is_active) console.debug(data);
}

function table(data) {
    if (is_active) console.table(data);
}
Enter fullscreen mode Exit fullscreen mode

Implementation

<script>
    window.onload = function () {
    log('hello world..');
    log('I have an information', logtype.info);
    log('But i must warn you', logtype.warn);
    log('About the errors you have made', logtype.error);
    log('Well, exceptions are not the end of the world', logtype.exception);
    log('And that calls for more debugging', logtype.debug);

var array = [
    {
        name: 'James',
        age: 21,
        location: 'Nigeria',
        role: 'Backend'
    }, {
        name: 'Mike',
        age: 19,
        location: 'Los Angeles',
        role: 'Frontend'
    }, {
        name: 'Parker',
        age: 26,
        location: 'London',
        role: 'Tester'
    }];

log(array, logtype.table);

</script>
Enter fullscreen mode Exit fullscreen mode

The result in web browser console is seen below.

web-console

Change the variable 'is_active=false' and all log activities will be stopped.

PS: this does not mean you should not clean up logs from code

Discussion

pic
Editor guide
Collapse
yoursunny profile image
Junxiao Shi

I don't have any printf() console.log() fmt.Println() when I commit code.

Wherever logging needs to stay in production, they go through libraries:

  • C: zf_log
  • JavaScript: loglevel or debug
  • Go: logrus

Then, I can use console.log etc freely during debugging, and run git grep -nw console.log to find and delete them before committing code.

Collapse
jamesthomson profile image
James Thomson

Myself I prefer a debug function which accepts a function so anything can be run in debug mode. It's a little more verbose, but very flexible. This React env implementation has a flag for production which may or may not be desirable.

const debug = (fn: () => void) => {
  const env = process.env.REACT_APP_ENV;
  const hasFlag = window.location.search.includes('debug=true');

  if (env === 'production' && !hasFlag) return;
  if (fn && typeof fn === 'function') fn();
};

export default debug;
Enter fullscreen mode Exit fullscreen mode
debug(() => console.log('debugging'));
Enter fullscreen mode Exit fullscreen mode
Collapse
cherrydt profile image
David Trapp

To me, this smells untidiness: leaving debug data to the eyes of the public is not clean for a professional (when left intentionally).

I disagree. In the website itself yes, but not inside the devtools.

I can't tell you how often I ran into an issue in some web application (sometimes a bug, sometimes just an unforeseen circumstance) that prevented me from doing my work, and I went into devtools to find out what went wrong and either fix it if the reason was external or bypass it or at least understand the problem. In some cases it was easy thanks to debug logs and sometimes it was super annoying because I first had to spend 15 minutes to figure out how to access that flag deeply hidden inside some closure which I could use to force logging on.

I think it is presumptuous to expect everyone who encounters a problem to stop their work and wait until you got time to debug their issue (if you even answer their support email) when they would have the ability to solve their problem themselves - if you hadn't made it intentionally hard by putting hurdles to understanding what's happening in their browser.

I see this annoying trend in desktop software too - while 15 years ago every decent software wrote a logfile, nowadays I often have to resort to reverse engineering just to gather logging data and understand why something doesn't work or crashes ("an error occurred" isn't helpful).

Collapse
princetegaton profile image
Prince Tegaton Author

I understand your point.. But error logs are totally different from debug step logs

Collapse
leob profile image
leob

In most cases I'm just temporarily adding "console.log" in lieu of using a debugger (which somehow I can never get used to when coding Javascript, while I ALWAYS use a debugger when working in PHP) ... once I've figured out how to get that piece of code working I immediately remove them (typically within an hour).

Collapse
baskarmib profile image
Baskarrao Dandlamudi

With the current Chrome browser we can make use of Logpoints in devtools. It works the same way as console.log for the front end.
developers.google.com/web/updates/...

Collapse
leob profile image
leob

Cool and interesting, but arguably more work than adding a console.log line in your source, and a big limitation is it won't work (or maybe it will?) with transpiled/bundled code (Babel, Webpack) ... ?

Collapse
rjulien profile image
r-julien

If(env === 'production') {
console.log = ()=>{};
}