Skip to content

Resource Hook Integration Guide (SDK version requirement >= 3.3.0)

Description

Resource Hook is used to supplement request-level business fields for automatically collected resource events.

Use Cases:

  • Writing business context before a request is initiated
  • Continuing to supplement fields after the response returns
  • The final reported resource event needs to carry both parts of data simultaneously

This capability supports both fetch and XMLHttpRequest.

How It Works

  1. Create a tracker id via createResourceTrackerId()
  2. Place this id in the request header x-rum-resource-id
  3. Write pre-request context with setResourceContext()
  4. Supplement post-response context with appendResourceContext()
  5. Trigger the final tracked resource report by calling finishResource()

If a request does not carry the x-rum-resource-id header, the SDK will continue with the original ordinary resource auto-collection pipeline.

Public API

const resourceId = DATAFLUX_RUM.createResourceTrackerId()

DATAFLUX_RUM.setResourceContext(resourceId, { order_id: '123' })
DATAFLUX_RUM.appendResourceContext(resourceId, { result: 'success' })
DATAFLUX_RUM.finishResource(resourceId)
DATAFLUX_RUM.getResource(resourceId)

API Semantics:

  • createResourceTrackerId() Create a new tracker id
  • setResourceContext(resourceId, context) Overwrite the current tracker's context
  • appendResourceContext(resourceId, context) Append more fields to the current tracker's context
  • finishResource(resourceId) Indicates this tracked resource is ready to finish. If the request is already completed, reporting is triggered immediately; if the request is not yet completed, the SDK will wait until the request completes before reporting.
  • getResource(resourceId) Returns the current tracker snapshot, mainly for debugging.

Fetch Example

const resourceId = window.DATAFLUX_RUM.createResourceTrackerId()

window.DATAFLUX_RUM.setResourceContext(resourceId, {
  order_id: '123',
  scene: 'checkout'
})

fetch('/api/order/detail', {
  headers: {
    'x-rum-resource-id': resourceId
  }
})
  .then((response) => {
    window.DATAFLUX_RUM.appendResourceContext(resourceId, {
      result: 'success',
      response_status: response.status
    })
    window.DATAFLUX_RUM.finishResource(resourceId)
    return response
  })
  .catch((error) => {
    window.DATAFLUX_RUM.appendResourceContext(resourceId, {
      result: 'error',
      error_message: error.message
    })
    window.DATAFLUX_RUM.finishResource(resourceId)
    throw error
  })

XHR Example

const resourceId = window.DATAFLUX_RUM.createResourceTrackerId()

window.DATAFLUX_RUM.setResourceContext(resourceId, {
  order_id: '123',
  scene: 'checkout'
})

const xhr = new XMLHttpRequest()
xhr.open('GET', '/api/order/detail', true)
xhr.setRequestHeader('x-rum-resource-id', resourceId)

xhr.addEventListener('load', () => {
  window.DATAFLUX_RUM.appendResourceContext(resourceId, {
    result: 'success',
    response_status: xhr.status
  })
  window.DATAFLUX_RUM.finishResource(resourceId)
})

xhr.addEventListener('error', () => {
  window.DATAFLUX_RUM.appendResourceContext(resourceId, {
    result: 'error',
    error_message: 'xhr_error'
  })
  window.DATAFLUX_RUM.finishResource(resourceId)
})

xhr.send()

Trace Scenario Example

If the same request also needs trace id injection, you must keep the x-rum-resource-id header and ensure the request origin is configured in the tracing whitelist.

window.DATAFLUX_RUM.init({
  // ...
  traceType: 'ddtrace',
  allowedDDTracingOrigins: [window.location.origin]
})

Then send the tracked request as usual:

const resourceId = window.DATAFLUX_RUM.createResourceTrackerId()

window.DATAFLUX_RUM.setResourceContext(resourceId, {
  scene: 'checkout'
})

fetch('/api/order/detail', {
  headers: {
    'x-rum-resource-id': resourceId
  }
})
  .then((response) => {
    window.DATAFLUX_RUM.appendResourceContext(resourceId, {
      trace_expected: 'true',
      response_status: response.status
    })
    window.DATAFLUX_RUM.finishResource(resourceId)
    return response
  })

The rawRumEvent._gc in the final tracker snapshot may contain traceId and spanId.

Debugging

You can view the current tracker snapshot at any time:

const snapshot = window.DATAFLUX_RUM.getResource(resourceId)
console.log(snapshot)

Typical snapshot structure:

{
  trackerId: 'uuid',
  status: 'request_collected',
  context: {
    order_id: '123',
    result: 'success'
  },
  resource: {
    type: 'fetch',
    url: '/api/order/detail',
    method: 'GET',
    status: 200
  },
  rawRumEvent: {
    type: 'resource',
    _gc: {
      traceId: '...',
      spanId: '...'
    }
  }
}

Current status values include:

  • created
  • request_collected
  • finished
  • flushed
  • timeout_flushed
  • cleared

Timeout Behavior

If the business code does not call finishResource(), the SDK will automatically flush this tracked resource after 30s.

The most easily misunderstood point here is:

  • This 30s is counted from after the request completes
  • Not from when the request starts

The actual sequence is:

  1. Request starts
  2. Request completes
  3. SDK associates with this resource via x-rum-resource-id
  4. If finishResource() hasn't been called yet, the SDK waits at most another 30s
  5. After that time, it automatically reports with the timeout_flushed status

This avoids tracked requests staying in a pending state indefinitely, while also giving business code a window to "supplement response context after the request completes".

Timing Notes

  • If finishResource() is called before the request completes, the SDK will not report immediately. Instead, it marks the tracker as finished and waits for the actual request completion before flushing.
  • If finishResource() is called after the request completes, the SDK flushes immediately.
  • If finishResource() is never called, it follows the logic above: "wait 30s after request completion and then auto-flush".

Notes

  • Business requests must allow the custom header x-rum-resource-id
  • If a request does not carry this header, it automatically downgrades to ordinary resource collection
  • If the tracker id carried in the header does not exist, it also downgrades to ordinary resource collection
  • getResource() is mainly for debugging and is not recommended as a dependency for business logic.