Traces

Understand distributed traces and how they flow through your system.

What is a Trace?#

A trace represents a single request as it flows through your distributed system. It starts when a request enters your system (e.g., an HTTP request from a browser) and includes every operation that happens to serve that request -- API calls, database queries, cache lookups, and external service calls.

Each trace has a globally unique Trace ID that correlates all operations together.

Frontend-to-Backend Tracing#

JustAnalytics provides end-to-end tracing from browser to backend. The monitor script (monitor.js) injects a W3C traceparent header into outgoing fetch/XHR requests. The server-side SDK reads this header and continues the trace.

Browser (monitor.js)
  └─ fetch('/api/orders') → traceparent: 00-abc123-def456-01
      └─ API Server (Node.js SDK)
          ├─ PostgreSQL query: SELECT * FROM orders
          ├─ Redis cache lookup
          └─ External API call: payment-service

Trace Explorer#

The Trace Explorer dashboard lets you search, filter, and inspect traces.

Filtering#

Filter traces by:

  • Service name -- which service(s) to include
  • Operation name -- specific endpoint or function
  • Duration -- minimum/maximum latency
  • Status -- success or error
  • Tags -- custom attributes set in your code
  • Time range -- when the trace occurred

Waterfall View#

Click on any trace to see the waterfall view, which shows:

  • All spans arranged hierarchically
  • Start time and duration of each span
  • Tags and attributes on each span
  • Errors that occurred within the trace
  • Gap analysis between spans

Creating Traces#

Traces are created automatically by the SDK's HTTP auto-instrumentation. You can also create manual traces:

import JA from '@justanalyticsapp/node';

const result = await JA.startSpan('process-order', async (span) => {
  span.setAttribute('order.id', orderId);
  span.setAttribute('order.total', total);

  // Nested spans create parent-child relationships
  const user = await JA.startSpan('fetch-user', async () => {
    return await db.users.findUnique({ where: { id: userId } });
  });

  const payment = await JA.startSpan('charge-payment', async (paymentSpan) => {
    paymentSpan.setAttribute('payment.method', 'stripe');
    return await stripe.charges.create({ amount: total });
  });

  return { user, payment };
});

W3C Trace Context#

JustAnalytics uses the W3C Trace Context standard for trace propagation. The traceparent header format is:

traceparent: 00-<trace-id>-<span-id>-<trace-flags>

Example:

traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

This ensures compatibility with other tracing systems that support the W3C standard.

Sampling#

By default, all traces are captured. For high-traffic applications, you can configure sampling:

JA.init({
  siteId: 'YOUR_SITE_ID',
  apiKey: 'YOUR_API_KEY',
  serviceName: 'api-server',
  sampleRate: 0.1, // Capture 10% of traces
});

Error traces are always captured regardless of the sample rate.