Level up your JavaScript browser logs with these console.log() tips


Level up your JavaScript browser logs with these console.log() tips

Ask any backend or frontend software engineer, and most of them will tell you, that a large part of their professional life is basically spent debugging, monitoring, and troubleshooting the apps they’ve created. It’s not that all of them are bad experts and constantly need to keep a watchful eye on their creations.

Software development as it is builds on the premise that software will fail. That being said, the basic difference between a greenhorn developer and an experienced one is how they prepare and plan for said failures.

One effective way to prepare for everything is continuous logging. It helps enormously when you’re planning for failure and eventual mitigation. On the other hand, regular logging can help with the frontend development tasks as well, however, it goes even much further than just a simple debugging and troubleshooting countermeasure. Effective logging can make the entire development experience faster, more fun, and more productive.

While most experts will agree that proper and diligent test-driven development is the way to go, the vast majority of them will also attest that the flexibility and the richness of information and code that can be achieved through the effective use of console.log() can also make a world of a difference. Great frontend logging practices can go a long way in improving the overall workflow and quality of the development cycle. With the tips and tricks, we’re about to share with you, you can debug your projects on the fly, while you’re in the development cycle, but they will also help you a great deal long after you’re done with the app but it’s not working as it’s supposed to.

 

Tips During the Development Cycle

 

Don’t use console.log()

This might sound a bit crazy, given the actual topic we’re talking about. However, instead of using console.log(), you can always use console. trace() as well to see what’s going on with your app. It does everything the log-route does and it also outputs the entire stack trace. When a message starts emitting, you’ll know exactly where from.

 

To identify your objects and avoid variable name confusion, use ES6s computed property names

This should be quite self-explanatory. Use the ES6’s computed property syntax and wrap your preferred objects you want to log inside console.log() – i.e. use console.log({user}) vs console.log(user).

They will be neatly logged in the variable name set as the value, and as the key as the object itself. This can be incredibly useful when you want to log several objects in the same log command because you’re in a hurry.

 

Give error, warn, and info (tiered log levels) a try

The console.log(param)by default, will log at the INFO level. On the other hand, you also have three other levels you can use. These are consoles.debug(), console.warn()and console.error(). Apart from the formatting differences, the browser’s developer console also allows you to filter out logs at different levels.

For lists and items, use the console.table()

Should we say more? If you ever find yourself in a situation where you need to log a list or an item, give this command a try.

 

Embrace the Debugger

Instead of going looking for your file in the developer console to add a breakpoint, why not shave off a few seconds, why not just drop a debugger in your code to stop execution when the actual line is being executed? After doing this, you can step over/into functions and debug them as you otherwise would.

 

Granular performance profiling with console.profile()and console.time()

If you wish to profile an exact user flow in your app to help you find hot spots easier, you can trigger console. profile(profileName) at the start of the action, and console.profileEnd(profileName) at the end, to make your life easier and inspect the CPU profile for the flow.

Also, you can see how long the flow takes with triggering the console.time(id)at the beginning, and console.timeEnd(id)at the end.

 

Use the console.count() for counting labelled executions

You might not find any actual good use for this, however, if you need it, it’s here. This command can help you know exactly how many times a piece of your code gets executed. In the case of eliminating race conditions and other similar scenarios, it can come incredibly handy.

 

code on a laptop screen

Image source: James Harrison via Unsplash

Logging with CSS

You can make good use of format strings to format your log messages. The %c is the placeholder for your CSS styles and anything after will be your message.

Apart from this, you can also style several elements if you extend the format string to include %s for string parameters.

While these are more cosmetic tricks, having a nice-looking log with nicely separated and easy-to-follow debug and info logs can clearly go a long way, especially when you have to revisit an app to deal with unexpected failures.

 

Logging for the long haul with console.log()

When we’re talking about frontend code production, there are several things you have to be ready with before handing over your final product. Things like generating cacheable asset digests, removing logs, and compressing your code. Why? Simply put, you don’t want your users to have to go into the developer console solely just to interact with your app. On the other hand, if your logs remain in the console, you open holes for security breaches.

Also. you want to oversee every little detail within your app to make sure it runs perfectly, and if it does not, at least, get notifications when your users encounter errors. In order to find and squish bugs as fast as possible, here are a couple of things you can to do pull them off.

 

Don’t use console.log()

Instead, give writing a wrapper class a try that also includes logic for conditionally logging based on the log level based set on a global variable by the backend. Wow, that’s a handful.

Warning, if you take this route, you’ll see TypeScript code snippets, so if you’re not really familiar with them, think of TypeScript as a superset of JS with types tacked on: const str = “some string”; becomes const str: string = “some string” – types are added after a variable followed by a semicolon.

 

Have the backend set your log level in order to protect your logs

You can have your apps configured to turn on debug level logging by default for admin users. You just need a JavaScript variable that is set by the backend.

You will see that some users will be quite handy and set these flags in the dev console to turn on granular logging, in most cases, you’ll be better off with this than having every log exposed to every user in the app by default, or getting all your logging completely removed from your app.

Set in a Ruby on Rails view:

 const logLevel: number = <%= @app.get_log_level_for_user %>

And in the Logger class:

class Logger {

   …

   …

   static info(…) {

     shouldLog(Level.INFO) && console.log(…);

        …

   }

}

Log on actionable errors (and notify as well)

This one’s also quite self-explanatory. You want to be notified whenever your users encounter an error, but you don’t necessarily want to output logs to the developer console. If this is what you’re after, you can do this by including a call to pipe the errors to a third-party APM service in the logger’s error function.

class Logger {

   …

   …

   static error(e) {

     if (shouldLog(Level.ERROR)) {

       console.error(e);

     }

     appsignal.sendError(e);

   }

}

You’ll see that there are a lot of third-party solutions that include different integrations to pipe your errors to outbound notifications services. Some of them can even be hooked up with project management tools to automatically create bugs and notifications for your team.


Finishing Thoughts

Hopefully, these few tips will help you both during the development cycle and in the long haul as well. While this is obviously just the tip of the iceberg when it comes to logging, implementing these simple steps can make the entire development process faster, more creative, and fun, not to mention, it can also help you a great deal with app maintenance down the road.


Learn more:

Szabolcs Szecsei
facebook
twitter
google
pinterest