Custom Instrumentation

On this page you will learn how to manually propagate trace information into and out of your JavaScript application.

Distributed tracing will be set up automatically if:

  • You've Set Up Tracing, or
  • You're using one of the SDKs that include tracing propagation out of the box:
    • @sentry/nextjs
    • @sentry/sveltekit
    • @sentry/remix
    • @sentry/astro

If you are using a different package, and have not enabled tracing, you can manually set up your application for distributed tracing to work.

For distributed tracing to work, the two headers that you extracted and stored in the active root span, sentry-trace and baggage, must be added to outgoing HTTP requests.

Here's an example of how to collect and inject this tracing information to outgoing requests:

Copied
const activeSpan = Sentry.getActiveSpan();
const rootSpan = activeSpan ? Sentry.getRootSpan(activeSpan) : undefined;

// Create `sentry-trace` header
const sentryTraceHeader = rootSpan
  ? Sentry.spanToTraceHeader(rootSpan)
  : undefined;

// Create `baggage` header
const sentryBaggageHeader = rootSpan
  ? Sentry.spanToBaggageHeader(rootSpan)
  : undefined;

// Make outgoing request
fetch("https://example.com", {
  method: "GET",
  headers: {
    baggage: sentryBaggageHeader,
    "sentry-trace": sentryTraceHeader,
  },
}).then((response) => {
  // ...
});

In this example, tracing information is propagated to the project running at https://example.com. If this project uses a Sentry SDK, it will extract and save the tracing information for later use.

The two services are now connected with your custom distributed tracing implementation.

If you're server-side rendering HTML and you use a Sentry SDK in your browser application, you can connect the backend and frontend traces by injecting your server's tracing information as <meta> tags into the HTML that's initially served to the browser. When the frontend SDK is initialized, it will automatically pick up the tracing information from the <meta> tags and continue the trace. Note, that your browser SDK needs to register browserTracingIntegration for this to work.

The easiest and recommended way to do this is to use the Sentry.getTraceMetaTags():

index.js
Copied
function renderHtml() {
  return `
    <html>
      <head>
        ${Sentry.getTraceMetaTags()}
      </head>
      <body>
        <!-- Your HTML content -->
      </body>
    </html>
  `;
}

Alternatively, if you need more control over how meta tags are generated, you can use Sentry.getTraceData() to get only the meta tag values and generate the meta tags yourself:

index.js
Copied
function renderHtml() {
  const metaTagValues = Sentry.getTraceData();

  return `
    <html>
      <head>
        <meta name="sentry-trace" content="${metaTagValues["sentry-trace"]}">
        <meta name="baggage" content="${metaTagValues.baggage}">
      </head>
      <body>
        <!-- Your HTML content -->
      </body>
    </html>
  `;
}

Available since SDK version 8.5.0.

In case the SDK's default behavior for the trace duration does not fit your needs, you can manually start a new trace that will no longer be connected to the current (distributed) trace. This means that spans or errors collected by the SDK during this new trace will not be connected to spans or errors collected before or after this new trace.

To start a new trace that remains valid throughout the duration of a callback, use startNewTrace:

Copied
myButton.addEventListener("click", async () => {
  Sentry.startNewTrace(() => {
    Sentry.startSpan(
      { op: "ui.interaction.click", name: "fetch click" },
      async () => {
        await fetch("http://example.com");
      },
    );
  });
});

Once the callback ends, the SDK will continue the previous trace (if available).

If you make outgoing requests from your project to other services, check if the headers sentry-trace and baggage are present in the request. If so, distributed tracing is working.

Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").