Updating your Node.js Diagnostics Skills

Why should I care about diagnostic tools?

When there is a bug or a performance problem, you can spend considerable time chasing the issue if you are not familiar with diagnostics utilities. Those can help developers identify the root cause of any application anomaly sooner.

Diagnostic techniques and tools for

Node.js

There are plenty of tools allowing you to find anomalies in your Node.js application. The use of these tools depends mostly on the environment where you can run them. There are some included in the Node.js core, and there are others provided by the Node.js ecosystem.

At a Development environment

PRINTING DEBUGGING INFORMATION

When developing, the most straightforward but dirtiest way is to use a `console.log()` to print a message to display helpful info.

app.get((req, res) => {
   const rand = Math.round(Math.random() * (3000 - 1000)) + 1000
   console.log(`Response will be sent in ${rand} miliseconds`)
   setTimeout(() => {
     res.send('ok')
   }, rand)
 })

PRINTING DEBUGGING INFORMATION

A permanent and better approach is to use util.debuglog or debug:

 app.get((req, res) => {
  const rand = Math.round(Math.random() * (3000 - 1000)) + 1000
  debug(`Response will be sent in ${rand} miliseconds`)
  setTimeout(() => {
    res.send('ok')
  }, rand)
})

Analyzing program's flow

If you need to check your program flow, use node.js inspector:

$ node --inspect index.js
$ node --inspect-brk index.js

Or if you use VS Code, use the debugger

Debugging Node.js core operations

Use the environment variables `NODE_DEBUG` for JavaScript logging and `NODE_DEBUG_NATIVE` for C++ logging

$ NODE_DEBUG=http node index.js

Diagnosing the future of your application

To identify better warnings for your program and possible existing problems with your code:

$ node --trace-warnings index.js

To see any deprecations, code that will stop working eventually:

$ node --trace-deprecation index.js
$ node --throw-deprecation index.js

Trace more potential issues in your app

To see any potential I/O operations blocking your event loop, this could cause bad performance later when in production:

$ node --trace-sync-io index.js

Debug an application exiting silently:

$ node --trace-exit index.js

Capturing diagnostics reports

The report is intended for development, test, and production use, to capture and preserve information for problem determination.

 

It includes JavaScript and native stack traces, heap statistics, platform information, resource usage, etc.

 

 

$ node --report-on-fatalerror index.js
$ node --report-uncaught-exception index.js
$ node --report-on-signal index.js
$ node --report-signal=SIGINT index.js

At a staging or pre-production environment

What should I BE doing on staging?

Before taking your code to production, it is recommended to analyze its performance. It is essential to study the resources consumption, speed of your application, and edge cases. To do that, basically, you explore aspects like:

 

  • Time expended by your application to serve the user's request

  • Memory consumption of your application while being executed

  •  Possible edge cases, odd behaviors, and crashes

Load test your application pre-production

Load testing is performed to determine a system's behavior under both normal and anticipated peak load conditions. It helps to identify the maximum operating capacity of an application as well as any bottlenecks and determine which element is causing degradation.

 

Here are some tools to help you with the task:

CPU Profiling or analyzing how much time you expend

It is recommended to analyze how much time your application takes to perform the operations needed to provide your users' output.  That's possible thanks to a profiler, which is a tool that allows you to measure the time taken by any individual operation executed in your program.

 

The profiler's result could be just a bunch of text-mode measures, making it harder to analyze. The suggested way is to use a graphic representation. The most common is the flame graph outlining the CPU operations.

Flame graphs

Understanding a flame graph

The Flame Graph visualization shows the time along the x-axis. The y-axis is used to indicate the function calls that make up a particular stack trace, which eases identifying where your program is mostly expending the time and help to diagnose bottlenecks. The wider a rectangle, is more time being used by the operation it belongs to.

Heap snapshotting or analyzing the memory used

Heap Snapshots capture a record of all live JavaScript objects in your Node.js application available when the snapshot is captured. The objects are grouped by their constructor name, with aggregated counts of the total number of objects, their shallow size (memory held by the object itself), and their retained size (memory that is freed when the object itself is deleted along with its dependent objects)

Comparing heap snapshots to analyze

memory

Tracing events to analyze the execution

The Trace Event provides a mechanism to centralize tracing information generated by V8, Node.js core, and userspace code; basically, it records all the events in the execution.

 

We can capture the information of the specified events categories in the execution of every iteration of the test explained above. to accomplish that, we will execute the script for the regular baseline Node.js script like this

$ node --trace-event-categories=v8,node,node.async_hooks index.js

Tracing events to analyze the execution

Capturing performance assets
pre-production

These tools are mean to be used in local environments and not be used in production to capture and see performance assets:

 

At the production environment

What should I Do in production?

The main problem at production is that previous techniques and tools mentioned before are not suitable or impact the program performance, reaching the paradox that analyzing the performance affects the performance itself.

Another aspect is that you can not usually predict all scenarios your application will be used or the load you will receive, so you should monitor the situation.

Some existing Monitoring options

There are some tools providing info, metrics, and monitoring your application in production environments, usually APMs like:
 

 

These platforms are primarily designed to provide general information and not Node.js specific information and can not generate performance assets and beware; you will lose performance

Capturing performance assets in production

There is a tool specialized in Node.js metrics and custom Node.js monitoring, allowing you to capture performance assets at will or automatically to analyze in production without a considerable performance overhead

Capturing performance assets in production

Thanks

Updating your Node.js Diagnostics Skills

By Adrián Estrada

Updating your Node.js Diagnostics Skills

  • 844