Application Insights SDK for Node.js part 5 : Out of box telemetries - Exception, Performance and Live Metrics Stream
Tags: applicationinsights, azure, node
Published: 2020-01-27 02:40:43

---
title: Application Insights SDK for Node.js part 5 : Out of box telemetries - Exception, Performance and Live Metrics Stream
published: true
description: Take a deeper look into Application Insight SDK for Node.js
tags: applicationinsights,azure,nodejs
cover_image: https://azurecomcdn.azureedge.net/cvt-143af90d7db8d8220163967e056e9185e6a4b2273729389738a071b204137b5b/images/page/services/monitor/application-monitoring.png
---

In the [previous](https://dev.to/kenakamu/application-insights-sdk-for-node-js-part-4-out-of-box-telemetries-basics-and-console-361k) article, I looked into Application Insights out of box telemetries about how to start using them and console collector as first example.

In this article, I look into Exception and Performance

# Exception

I need to log whenever exceptions happened inside the application which terminates the application. [Exception](https://github.com/microsoft/ApplicationInsights-node.js/blob/develop/AutoCollection/Exceptions.ts) module uses process on following events to handle them.

- [UncaughtException](https://nodejs.org/api/process.html#process_event_uncaughtexception)
- [UnhandledRejection](https://nodejs.org/api/process.html#process_event_unhandledrejection)

One caveat is that framework such as Express swallowing (or handling) the exception nicely, which doesn't crash the application. This means most errors won't logged in Application Insights as it won't be reached to "UncaughtException".

One example I can break it is this. In the following endpoint, I get data from Azure Storage and it has own promise. If I raise an error inside the callback, then express cannot handle it and Application Insight caught it.

In this example, I use "res" object of tableSerivce and treat it as if res object in express get function. At a result, node.js cannot find "send" function in res object and crashed.

```javascript
app.get("/:p/:r", (req, res) => {
    tableService.retrieveEntity("mytable", req.params.p, req.params.r, (err, result, res) => {
        if (!err) {
            res.send(`${result.PartitionKey._} - ${result.RowKey._}`);
        } else {
            res.send("No data");
        }
    });
});
```

```shell
Debugger listening on ws://127.0.0.1:32350/75b11dd4-c65e-4093-9342-3170ec21812e
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
Waiting for the debugger to disconnect...
TypeError: res.send is not a function
    at c:\Users\kenakamu\Desktop\mynode\index.js:110:17
```

I see the exception is logged in Application Insights as well.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ii2jalxwbil5l09w9gez.jpg)

## How Application Insights does log when node.js crashes

When unhandledexception happens, node.js application will be shut down. process.on gives me some window to operate something important.

SDK uses following method in order.

```javascript
this._client.trackException({ exception: error });
this._client.flush({ isAppCrashing: true });
```

As I explained in the [first post](https://dev.to/kenakamu/application-insights-sdk-for-node-js-3ki1), Application Insights SDK has feature to flush cached data into disk. When **isAppCrashing** is true, then the **flush** function synchronously writes cache to the disk storage. It later pickup the log when the application start running.

So if I don't see the exception log in Application Insights, it could be following reasons:

- The application is still stop working so no one pickup the log
- The application is up and running but the log is not picked up yet
- SDK failed to flush log by some reason.

I usually wait several minutes after the application restart to see the log.

## Explicit Exception logging

As I said, framework such as Express handles exception nicely so that the application won't crash. However, as a developer, I should handle exception by myself as much as possible by using try catch appropriately and track exception by using SDK.

Simply call trackException like example below. (the sample comment clearly said when to use this as well :))

```javascript
client.trackException({exception: new Error("handled exceptions can be logged with this method")});
```
# Performance

[Performance.ts](https://github.com/microsoft/ApplicationInsights-node.js/blob/develop/AutoCollection/Performance.ts) module collects following metrics.

- CPU
- Memory
- Network
- DependencyRate
- ExceptionRate

Some of these counters will be auto collected when LiveMetricsCounter is enabled. The constructor has default parameters which affect the collection. 

- CollectionInteravl: one minutes by default
- EnableLiveMetricsCounters: false by default

```javascript
constructor(client: TelemetryClient, collectionInterval = 60000, enableLiveMetricsCounters = false) {
    if (!AutoCollectPerformance.INSTANCE) {
        AutoCollectPerformance.INSTANCE = this;
    }

    this._isInitialized = false;
    this._client = client;
    this._collectionInterval = collectionInterval;
    this._enableLiveMetricsCounters = enableLiveMetricsCounters;
}
```

When enable function is called from **start** or **setAutoCollectPerformance** function, Performance module set handlers for each metrics and call **setInterval** to collect them all.

## TrackMetric

One important thing to know about this module is that it uses **trackMetric** function to track data, which typically goes to **"Custom Metrics"** but if I specify one of performance counter name, then it automatically goes to **performanceCounters**.

For example, if I add code like below and call the endpoint,

```javascript
app.get("/cpu100", (req, res) => {
    client.trackMetric({name: "\\Processor(_Total)\\% Processor Time", value: 100});
    res.send("cpu100");
});

``` 

I can query the result not from customMetircs but from performanceCounters.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/0c6zpk1zayo2aco2nma0.jpg)

## Live Metric Stream

If I want to monitor the application (near) real-time, then I can use Live Metric Stream. I need to explicitly enable it as it's disabled by default as I explained above. By default, it doesn't show anything.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/rombbw3wz7ts29aouw3r.jpg)

I call **setSendLiveMetrics(true)** during setup.

```javascript
var appInsights = require("applicationinsights");
appInsights.setup("<instrumentation_key>")
    .setAutoCollectConsole(true, true)
    .setSendLiveMetrics(true)
    .start();
```

Once I restart the application and go back to Live Metric Stream, I can see live metrics from my application.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/hnavslyirc30hkclk42s.jpg)

## Native Performance

In addition to Performance, I can use [NativePerformance.ts](https://github.com/microsoft/ApplicationInsights-node.js/blob/develop/AutoCollection/NativePerformance.ts) module to track additional information such as:

- GarbageCollection
- EventLoop
- HeapUsage

These are very deep information when troubleshooting, which I can explicitly enable by calling **setAutoCollectPerformance** and pass true for second argument.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/xalunndigohp2tv2h003.jpg)

# Summary

Exception and Performance are very important when monitor and troubleshooting the  application. Live Metric is also nice to have when I need to watch it live!

I look into HttpRequests and HttpDependencies in next article.