Troubleshooting

Node.js agent API

New Relic offers several tools to help obtain the information needed to provide useful metrics about your Node.js application. These include:

Reading the route names (if used) from the Express and Restify routers

Using the API to name the current request, either with simple names or groups of controllers with actions

Support rules that are stored in your agent's configuration that can mark requests to be renamed or ignored based on regular expressions matched against the request's raw URLs (also available as API calls)

The number of names that New Relic tracks needs to be small enough so that the user experience is robust. It also needs to be large enough to provide the right amount of information (without overwhelming you with data) so that you can identify problem spots in your applications more easily.

Request names

The Node.js agent captures the HTTP method along with a potentially parameterized path (such as /user/:id) or a regular expression (such as /^/user/([-0-9a-f]+)$/). These pieces of information become part of the request name.

If you have support for slow transaction traces and have enabled capture_params in your config file, the transaction trace will also have the request's parameters and their values attached to it. If you are dissatisfied with the request names that the Node.js agent uses, you can use API calls to create more descriptive names.

If grouping your requests under the generic name, then /* is sufficient, and you do not need to customize your configuration file or API calls.

Requirements

New Relic uses request names to group requests for many charts and tables. The value of these visualizations will drop as the number of different request names increases.

For example, do not include potentially dynamic data like GUIDs, numerical IDs, or timestamps in the request names you create. If your request is slow enough to generate a transaction trace, that trace will contain the original URL. If you enable parameter capture, the parameters will also be attached to the trace.

Avoid having more than 50 different transaction names. For example, if you have more than a couple hundred different request names, rethink your naming strategy.

Avoid metric grouping issues

The request naming API helps New Relic avoid problems with trying to handle too many metrics, which sometimes is referred to as "metric explosion." New Relic has several strategies to deal with these issues; the most severe is simply to blacklist offending applications.

The main reason for you to be careful in using these request-naming tools is to prevent that from happening to your applications. For more information, see Metric grouping issues.

Guidelines

Define your configuration rules from the most specific to the most general. The first rules listed in your config file or added with the Node.js transaction naming API will be applied first and should be narrowly targeted. More general "fall-through" rules should be added toward the end of the list, because they will be evaluated in the order they were configured or added using the Node.js transaction naming API.

If the retailer reversed the order, the rules would catch all transactions in :customer, which would not be as useful.

Load the request naming API

Make sure that loading the New Relic module is the first thing your application does, as it needs to bootstrap itself before the rest of your application loads:

var newrelic = require('newrelic');

This returns the request naming API. You can safely require the module from multiple modules in your application, as it only initializes itself once.

Request API calls

Here is a summary of the Request API calls for New Relic's Node.js agent.

newrelic.setTransactionName(name)

Name the current request, following the request naming requirements. You can call this function anywhere within the context of an HTTP request handler, at any time after handling of the request has started, but before the request has finished. In general, if the request and response objects are in scope, you can set the name.

Explicitly calling newrelic.setTransactionName() will override any names set by Express or Restify routes. Also, calls to newrelic.setTransactionName() and newrelic.setControllerName() will overwrite each other. The last one to run before the request ends wins.

newrelic.setControllerName(name, [action])

Name the current request using a controller-style pattern, optionally including the current controller action. If the action is omitted, New Relic will include the HTTP method (GET, POST, etc.) as the action. The rules for when you can call newrelic.setControllerName() are the same as they are for newrelic.setTransactionName(), including the request naming requirements.

Explicitly calling newrelic.setControllerName() will override any names set by Express or Restify routes. Also, calls to newrelic.setTransactionName() and newrelic.setControllerName() will overwrite each other. The last one to run before the request ends wins.

Custom instrumentation API calls

The provided onRequire callback will be fired when the given module is loaded with require. The moduleName parameter should be the string that will be passed to require; for example, 'express' or 'amqplib/callback_api'. The optional onError callback is called if the onRequire parameters throws an error. This is useful for debugging your instrumentation.

Use this method to:

Add instrumentation for modules not currently instrumented by New Relic.

The url defines the transaction name and needs to be static. Do not include variable data such as user ID.

The handle defines the function you want to instrument.

New Relic will capture any metrics that would be captured by auto-instrumentation, as well as manual instrumentation via startSegment().

You must handle custom transactions manually by calling newrelic.getTransaction() at the start of your transaction, and then call transaction.end() when you are finished. New Relic begins timing the transaction when newrelic.startWebTransaction() is called and ends the transaction when transaction.end() is called. You can also return a promise to indicate the end of the transaction.

The handle defines a function that includes the entire background job you want to instrument.

New Relic will capture any metrics that would be captured by auto-instrumentation, as well as manual instrumentation via startSegment().

You must handle custom transactions manually by calling newrelic.getTransaction() at the start of your transaction, and then call transaction.end() when you are finished. New Relic begins timing the transaction when newrelic.startBackgroundTransaction() is called and ends the transaction when transaction.end() is called. You may also return a promise to indicate the end of the transaction.

newrelic.getTransaction()

Returns a handle on the currently executing transaction. This handle can then be used to interact with a given transaction safely from any context. It is best used with newrelic.startWebTransaction() and newrelic.startBackgroundTransaction().

Custom metrics API calls

Use recordMetric to record an event-based metric, usually associated with a particular duration. The name must be a string following standard metric naming rules. The value will usually be a number, but it can also be an object.

When value is a numeric value, it should represent the magnitude of a measurement associated with an event; for example, the duration for a particular method call.

When value is an object, it must contain count, total, min, max, and sumOfSquares keys, all with number values. This form is useful to aggregate metrics on your own and report them periodically; for example, from a setInterval. These values will be aggregated with any previously collected values for the same metric. The names of these keys match the names of the keys used by the platform API.

newrelic.incrementMetric(name, [amount])

Use incrementMetric to update a metric that acts as a simple counter. The count of the selected metric will be incremented by the specified amount, defaulting to 1.

Custom events API calls

Use these API calls to record additional Insights events:

newrelic.recordCustomEvent(eventType, attributes)

Use recordCustomEvent to record an event-based metric, usually associated with a particular duration.

The eventType must be an alphanumeric string less than 255 characters.

The attributes must be an object of key and value pairs. The keys must be shorter than 255 characters, and the values must be string, number, or boolean.

Transaction handle methods

This section details the methods provided by the TransactionHandle class instance that can be obtained through newrelic.getTransaction().

Use these methods to interact directly with the current transaction:

transactionHandle.end([callback])

Use transactionHandle.end to end the transaction referenced by the handle instance.

The callback is invoked when the transaction has fully ended. The finished transaction passed to the callback as the first argument.

transactionHandle.ignore()

Use transactionHandle.ignore to end the transaction referenced by the handle instance.

transactionHandle.acceptDistributedTracePayload is used to instrument the called service for inclusion in a distributed trace. It links the spans in a trace by accepting the payload generated by createDistributedTracePayload.

Other API calls

New Relic's Node.js agent includes additional API calls.

newrelic.addCustomAttribute(name, value)

Set a custom attribute value to be displayed along with the transaction trace in the New Relic UI. This must be called within the context of a transaction so it has a place to set the custom attributes. Custom attributes will appear in New Relic APM's transaction trace detail view and in errors for the transaction.

Set multiple custom attribute values to be displayed along with the transaction trace in the New Relic UI. The attributes should be passed as a single object. This must be called within the context of a transaction so it has a place to set the custom attributes. Custom attributes will appear in the transaction trace detail view and in errors for the transaction.

Returns the HTML snippet to be inserted into the header of HTML pages to enable New Relic Browser. The HTML will instruct the browser to fetch a small JavaScript file and start the page timer.

newrelic.setIgnoreTransaction(ignored)

Tell the module whether or not to ignore a given request. This allows you to explicitly filter long-polling, irrelevant routes or requests you know will be time-consuming. This also allows you to gather metrics for requests that otherwise would be ignored.

To ignore the transaction, set the parameter to true will ignore the transaction.

To prevent a transaction from being ignored with this function, pass the parameter false.

Passing null or undefined will not change whether the transaction is ignored.

newrelic.noticeError(error, [customParameters])

Use this call if your app is doing its own error handling with domains or try/catch clauses, but you want all of the information about how many errors are coming out of the app to be centrally managed. Unlike other Node.js calls, this can be used outside of route handlers, but it will have additional context if called from within transaction scope.

options.collectPendingData - type boolean - Tell the agent whether to send any pending data to the New Relic collector before shutting down.

options.timeout - type number (ms) - The default time before forcing a shutdown. When collectPendingData is true, the agent will wait for a connection before shutting down. This timeout is useful for short lived processes, like AWS Lambda, in order to keep the process from staying open too long, while trying to connect.

Rules for naming and ignoring requests

If you do not want to put calls to the New Relic module directly into your application code, you can use pattern-based rules to name requests. There are two sets of rules: one for renaming requests, and one to mark requests to be ignored by New Relic's instrumentation.

Here is the structure for rules in New Relic's Node.js agent.

rules.name

A list of rules of the format {pattern : "pattern", name : "name"} for matching incoming request URLs to pattern and naming the matching New Relic transaction's name. This acts as a regex replace, where you can set the pattern either as a string, or as a JavaScript regular expression literal, and both pattern and name are required.

When passing a regex as a string, escape backslashes, as the agent does not keep them when given as a string in a pattern. Define your configuration rules from the most specific to the most general, as the patterns will be evaluated in order and are terminal in nature. For more information, see the naming guidelines.

This can also be set with the environment variable NEW_RELIC_NAMING_RULES, with multiple rules passed in as a list of comma-delimited JSON object literals:

Optional rules attributes

Additional optional attributes are available:

Optional rules attributes

Description

terminate_chain

Default: true

When set to true (default), no further rules will be evaluated if this rule is a match. Setting this to false is useful when multiple rules should be used together. For example, one rule could be replacing a common pattern in many different URLs, while subsequent rule(s) would be more specific.

replace_all

Default: false

When set to true, all matches of the pattern will be replaced. Otherwise, only the first match will be replaced. Using the g flag with regular expression literal will have the same effect. For example:

pattern: '[0-9]+',
replace_all: true

This has the same effect as pattern: /[0-9]+/g.

precedence

By default the rules are evaluated in order, from first to last. If you prefer to have complete control over the order, you can give each rule a precedence attribute. The precedence is an integer number, and rules are evaluated in ascending order. If precedence is not explicitly defined, it will be set to 500 by default.

Additional attributes are ignored.

Testing your naming rules

The Node.js agent comes with a command-line tool for testing naming rules. For more information, run the following command in terminal window in a directory where your app is installed:

node node_modules/.bin/newrelic-naming-rules

Naming rule examples

Here are some examples of naming rules and the results.

Match full URL

pattern: "^/items/[0-9]+$",
name: "/items/:id"

will result in:

/items/123 => /items/:id
/orders/123 => /orders/123 (not replaced since the rule is a full match)

If you are using socket.io, you will have a use case for ignoring rules right out of the box. To keep socket.io long-polling from dominating your response-time metrics and affecting the Apdex metrics for your application, add a rule such as:

API calls for rules

Here are the API calls for naming and ignoring rules with New Relic's Node.js agent.

newrelic.addNamingRule(pattern, name)

Programmatic version of rules.name. Once naming rules are added, they cannot be removed until the Node process is restarted. They can also be added via the Node.js agent's configuration. Both parameters are required.

newrelic.addIgnoringRule(pattern)

Programmatic version of rules.ignore. Once ignoring rules are added, they cannot be removed until the Node process is restarted. They can also be added via the Node.js agent's configuration. This parameter is required.