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.

For more information, see the Node.js agent configuration documentation and the Node.js agent API documentation on Github.

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.

Example: URL pattern matching

An online retailer has a URL pattern like this:

/user/customers/all/prospects
/user/customers/all/current
/user/customers/all/returning
/user/customers/John
/user/customers/Jane

The retailer could create rules like this:

// newrelic.js
exports.config={
  //other configuration
  rules:{
    name:[
      { pattern: "/user/customers/all/prospects/", name: "/user/customers/all/prospects" },
      { pattern: "/user/customers/all/.*", name: "/user/customers/all" },
      { pattern: "/user/customers/.*", name: "/user/customers/:customer" }
    ]
  }
}

With these rules, the retailer would create three transaction names:

  • /user/customers/:customer
  • /user/customers/all
  • /user/customers/all/prospects

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

Use these API calls to expand your instrumentation with custom instrumentation.

newrelic.instrument(moduleName, onRequire [, onError])

Sets an instrumentation callback for a specific module.

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.
  • Instrument your own code.
  • Replace the Node.js agent's built-in instrumentation with your own.

For more information, see New Relic's Node.js instrumentation tutorial on Github.

newrelic.instrumentDatastore(moduleName, onRequire [, onError])

Sets an instrumentation callback for a datastore module.

This method is just like newrelic.instrument(), except it provides a datastore-specialized shim. For more information, see New Relic's Node.js datastore instrumentation tutorial on Github.

newrelic.instrumentMessages(moduleName, onRequire [, onError])

Sets an instrumentation callback for a message service client module.

This method is just like newrelic.instrument(), except it provides a message-service-specialized shim. For more information, see New Relic's Node.js message service instrumentation tutorial on Github.

newrelic.instrumentWebframework(moduleName, onRequire [, onError])

Sets an instrumentation callback for a web framework module.

This method is just like newrelic.instrument(), except it provides a web-framework-specialized shim. For more information, see New Relic's Node.js web framework instrumentation tutorial on Github.

newrelic.startWebTransaction(url, handle)

Instrument the specified web transaction. Using this API call, you can instrument transactions that New Relic does not automatically detect.

  • 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 createTracer().

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.

newrelic.startBackgroundTransaction(name, [group], handle)

Instrument the specified background transaction. Using this API call, you can expand New Relic's instrumentation to capture data from background transactions.

  • The name defines the transaction name and needs to be static. Do not include variable data such as user ID.
  • The group is optional, and it allows you to group similar jobs together via the transaction type in the user interface. Like name, the group needs to be static.
  • 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 createTracer().

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 end or ignore a given transaction safely from any context. It is best used with newrelic.startWebTransaction() and newrelic.startBackgroundTransaction().

newrelic.endTransaction()

End the current web or background custom transaction. This method requires being in the correct transaction context when called. This API call takes no arguments.

newrelic.createTracer(name, callback)

Instrument a particular callback to improve visibility into a transaction. Use this API call to improve instrumentation of a particular method, or to track work across asynchronous boundaries by calling createTracer() in both the target function and its parent asynchronous function.

  • The name defines a name for the tracer. This name will be visible in transaction traces and as a new metric in the New Relic UI.
  • The callback defines the callback you want to trace.

The agent begins timing the segment when createTracer is called, and ends the segment when the callback defined by the callback argument finishes executing.

newrelic.createWebTransaction(url, handle) DEPRECATED

This method has been deprecated in favor of newrelic.startWebTransaction().

Instrument the specified web transaction. Using this API call, you can instrument transactions that New Relic does not automatically detect.

The url defines the transaction name and needs to be static. Do not include potentially dynamic 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 createTracer().

If called within an active web transaction, the agent will create a new segment. If called within an active background transaction, this call creates a new, independent transaction and captures any new calls within the handle inside the new transaction.

You must end custom transactions manually by calling endTransaction(). New Relic begins timing the transaction when createWebTransaction() is called and ends the transaction when endTransaction() is called.

newrelic.createBackgroundTransaction(name, [group], handle) DEPRECATED

This method has been deprecated in favor of newrelic.startBackgroundTransaction().

Instrument the specified background transaction. Using this API call, you can expand New Relic's instrumentation to capture data from background transactions.

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

The group is optional, and it allows you to group similar jobs together via the transaction type in the user interface. Like name, the group needs to be static. 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 createTracer().

You must end custom transactions manually by calling endTransaction(). New Relic begins timing the transaction when createBackgroundTransaction() is called and ends the transaction when endTransaction() is called.

Custom metrics API calls

Use these API calls to record additional arbitrary metrics:

newrelic.recordMetric(name, value)

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.

Other API calls

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

newrelic.addCustomParameter(name, value)

Set a custom parameter 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 parameters. Custom parameters will appear in New Relic APM's transaction trace detail view and in errors for the transaction.

If you want to use your custom parameters or attributes in Insights, avoid using any of the reserved terms used by NRQL and Insights when naming them.

newrelic.addCustomParameters(params)

Set multiple custom parameter values to be displayed along with the transaction trace in the New Relic UI. The parameters 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 parameters. Custom parameters will appear in the transaction trace detail view and in errors for the transaction.

If you want to use your custom parameters or attributes in Insights, avoid using any of the reserved terms used by NRQL and Insights when naming them.

newrelic.getBrowserTimingHeader()

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.

Errors recorded using this method do not obey the ignore_status_codes configuration value.

newrelic.shutdown([options], callback)

Use this method to gracefully shut down the agent.

options

  • 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.

Example:

  newrelic.shutdown({ collectPendingData: true, timeout: 3000}, function(error) {
    process.exit()
  })

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:

    NEW_RELIC_NAMING_RULES='{"pattern":"^t","name":"u"},{"pattern":"^u","name":"t"}'

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)
Replace first match in URL
pattern: "[0-9]+",
name: ":id"

will result in:

/orders/123  =>  /orders/:id
/items/123  =>  /items/:id
/orders/123/items/123  =>  /orders/:id/items/123
Replace all matches in any URL
pattern: "[0-9]+",
name: ":id",
replace_all: true

will result in:

/orders/123/items/123  =>  /orders/:id/items/:id
Match group references

Using regular expression match group references:

pattern: '^/(items|orders)/[0-9]+$',
name: '/\\1/:id'

will result in:

/orders/123  =>  /orders/:id
/items/123  =>  /items/:id
rules.ignore

This can also be set via the environment variable NEW_RELIC_IGNORING_RULES, with multiple rules passed in as a list of comma-delimited patterns. Currently there is no way to escape commas in patterns.

NEW_RELIC_IGNORING_RULES='^/socket\.io/\*/xhr-polling,ignore_me'

Here are full examples of how rules are included in the configuration file:

Naming rule example
  // newrelic.js
  exports.config = {
    // other configuration
    rules : {
      name : [
        { pattern: "/tables/name-here", name: "/name-hererule1" }
      ]
    }
Ignoring rule example

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:

  // newrelic.js
  exports.config = {
    // other configuration
    rules : {
      ignore : [
        '^\/socket\.io\/.*\/xhr-polling'
      ]
    }
  };

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 mandatory.

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. Both parameters are mandatory.

For more help

Join the discussion about Node.js monitoring in the New Relic Online Technical Community! The Technical Community is a public platform to discuss and troubleshoot your New Relic toolset.

If you need additional help, get support at support.newrelic.com.