Custom Transactionsedit

Elastic APM uses the concept of transactions and spans to collect performance data. Spans are used to measure a unit of operation and they are grouped into the transactions.

By default, Elastic APM JS agent creates transactions for all the Supported Technologies and send them to the apm-server, however if the current instrumentation doesn’t provide all the insights, you can create custom transactions to fill the gaps.

Here is an example of using custom transactions and spans:

const transaction = apm.startTransaction('Application start', 'custom')
const url = 'http://example.com/data.json'
const httpSpan = transaction.startSpan('GET ' + url, 'external.http')
fetch(url)
  .then((resp) => {
    if (!resp.ok) {
      apm.captureError(new Error(`fetch failed with status ${resp.status} ${resp.statusText}`))
    }
    httpSpan.end()
    transaction.end()
  })

custom transactions are not managed by the agent, therefore, the agent does not capture spans and other timing information based on automatic instrumentations, e.g. XHR, Resource Timing etc.

Creating a Managed transactionedit

If the user is interested in associating all the other timing information and spans in the custom transactions based on the supported technologies, they can pass the managed flag to true while creating the transaction and will be controlled by the agent. However, the transaction might get closed automatically once all the associated spans are completed. If the user wants to control this behavior, they can create a blocking span that will hold the transaction until span.end is called.

const transaction = apm.startTransaction('custom managed', 'custom', { managed: true })
const span = transaction.startSpan('async-task', 'app', { blocking: true })

setTimeout(() => {
  span.end()
  /**
   * This would also end the managed transaction once all the blocking spans are completed and
   * transaction would also contain other timing information and spans similar to auto
   * instrumented transactions like `page-load` and `route-change`.
   */
}, 1000)

Both custom and managed transactions are queued and sent together automatically at configured intervals after transaction.end is called.