UNPKG

20.6 kBMarkdownView Raw
1# Application Insights for Node.js
2
3[![npm version](https://badge.fury.io/js/applicationinsights.svg)](http://badge.fury.io/js/applicationinsights)
4[![Build Status](https://travis-ci.org/Microsoft/ApplicationInsights-node.js.svg?branch=master)](https://travis-ci.org/Microsoft/ApplicationInsights-node.js)
5
6[Azure Application Insights][] monitors your backend services and components after
7you deploy them to help you [discover and rapidly diagnose performance and other
8issues][]. Add this SDK to your Node.js services to include deep info about Node.js
9processes and their external dependencies such as database and cache services.
10You can use this SDK for your Node.js services hosted anywhere: your datacenter,
11Azure VMs and Web Apps, and even other public clouds.
12
13[Azure Application Insights]: https://azure.microsoft.com/documentation/articles/app-insights-overview/
14[discover and rapidly diagnose performance and other issues]: https://docs.microsoft.com/azure/application-insights/app-insights-detect-triage-diagnose
15
16This library tracks the following out-of-the-box:
17- Incoming and outgoing HTTP requests
18- Important system metrics such as CPU usage
19- Unhandled exceptions
20- Events from many popular third-party libraries ([see Automatic third-party instrumentation](#automatic-third-party-instrumentation))
21
22You can manually track more aspects of your app and system using the API described in the
23[Track custom telemetry](#track-custom-telemetry) section.
24
25## Getting Started
26
271. Create an Application Insights resource in Azure by following [these instructions][].
282. Grab the _Instrumentation Key_ (aka "ikey") from the resource you created in
29 step 1. Later, you'll either add it to your app's environment variables or
30 use it directly in your scripts.
313. Add the Application Insights Node.js SDK to your app's dependencies and
32 package.json:
33 ```bash
34 npm install --save applicationinsights
35 ```
36 > *Note:* If you're using TypeScript, do not install a separate "typings" package.
37 > This NPM package contains built-in typings.
384. As early as possible in your app's code, load the Application Insights
39 package:
40 ```javascript
41 let appInsights = require('applicationinsights');
42 ```
435. Configure the local SDK by calling `appInsights.setup('_your_ikey_');`, using
44 the ikey you grabbed in step 2. Or put this ikey in the
45 `APPINSIGHTS_INSTRUMENTATIONKEY` environment variable and call
46 `appInsights.setup()` without parameters.
47 > For more configuration options see below.
486. Finally, start automatically collecting and sending data by calling
49 `appInsights.start();`.
50
51[these instructions]: https://docs.microsoft.com/azure/application-insights/app-insights-nodejs
52
53
54## Basic Usage
55
56For out-of-the-box collection of HTTP requests, popular third-party library events,
57unhandled exceptions, and system metrics:
58
59```javascript
60let appInsights = require("applicationinsights");
61appInsights.setup("_your_ikey_").start();
62```
63
64* If the instrumentation key is set in the environment variable
65 APPINSIGHTS\_INSTRUMENTATIONKEY, `.setup()` can be called with no
66 arguments. This makes it easy to use different ikeys for different
67 environments.
68
69Load the Application Insights library (i.e. `require("applicationinsights")`) as
70early as possible in your scripts, before loading other packages. This is needed
71so that the Application Insights libary can prepare later packages for tracking.
72If you encounter conflicts with other libraries doing similar preparation, try
73loading the Application Insights library after those.
74
75Because of the way JavaScript handles callbacks, additional work is necessary to
76track a request across external dependencies and later callbacks. By default
77this additional tracking is enabled; disable it by calling
78`setAutoDependencyCorrelation(false)` as described in the
79Configuration section below.
80
81## Migrating from versions prior to 0.22
82
83There are breaking changes between releases prior to version 0.22 and after. These
84changes are designed to bring consistency with other Application Insights SDKs and
85allow future extensibility. Please review this README for new method and property names.
86
87In general, you can migrate with the following:
88- Replace references to `appInsights.client` with `appInsights.defaultClient`
89- Replace references to `appInsights.getClient()` with `new appInsights.TelemetryClient()`
90- Replace all arguments to client.track* methods with a single object containing named
91properties as arguments. See your IDE's built-in type hinting, or [TelemetryTypes](https://github.com/Microsoft/ApplicationInsights-node.js/tree/develop/Declarations/Contracts/TelemetryTypes), for
92the expected object for each type of telemetry.
93
94If you access SDK configuration functions without chaining them to `appInsights.setup()`,
95you can now find these functions at appInsights.Configuration
96(eg. `appInsights.Configuration.setAutoCollectDependencies(true)`).
97Take care to review the changes to the default configuration in the next section.
98
99## Configuration
100
101The appInsights object provides a number of configuration methods. They are
102listed in the following snippet with their default values.
103
104```javascript
105let appInsights = require("applicationinsights");
106appInsights.setup("<instrumentation_key>")
107 .setAutoDependencyCorrelation(true)
108 .setAutoCollectRequests(true)
109 .setAutoCollectPerformance(true)
110 .setAutoCollectExceptions(true)
111 .setAutoCollectDependencies(true)
112 .setAutoCollectConsole(true)
113 .setUseDiskRetryCaching(true)
114 .start();
115```
116
117Please review their descriptions in your IDE's built-in type hinting, or [applicationinsights.ts](https://github.com/Microsoft/ApplicationInsights-node.js/tree/develop/applicationinsights.ts) for
118detailed information on what these control, and optional secondary arguments.
119
120Note that by default `setAutoCollectConsole` is configured to *exclude* calls to `console.log`
121(and other `console` methods). By default, only calls to supported third-party loggers
122(e.g. `winston`, `bunyan`) will be collected. You can change this behavior to *include* calls
123to `console` methods by using `setAutoCollectConsole(true, true)`.
124
125### Sampling
126
127By default, the SDK will send all collected data to the Application Insights service. If you collect a lot of data, you might want to enable sampling to reduce the amount of data sent. Set the `samplingPercentage` field on the Config object of a Client to accomplish this. Setting `samplingPercentage` to 100 (the default) means all data will be sent, and 0 means nothing will be sent.
128
129If you are using automatic correlation, all data associated with a single request will be included or excluded as a unit.
130
131Add code such as the following to enable sampling:
132
133```javascript
134const appInsights = require("applicationinsights");
135appInsights.setup("<instrumentation_key>");
136appInsights.defaultClient.config.samplingPercentage = 33; // 33% of all telemetry will be sent to Application Insights
137appInsights.start();
138```
139
140### Multiple roles for multi-component applications
141
142If your application consists of multiple components that you wish to instrument all with the same Instrumentation Key and still see these components as separate units in the Portal as if they were using separate Instrumentation Keys (for example, as separate nodes on the Application Map) you may need to manually configure the RoleName field to distinguish one component's telemetry from other components sending data to your Application Insights resource. (See [Monitor multi-component applications with Application Insights (preview)](https://docs.microsoft.com/azure/application-insights/app-insights-monitor-multi-role-apps))
143
144Use the following to set the RoleName field:
145
146```javascript
147const appInsights = require("applicationinsights");
148appInsights.setup("<instrumentation_key>");
149appInsights.defaultClient.context.tags[appInsights.defaultClient.context.keys.cloudRole] = "MyRoleName";
150appInsights.start();
151```
152
153### Automatic third-party instrumentation
154
155In order to track context across asynchronous calls, some changes are required in third party libraries such as mongodb and redis.
156By default ApplicationInsights will use [`diagnostic-channel-publishers`](https://github.com/Microsoft/node-diagnostic-channel/tree/master/src/diagnostic-channel-publishers)
157to monkey-patch some of these libraries.
158This can be disabled by setting the `APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL` environment variable. Note that by setting that
159environment variable, events may no longer be correctly associated with the right operation. Individual monkey-patches can be
160disabled by setting the `APPLICATION_INSIGHTS_NO_PATCH_MODULES` environment variable to a comma separated list of packages to
161disable, e.g. `APPLICATION_INSIGHTS_NO_PATCH_MODULES=console,redis` to avoid patching the `console` and `redis` packages.
162
163Currently there are 9 packages which are instrumented: `bunyan`, `console`, `mongodb`, `mongodb-core`, `mysql`, `redis`, `winston`,
164`pg`, and `pg-pool`. Visit the [diagnostic-channel-publishers' README](https://github.com/Microsoft/node-diagnostic-channel/blob/master/src/diagnostic-channel-publishers/README.md)
165for information about exactly which versions of these packages are patched.
166
167The `bunyan`, `winston`, and `console` patches will generate Application Insights Trace events based on whether `setAutoCollectConsole` is enabled.
168The rest will generate Application Insights Dependency events based on whether `setAutoCollectDependencies` is enabled.
169
170## Track custom telemetry
171
172You can track any request, event, metric or exception using the Application
173Insights client. Examples follow:
174
175```javascript
176let appInsights = require("applicationinsights");
177appInsights.setup().start(); // assuming ikey in env var. start() can be omitted to disable any non-custom data
178let client = appInsights.defaultClient;
179client.trackEvent({name: "my custom event", properties: {customProperty: "custom property value"}});
180client.trackException({exception: new Error("handled exceptions can be logged with this method")});
181client.trackMetric({name: "custom metric", value: 3});
182client.trackTrace({message: "trace message"});
183client.trackDependency({target:"http://dbname", name:"select customers proc", data:"SELECT * FROM Customers", duration:231, resultCode:0, success: true, dependencyTypeName: "ZSQL"});
184client.trackRequest({name:"GET /customers", url:"http://myserver/customers", duration:309, resultCode:200, success:true});
185
186let http = require("http");
187http.createServer( (req, res) => {
188 client.trackNodeHttpRequest({request: req, response: res}); // Place at the beginning of your request handler
189});
190```
191
192An example utility using `trackMetric` to measure how long event loop scheduling takes:
193
194```javascript
195function startMeasuringEventLoop() {
196 var startTime = process.hrtime();
197 var sampleSum = 0;
198 var sampleCount = 0;
199
200 // Measure event loop scheduling delay
201 setInterval(() => {
202 var elapsed = process.hrtime(startTime);
203 sampleSum += elapsed[0] * 1e9 + elapsed[1];
204 sampleCount++;
205 }, 0);
206
207 // Report custom metric every second
208 setInterval(() => {
209 var samples = sampleSum;
210 var count = sampleCount;
211 sampleSum = 0;
212 sampleCount = 0;
213
214 if (count > 0) {
215 var avgNs = samples / count;
216 var avgMs = Math.round(avgNs / 1e6);
217 client.trackMetric({name: "Event Loop Delay", value: avgMs});
218 }
219 }, 1000);
220}
221```
222
223## Preprocess data with Telemetry Processors
224
225```javascript
226public addTelemetryProcessor(telemetryProcessor: (envelope: Contracts.Envelope, context: { http.RequestOptions, http.ClientRequest, http.ClientResponse, correlationContext }) => boolean)
227```
228
229You can process and filter collected data before it is sent for retention using
230_Telemetry Processors_. Telemetry processors are called one by one in the
231order they were added before the telemetry item is sent to the cloud.
232
233If a telemetry processor returns false that telemetry item will not be sent.
234
235All telemetry processors receive the telemetry data and its envelope to inspect and
236modify. They also receive a context object. The contents of this object is defined by
237the `contextObjects` parameter when calling a track method for manually tracked telemetry.
238For automatically collected telemetry, this object is filled with available request information
239and the persistent request context as provided by `appInsights.getCorrelationContext()` (if
240automatic dependency correlation is enabled).
241
242The TypeScript type for a telemetry processor is:
243
244```typescript
245telemetryProcessor: (envelope: ContractsModule.Contracts.Envelope, context: { http.RequestOptions, http.ClientRequest, http.ClientResponse, correlationContext }) => boolean;
246```
247
248For example, a processor that removes stack trace data from exceptions might be
249written and added as follows:
250
251```javascript
252function removeStackTraces ( envelope, context ) {
253 if (envelope.data.baseType === "Microsoft.ApplicationInsights.ExceptionData") {
254 var data = envelope.data.baseData;
255 if (data.exceptions && data.exceptions.length > 0) {
256 for (var i = 0; i < data.exceptions.length; i++) {
257 var exception = data.exceptions[i];
258 exception.parsedStack = null;
259 exception.hasFullStack = false;
260 }
261 }
262 }
263 return true;
264}
265
266appInsights.defaultClient.addTelemetryProcessor(removeStackTraces);
267```
268
269More info on the telemetry API is available in [the docs][].
270
271[the docs]: https://azure.microsoft.com/documentation/articles/app-insights-api-custom-events-metrics/
272
273## Use multiple instrumentation keys
274
275You can create multiple Azure Application Insights resources and send different
276data to each by using their respective instrumentation keys ("ikey"). For
277example:
278
279```javascript
280let appInsights = require("applicationinsights");
281
282// configure auto-collection under one ikey
283appInsights.setup("_ikey-A_").start();
284
285// track some events manually under another ikey
286let otherClient = new appInsights.TelemetryClient("_ikey-B_");
287otherClient.trackEvent({name: "my custom event"});
288```
289
290## Examples
291
292* Track dependencies
293
294 ```javascript
295 let appInsights = require("applicationinsights");
296 let client = new appInsights.TelemetryClient();
297
298 var success = false;
299 let startTime = Date.now();
300 // execute dependency call here....
301 let duration = Date.now() - startTime;
302 success = true;
303
304 client.trackDependency({target:"http://dbname", name:"select customers proc", data:"SELECT * FROM Customers", duration:duration, resultCode:0, success: true, dependencyTypeName: "ZSQL"});
305 ```
306
307* Assign custom properties to be included with all events
308
309 ```javascript
310 appInsights.defaultClient.commonProperties = {
311 environment: process.env.SOME_ENV_VARIABLE
312 };
313 ```
314
315* Manually track all HTTP GET requests
316
317 Note that all requests are tracked by default. To disable automatic
318 collection, call `.setAutoCollectRequests(false)` before calling `start()`.
319
320 ```javascript
321 appInsights.defaultClient.trackRequest({name:"GET /customers", url:"http://myserver/customers", duration:309, resultCode:200, success:true});
322 ```
323 Alternatively you can track requests using ```trackNodeHttpRequest``` method:
324
325 ```javascript
326 var server = http.createServer((req, res) => {
327 if ( req.method === "GET" ) {
328 appInsights.defaultClient.trackNodeHttpRequest({request:req, response:res});
329 }
330 // other work here....
331 res.end();
332 });
333 ```
334
335* Track server startup time
336
337 ```javascript
338 let start = Date.now();
339 server.on("listening", () => {
340 let duration = Date.now() - start;
341 appInsights.defaultClient.trackMetric({name: "server startup time", value: duration});
342 });
343 ```
344
345## Advanced configuration options
346The Client object contains a `config` property with many optional settings for
347advanced scenarios. These can be set as follows:
348```
349client.config.PROPERTYNAME = VALUE;
350```
351These properties are client specific, so you can configure `appInsights.defaultClient`
352separately from clients created with `new appInsights.TelemetryClient()`.
353
354| Property | Description |
355| ------------------------------- |------------------------------------------------------------------------------------------------------------|
356| instrumentationKey | An identifier for your Application Insights resource |
357| endpointUrl | The ingestion endpoint to send telemetry payloads to |
358| proxyHttpUrl | A proxy server for SDK HTTP traffic (Optional, Default pulled from `http_proxy` environment variable) |
359| proxyHttpsUrl | A proxy server for SDK HTTPS traffic (Optional, Default pulled from `https_proxy` environment variable) |
360| httpAgent | An http.Agent to use for SDK HTTP traffic (Optional, Default undefined) |
361| httpsAgent | An https.Agent to use for SDK HTTPS traffic (Optional, Default undefined) |
362| maxBatchSize | The maximum number of telemetry items to include in a payload to the ingestion endpoint (Default `250`) |
363| maxBatchIntervalMs | The maximum amount of time to wait to for a payload to reach maxBatchSize (Default `15000`) |
364| disableAppInsights | A flag indicating if telemetry transmission is disabled (Default `false`) |
365| samplingPercentage | The percentage of telemetry items tracked that should be transmitted (Default `100`) |
366| correlationIdRetryIntervalMs | The time to wait before retrying to retrieve the id for cross-component correlation (Default `30000`) |
367| correlationHeaderExcludedDomains| A list of domains to exclude from cross-component correlation header injection (Default See [Config.ts][]) |
368
369[Config.ts]: https://github.com/Microsoft/ApplicationInsights-node.js/blob/develop/Library/Config.ts
370
371## Branches
372
373- Ongoing development takes place on the [develop][] branch. **Please submit
374 pull requests to this branch.**
375- Releases are merged to the [master][] branch and published to [npm][].
376
377[master]: https://github.com/Microsoft/ApplicationInsights-node.js/tree/master
378[develop]: https://github.com/Microsoft/ApplicationInsights-node.js/tree/develop
379[npm]: https://www.npmjs.com/package/applicationinsights
380
381## Links
382
383* [ApplicationInsights-Home][] is our central repo for libraries and info for
384 all languages and platforms.
385* Follow the latest Application Insights changes and announcements on the
386 [ApplicationInsights-Announcements][] repo.
387* [SDK Release Schedule][]
388
389[ApplicationInsights-Announcements]: https://github.com/Microsoft/ApplicationInsights-Announcements
390[ApplicationInsights-Home]: https://github.com/Microsoft/ApplicationInsights-Home
391[SDK Release Schedule]: https://github.com/Microsoft/ApplicationInsights-Home/wiki/SDK-Release-Schedule
392
393## Contributing
394
3951. Install all dependencies with `npm install`.
3962. Set an environment variable to your instrumentation key (optional).
397 ```bash
398 // windows
399 set APPINSIGHTS_INSTRUMENTATIONKEY=<insert_your_instrumentation_key_here>
400 // linux/macos
401 export APPINSIGHTS_INSTRUMENTATIONKEY=<insert_your_instrumentation_key_here>
402 ```
4033. Run tests
404 ```bash
405 npm run test
406 npm run backcompattest
407 npm run functionaltest
408 ```
409 _Note: Functional tests require Docker_
410
411---
412
413This project has adopted the [Microsoft Open Source Code of Conduct][]. For more
414information see the [Code of Conduct FAQ][] or contact
415[opencode@microsoft.com][] with any additional questions or comments.
416
417[Microsoft Open Source Code of Conduct]: https://opensource.microsoft.com/codeofconduct/
418[Code of Conduct FAQ]: https://opensource.microsoft.com/codeofconduct/faq/
419[opencode@microsoft.com]: mailto:opencode@microsoft.com