How to Debug From Frontend to Backend Faster with OpenTelemetry

How to Debug From Frontend to Backend Faster with OpenTelemetry

Michael Shi Michael Shi • Jun 5, 2023
How to Debug From Frontend to Backend Faster with OpenTelemetry

When debugging tricky issues, it can be pretty helpful to easily find the API request a specific user made from their browser, and trace it all the way through to the backend. Or even in reverse, to go from an exception thrown in the backend, to the user session that caused it.

With OpenTelemetry, a vendor-neutral and open source instrumentation framework, it’s now trivial to link frontend API calls, user actions, and even session replays to all your backend telemetry, eliminating a traditional blind-spot between frontend and backend debugging tools.

We’ll walk through some of the benefits you can get from adding OpenTelemetry-based distributed tracing to your frontend applications, and then a few ways you can get it installed and running in just a few minutes!

Why Distributed Tracing in the Frontend?

Whether debugging frontend or backend issues, being able to understand what actions happened before the bug occurred can be key to figuring out tricky edge cases. For example, what button or inputs did the user do that could have possibly triggered the bug? Or which user flow was the user stepping through that we didn’t account for?

Without distributed tracing, it can be a tedious exercise to link together session replays, frontend exception monitoring and backend logging and APM signals together to get a clear picture. However, with distributed tracing, it becomes a lot easier to see what series of API calls were made for a user session, what logs and spans the backend services emitted for each API call, and even being able to see the session replay to visually confirm what the user was doing leading up to the error.

This gives a really powerful tool to understand a bug end-to-end and answer questions a lot quicker than trying to debug with only backend or frontend telemetry separately.

Additionally, frontend tracing can also identify and track frontend performance for real users, being able to measure loading times, least contentful paint timings, and capture error messages.

Adding OpenTelemetry Tracing to the Frontend

There are a few ways to add OpenTelemetry to the frontend, from manually installing OpenTelemetry SDK components or a pre-bundled package offered by HyperDX.

Using @hyperdx/browser

The HyperDX browser bundle automatically sets up OpenTelemetry instrumentation to collection network requests, errors, timings, session replay and more. It eliminates some of the boilerplate associated with OpenTelemetry and exposes a typical browser SDK interface.

First you can install it via

npm install @hyperdx/browser

Alternatively you can include the package via script tag with <script src="//www.unpkg.com/@hyperdx/browser@0.14.4/build/index.js"></script>. Which will set the HyperDX library as a global.

Afterwards, you can initialize the library with a service name (any name you’d like to identify your app), along with the URL pattern for your API server if you’d like to propagate traces to your backend (tracePropagationTargets).

Additionally, if you’re sending to HyperDX, you’ll need to specify an apiKey. Otherwise, you’ll want to configure the urlto point to your OpenTelemetry collector.

Example:

import HyperDX from '@hyperdx/browser';
 
HyperDX.init({
  apiKey: '<YOUR_API_KEY_HERE>',
  // url: '<YOUR_OTEL_COLLECTOR_URL_HERE>', // Not required when using HyperDX
  service: 'my-frontend-app',
  tracePropagationTargets: [/api.myapp.domain/i], // Set to link traces from frontend to backend requests
});

Afterwards, you can attach arbitrary custom metadata to all events from the session via

HyperDX.setGlobalAttributes({
  userEmail: user.email,
  userName: user.name,
  teamName: user.team.name,
  // Other custom properties...
});

Alternatively via @opentelemetry/sdk-trace-web and @opentelemetry/auto-instrumentations-web

Alternatively, you can manually set up the OpenTelemetry SDK, in which case we recommend using the auto-instrumentation package to automatically instrument document timings, user actions, and network requests.

First you’ll need to install the required dependencies via:

npm install @opentelemetry/sdk-trace-web @opentelemetry/auto-instrumentations-web @opentelemetry/exporter-trace-otlp-http @opentelemetry/sdk-trace-base @opentelemetry/instrumentation @opentelemetry/context-zone @opentelemetry/resources @opentelemetry/semantic-conventions
const { WebTracerProvider } = require('@opentelemetry/sdk-trace-web');
const {
  getWebAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-web');
const {
  OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-http');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { ZoneContextManager } = require('@opentelemetry/context-zone');
const { Resource } = require('@opentelemetry/resources');
const {
  SemanticResourceAttributes,
} = require('@opentelemetry/semantic-conventions');
 
const exporter = new OTLPTraceExporter({
  url: 'https://<your collector endpoint>:443/v1/traces',
});
 
const provider = new WebTracerProvider({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'browser',
  }),
});
provider.addSpanProcessor(new BatchSpanProcessor(exporter));
provider.register({
  contextManager: new ZoneContextManager(),
});
 
registerInstrumentations({
  instrumentations: [getWebAutoInstrumentations()],
});

Now you’re all set and you’ll be able to receive OpenTelemetry traces directly from your frontend application!

If you want to avoid setting up OpenTelemetry and managing your own observability tooling, you should check out how HyperDX can be your full-stack managed observability tool.