Options
All
  • Public
  • Public/Protected
  • All
Menu

dd-trace

Datadog JavaScript Tracer API

This is the API documentation for the Datadog JavaScript Tracer. If you are just looking to get started, check out the tracing setup documentation.

Overview

The module exported by this library is an instance of the Tracer class.

Manual Instrumentation

If you aren’t using supported library instrumentation (see Compatibility), you may want to manually instrument your code.

This can be done using the OpenTracing API and the Scope Manager.

OpenTracing API

This library is OpenTracing compliant. Use the OpenTracing API and the Datadog Tracer (dd-trace) library to measure execution times for specific pieces of code. In the following example, a Datadog Tracer is initialized and used as a global tracer:

const tracer = require('dd-trace').init()
const opentracing = require('opentracing')

opentracing.initGlobalTracer(tracer)

The following tags are available to override Datadog specific options:

  • service.name: The service name to be used for this span. The service name from the tracer will be used if this is not provided.
  • resource.name: The resource name to be used for this span. The operation name will be used if this is not provided.
  • span.type: The span type to be used for this span. Will fallback to custom if not provided.

Scope Manager

In order to provide context propagation, this library includes a scope manager. A scope is basically a wrapper around a span that can cross both synchronous and asynchronous contexts.

The scope manager contains 3 APIs available on tracer.scope():

scope.active()

This method returns the active span from the current scope.

scope.activate(span, fn)

This method activates the provided span in a new scope available in the provided function. Any asynchronous context created from whithin that function will also have the same scope.

const tracer = require('dd-trace').init()
const scope = tracer.scope()
const log = console.log

const requestSpan = tracer.startSpan('web.request')
const promise = Promise.resolve()

scope.activate(requestSpan, () => {
  log(scope.active()) // requestSpan because in new scope

  someFunction() // requestSpan because called in scope

  setTimeout(() => {
    log(scope.active()) // requestSpan because setTimeout called in scope
  })

  promise.then(() => {
    log(scope.active()) // requestSpan because then() called in scope
  })
})

function someFunction () {
  log(scope.active())
}

log(scope.active()) // null

someFunction() // null because called outside the scope

scope.bind(target, [span])

This method binds a target to the specified span, or to the active span if unspecified. It supports binding functions, promises and event emitters.

When a span is provided, the target is always bound to that span. Explicitly passing null as the span will actually bind to null or no span. When a span is not provided, the binding uses the following rules:

  • Functions are bound to the span that is active when scope.bind(fn) is called.
  • Promise handlers are bound to the active span in the scope where .then() was called. This also applies to any equivalent method such as .catch().
  • Event emitter listeners are bound to the active span in the scope where .addEventListener() was called. This also applies to any equivalent method such as .on()

Note: Native promises and promises from bluebird, q and when are already bound by default and don't need to be explicitly bound.

Examples
Function binding
const tracer = require('dd-trace').init()
const scope = tracer.scope()
const log = console.log

const outerSpan = tracer.startSpan('web.request')

scope.activate(outerSpan, () => {
  const innerSpan = tracer.startSpan('web.middleware')

  const boundToInner = scope.bind(() => {
    log(scope.active())
  }, innerSpan)

  const boundToOuter = scope.bind(() => {
    log(scope.active())
  })

  boundToInner() // innerSpan because explicitly bound
  boundToOuter() // outerSpan because implicitly bound
})
Promise binding
const tracer = require('dd-trace').init()
const scope = tracer.scope()
const log = console.log

const outerSpan = tracer.startSpan('web.request')
const innerPromise = Promise.resolve()
const outerPromise = Promise.resolve()

scope.activate(outerSpan, () => {
  const innerSpan = tracer.startSpan('web.middleware')

  scope.bind(innerPromise, innerSpan)
  scope.bind(outerPromise)

  innerPromise.then(() => {
    log(scope.active()) // innerSpan because explicitly bound
  })

  outerPromise.then(() => {
    log(scope.active()) // outerSpan because implicitly bound on `then()` call
  })
})

Note: async/await cannot be bound and always execute in the scope where await was called. If binding async/await is needed, the promise must be wrapped by a function.

Event emitter binding
const tracer = require('dd-trace').init()
const scope = tracer.scope()
const log = console.log
const EventEmitter = require('events').EventEmitter

const outerSpan = tracer.startSpan('web.request')
const innerEmitter = new EventEmitter()
const outerEmitter = new EventEmitter()

scope.activate(outerSpan, async () => {
  const innerSpan = tracer.startSpan('web.middleware')

  scope.bind(innerEmitter, innerSpan)
  scope.bind(outerEmitter)

  innerEmitter.on('request', () => {
    log(scope.active()) // innerSpan because explicitly bound
  })

  outerEmitter.on('request', () => {
    log(scope.active()) // outerSpan because implicitly bound on `then()` call
  })
})

innerEmitter.emit('request')
outerEmitter.emit('request')

See the API documentation for more details.

Integrations

APM provides out-of-the-box instrumentation for many popular frameworks and libraries by using a plugin system. By default all built-in plugins are enabled. Disabling plugins can cause unexpected side effects, so it is highly recommended to leave them enabled.

Built-in plugins can be configured individually:

const tracer = require('dd-trace').init()

// enable and configure postgresql integration
tracer.use('pg', {
  service: 'pg-cluster'
})

Available Plugins

Advanced Configuration

Tracer settings

Options can be configured as a parameter to the init() method or as environment variables.

Config Environment Variable Default Description
enabled DD_TRACE_ENABLED true Whether to enable the tracer.
debug DD_TRACE_DEBUG false Enable debug logging in the tracer.
service DD_SERVICE_NAME | The service name to be used for this program.
url DD_TRACE_AGENT_URL | The url of the trace agent that the tracer will submit to. Takes priority over hostname and port, if set.
hostname DD_TRACE_AGENT_HOSTNAME localhost The address of the agent that the tracer will submit to.
port DD_TRACE_AGENT_PORT 8126 The port of the trace agent that the tracer will submit to.
dogstatsd.port DD_DOGSTATSD_PORT 8125 The port of the Dogstatsd agent that metrics will be submitted to.
env DD_ENV | Set an application’s environment e.g. prod, pre-prod, stage.
logInjection DD_LOGS_INJECTION false Enable automatic injection of trace IDs in logs for supported logging libraries.
tags | {} Set global tags that should be applied to all spans.
sampleRate | 1 Percentage of spans to sample as a float between 0 and 1.
flushInterval | 2000 Interval in milliseconds at which the tracer will submit traces to the agent.
runtimeMetrics DD_RUNTIME_METRICS_ENABLED false Whether to enable capturing runtime metrics. Port 8125 (or configured with dogstatsd.port) must be opened on the agent for UDP.
reportHostname DD_TRACE_REPORT_HOSTNAME false Whether to report the system's hostname for each trace. When disabled, the hostname of the agent will be used instead.
experimental | {} Experimental features can be enabled all at once using boolean true or individually using key/value pairs. There are currently no experimental features available.
plugins | true Whether or not to enable automatic instrumentation of external libraries using the built-in plugins.

Custom Logging

By default, logging from this library is disabled. In order to get debbuging information and errors sent to logs, the debug options should be set to true in the init() method.

The tracer will then log debug information to console.log() and errors to console.error(). This behavior can be changed by passing a custom logger to the tracer. The logger should contain a debug() and error() methods that can handle messages and errors, respectively.

For example:

const bunyan = require('bunyan')
const logger = bunyan.createLogger({
  name: 'dd-trace',
  level: 'trace'
})

const tracer = require('dd-trace').init({
  logger: {
    debug: message => logger.trace(message),
    error: err => logger.error(err)
  },
  debug: true
})

Generated using TypeDoc