Debugging is an important skill for every developer. Here’s how to quickly setup debugging for nodejs with free tools everyone has.
There are many fancy tools for debugging your application. Data dog, rookout, aspecto and sentry to name a few. They are all commercial solutions though. They cost money, and have their learning curve for new developers coming into the team.
There is a tool that almost every computer in the world has that can give you debugging and profiling capabilities for your nodejs applications: chrome dev tools.
When it comes to debugging nodejs applications, the first tool that comes to mind is the almighty `console.log`.
You just sprinkle your codebase with
console.log s in the right places, spin up your nodejs server and see the values of your objects at any given time.
But that’s a primitive way of debugging. More like logs reading… And what about profiling your application and checking memory usage and cpu consumption?
How to really debug a nodejs application?
With Chrome dev tools it’s very easy.
Let’s demo that. For this demo I’ll be using this repository: https://github.com/YonatanKra/nodejs-perf-demo
1. You can clone it and try along (don’t forget to
npm install after you clone it).
2. We start the application with the
node --inspect gc/gc-example.js
3. We head over to chrome and browse to
4. Inside, we should see our server running (see the Target section in the image below).
5. Click the
inspect link under the running process’s name and you should get to the nodejs chrome dev tools:
Once there, you can use the nodejs console, see the source files and add debug points, and profile the app’s memory or CPU usage.
How to add a debug point to a nodejs application?
We head over to the
Sources tab and hit Ctrl+P (or cmnd + p on Mac). This will allow you to search for your file. In my case, I’ll search for
After I open the file, I just set a debug point wherever I want. In this case, I’ll add it to the API entry point:
Because in my case, the server is running locally on port 8080, I can trigger my API using
curl like this:
Because our server is serving using the GET method, we could have reached the same effect by browsing to this URL. Sometimes you have a POST gateway to test, so you’d have to use
curl or tools like
Triggering the API will result in the code stopping at the breakpoint:
How to profile the CPU usage of a nodejs application?
For this part, we’ll head over to the Profiler tab:
We can click on the “Start” button or the small record button at the top left part and it will start recording our application.
We will use the
curl trick from above to trigger the code of our application and then click on the record button again or on the Stop button that replaced the start button:
Once we stop the recording, we will get to a flame chart of the recording:
A record item, named “Profile 1”, is created. If we record again, we’d have more than one recording and we can browse them using the left CPU profiles menu.
You can zoom in and see exactly what functions ran, how long it took every function to run, garbage collection instances etc.:
There’s much more information but that’s beyond the scope of this article.
How to profile the memory of a nodejs application?
Now we head over to the memory tab:
Explaining about it is a bit out of the scope of this article, but you can take a heap snapshot (what objects live in your app’s memory), track allocation of memory in your app and even what applications allocated how much memory.
With all of these tools you can easily solve memory issues – the most (in)famous of them is the dreadful memory leak. You can dig a bit deeper with this video.
How to debug multiple applications?
--inspect flag opens the debugging connection on
127.0.0.1:9229 as default. Trying to run two debugging instances will result in an error:
How to solve “address already in use” error when debugging nodejs?
In order to solve this, you can set the url and port when starting your debug session like this:
Doing that, will not show your app in the
chrome://inspect page automatically. There’s another step you need to do in order to make this work.
chrome://inspect page there’s a link to open the nodejs dedicated devtools:
This will open the dedicated devtools where you will have a Connection page:
Just click the “Add connection” button and add your debug url and port (the one you set when running the
How to debug and profile a nodejs app remotely?
All this is nice, and we can debug and profile the application when it is running locally. How about remotely?
In order for an app to be exposed to the world, you should expose it in the url
Serving your app through
0.0.0.0 exposes your server to everyone. This is highly insecure and blocked by most cloud vendors by default (and probably your devops team will object to that as well).
In order to get over this obstacle, you can leave the debug URL local (e.g.
127.0.0.1:<port>) like this:
and access the server via SSH tunnel like this:
ssh -L 9221:localhost:9230 [email protected]
You would usually be prompted for a password or use a key file (
pem) in order to access the machine, but your computer will have access to the machine’s
localhost just as if you debug it locally.
Chrome dev tools have
localhost:9221 set up by default. If you are using a different port, just set it up in the connection page.
Debugging is a necessary phase in the development process. No matter how many tests you write, and how many years of experience you have – solving a bug will require a kind of debugging (I usually debug the code when running the tests).
Using the knowledge in this article, you can now debug nodejs applications using chrome dev tools. More than that – you can profile your applications and solve performance issues. If you want to read more about profiling JS applications click here. You can browse the performance category to see more related articles.
Remote debugging is rarely needed in my experience, but chrome dev tools allows you that as well by connecting to remote servers via the Connection tab.
Thanks a lot to Yuval Bar Levi and Miki Ezra Stanger the kind and thorough review!