loading...
Cover image for Application Insights SDK for Node.js part 6 : Out of box telemetries - HttpRequests and HttpDependencies

Application Insights SDK for Node.js part 6 : Out of box telemetries - HttpRequests and HttpDependencies

kenakamu profile image Kenichiro Nakamura ・4 min read

In the previous article, I looked into Exception and Performance modules of Application Insights out of box telemetries.

In this article, I look into HttpRequests and HttpDependencies which are heart of Web Applications.

HttpRequests

HttpRequests.ts module collect http requests information which is most basic information I need to collect.

It's enabled by default and there are two main feature to enable. The below code is taken from applicationInsights.ts. It enables correlation and then enable HttpRequests module.

export function start() {
    ...
        _serverRequests.useAutoCorrelation(_isCorrelating, _forceClsHooked);
        _serverRequests.enable(_isRequests);
    ...
    return Configuration;
}

The reason why auto correlation is required is written in a comment in enable function.

Autocorrelation requires automatic monitoring of incoming server requests. Disabling autocollection but enabling autocorrelation will still enable request monitoring but will not produce request events

The module basically wraps http/https server with its own and track it to Application Insights. It's done at initialize function and I see the comment says below.

The http.createServer function will instantiate a new http.Server object.
Inside the Server's constructor, it is using addListener to register the onRequest handler. So there are two ways to inject the wrapped onRequest handler:
1) Overwrite Server.prototype.addListener (and .on()) globally and not patching the http.createServer call. Or
2) Overwrite the http.createServer method and add a patched addListener to the fresh server instance.

When the request comes in, the injected code is called, which calls two main functions which track request.

  • trackRequest: Start tracking by checking several things including request detail and setup endRequest function when either request finish processing or endup error.
  • endRequest: Called once the request has been successfully processed or failed. Parse the request depending on the result and track it by trackRequest function.

Query request log

I can see the results by querying requests.
Alt Text
I can also see the results by using chart. Following chart shows which endpoint I accessed by using Pie chart, name and itemCount.
Alt Text

HttpDependencies

HttpDependencies.ts module tracks application dependencies. My application depends on Azure Storage Table and SDK track it automatically. This is the main module to create Application map diagram.

Track Http/Https dependency

The module uses http.request and https.request to wrap the outgoing requests to track the dependency. It also wrap get requests for to support older version of node.js.

// On node >= v0.11.12 and < 9.0 (excluding 8.9.0) https.request just calls http.request (with additional options).
// On node < 0.11.12, 8.9.0, and 9.0 > https.request is handled separately
// Patch both and leave a flag to not double-count on versions that just call through
// We add the flag to both http and https to protect against strange double collection in other scenarios
http.request = (options, ...requestArgs: any[]) => {
    const request: http.ClientRequest = originalRequest.call(http, options, ...requestArgs);
    clientRequestPatch(request, options);
    return request;
};

https.request = (options, ...requestArgs: any[]) => {
    const request: http.ClientRequest = originalHttpsRequest.call(https, options, ...requestArgs);
    clientRequestPatch(request, options);
    return request;
};

// Node 8 calls http.request from http.get using a local reference!
// We have to patch .get manually in this case and can't just assume request is enough
// We have to replace the entire method in this case. We can't call the original.
// This is because calling the original will give us no chance to set headers as it internally does .end().
http.get = (options, ...requestArgs: any[]) => {
    const request: http.ClientRequest = http.request.call(http, options, ...requestArgs);
    request.end();
    return request;
};
https.get = (options, ...requestArgs: any[]) => {
    const request: http.ClientRequest = https.request.call(https, options, ...requestArgs);
    request.end();
    return request;
};

Track other dependency

The module support following databases for detail tracking.

  • mongo
  • mysql
  • redis
  • postgres

The way it tracks is very similar how Console modules works. See Diagnostic Channel Publishers for more detail.

Application Dashboard

One way to fully take advantage of these logs is to use "Application Dashboard", which is Azure dashboard for Application Insights.

I can access it from Overview menu.
Alt Text

The dashboard contains many useful charts to monitor and analyze the application. I can change several settings on the top.

  • Refresh rate
  • Period
  • Adding additional filters. Alt Text

I can also customize the dashboard or create new one from this.

Summary

For me, HttpRequests and HttpDependencies modules are mandatory for any web application whenever I use Application Insights as it's used in other features too.

This is the end of the Application Insights SDK for Node.js series and I hope I could provide some useful information for others.

Discussion

pic
Editor guide