All files tracing.js

100% Statements 57/57
100% Branches 9/9
100% Functions 5/5
100% Lines 57/57

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 641x   1x   1x 1x 1x 1x 1x   1x 1x 1x 1x 1x 1x 3x 3x 3x 1x 1x 3x 3x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x   1x 1x 1x 1x 1x 1x 1x 1x 1x 13x 10x 5x 5x 5x 5x 5x 5x 10x 10x 13x 13x 13x 1x 1x 1x 1x 1x      
import { AsyncLocalStorage } from 'node:async_hooks'
 
const asyncLocalStorage = new AsyncLocalStorage()
 
/**
 * Return's the request's trace id, if set else null.
 * @return {string|null}
 */
const getTraceId = () => asyncLocalStorage.getStore()?.get('traceId')
 
/**
 * Appends the trace id to an existing set of headers.
 * @param { string } headerName name of header to put trace id in
 * @param { Object } headers object container existing headers
 * @return { Object }
 */
function withTraceId(headerName, headers = {}) {
  const traceId = getTraceId()
  if (traceId) {
    headers[headerName] = traceId
  }
  return headers
}
/**
 * Wrap the request lifecycle in an asyncLocalStorage run call. This allows the
 * passed store to be available during the request lifecycle.
 * @param { Request } request
 * @param { Map<string, string> } store
 */
function wrapLifecycle(request, store) {
  const requestLifecycle = request._lifecycle.bind(request)
  request._lifecycle = () => asyncLocalStorage.run(store, requestLifecycle)
}
 
/**
 * @satisfies {Plugin}
 */
const tracing = {
  plugin: {
    name: 'tracing',
    version: '0.1.0',
    once: true,
    register(server, options) {
      if (options.tracingHeader) {
        server.ext('onRequest', (request, h) => {
          const store = new Map()
          const tracingHeader = options?.tracingHeader
          const traceId = request.headers[tracingHeader]
          store.set('traceId', traceId)
          wrapLifecycle(request, store)
          return h.continue
        })
      }
      server.decorate('request', 'getTraceId', getTraceId)
      server.decorate('server', 'getTraceId', getTraceId)
    }
  },
  options: {
    tracingHeader: 'x-cdp-request-id'
  }
}
 
export { tracing, getTraceId, withTraceId }