Skip to main content

Overview

Lifecycle callbacks let you observe trace events without modifying your tracing logic. Use them for monitoring, metrics, alerting, or debugging — the SDK invokes them at key points in a trace’s lifecycle.

TraceCallbacks Interface

interface TraceCallbacks {
  /** Called once when the trace is first created on the server (first successful flush) */
  onCreated?: (traceId: string) => void;

  /** Called after each successful flush */
  onFlushed?: (traceId: string, itemCount: number) => void;

  /** Called when a flush operation fails after retries */
  onFlushError?: (error: Error, operation: string) => void;

  /** Called when the trace is closed */
  onClosed?: (traceId: string, reason?: string) => void;

  /** Called when items are dropped (e.g., queue full) */
  onDropped?: (count: number, reason: string) => void;
}

Callback Reference

onCreated

Fired once per trace, after the first successful flush (i.e., the server has acknowledged the trace).
onCreated: (traceId: string) => void
ParameterTypeDescription
traceIdstringW3C-compatible trace ID (32-char hex)

onFlushed

Fired after every successful flush. Useful for tracking throughput or confirming delivery.
onFlushed: (traceId: string, itemCount: number) => void
ParameterTypeDescription
traceIdstringThe trace that was flushed
itemCountnumberNumber of items (events, attributes, tags) in this flush

onFlushError

Fired when a flush fails after exhausting all retries. The data from that flush attempt is lost.
onFlushError: (error: Error, operation: string) => void
ParameterTypeDescription
errorErrorThe final error after retries
operationstringThe operation that failed (e.g., "CreateTrace", "FlushTrace")

onClosed

Fired when a trace is closed, either explicitly via trace.close() or automatically (e.g., max lifetime exceeded, page unload).
onClosed: (traceId: string, reason?: string) => void
ParameterTypeDescription
traceIdstringThe trace that was closed
reasonstring | undefinedOptional close reason passed to trace.close(reason)

onDropped

Fired when items are discarded because the flush queue has reached maxQueueSize. This is a signal to reduce event volume or increase the queue size.
onDropped: (count: number, reason: string) => void
ParameterTypeDescription
countnumberNumber of items dropped
reasonstringWhy items were dropped (e.g., "queue full")

Setting Callbacks

Client-Level (All Traces)

Callbacks set on the client apply to every trace it creates:
const client = new Client('your-api-key', {
  callbacks: {
    onCreated: (traceId) => {
      console.log('Trace created:', traceId);
    },
    onFlushError: (error, operation) => {
      console.error(`${operation} failed:`, error.message);
    }
  }
});

Per-Trace (Override)

Per-trace callbacks override client-level callbacks for that specific trace:
const trace = client.trace({
  name: 'CriticalFlow',
  callbacks: {
    onFlushed: (traceId, itemCount) => {
      metrics.increment('critical_flush', { traceId, itemCount });
    },
    onFlushError: (error, operation) => {
      alerting.send(`Critical trace flush failed: ${error.message}`);
    }
  }
});

Use Cases

Metrics Collection

Track SDK health and throughput:
const client = new Client('your-api-key', {
  callbacks: {
    onCreated: () => metrics.increment('mirador.traces.created'),
    onFlushed: (_, itemCount) => {
      metrics.increment('mirador.flushes.success');
      metrics.histogram('mirador.flush.item_count', itemCount);
    },
    onFlushError: (error, operation) => {
      metrics.increment('mirador.flushes.error', { operation });
    },
    onDropped: (count) => {
      metrics.increment('mirador.items.dropped', {}, count);
    }
  }
});

Error Alerting

Get notified when trace delivery fails:
const client = new Client('your-api-key', {
  callbacks: {
    onFlushError: (error, operation) => {
      // Send to your error tracking service
      Sentry.captureException(error, {
        tags: { operation, source: 'mirador-sdk' }
      });
    },
    onDropped: (count, reason) => {
      Sentry.captureMessage(`Mirador SDK dropped ${count} items: ${reason}`, 'warning');
    }
  }
});

Debug Logging

Verbose output during development:
const client = new Client('your-api-key', {
  debug: true,
  callbacks: {
    onCreated: (traceId) => console.log(`[Mirador] Created: ${traceId}`),
    onFlushed: (traceId, n) => console.log(`[Mirador] Flushed ${n} items for ${traceId}`),
    onFlushError: (err, op) => console.error(`[Mirador] ${op} failed:`, err),
    onClosed: (traceId, reason) => console.log(`[Mirador] Closed: ${traceId} (${reason ?? 'no reason'})`),
    onDropped: (count, reason) => console.warn(`[Mirador] Dropped ${count}: ${reason}`)
  }
});

Trace Correlation Logging

Log trace IDs for request correlation in your backend:
import { Client } from '@miradorlabs/nodejs-sdk';

const client = new Client(process.env.MIRADOR_API_KEY, {
  callbacks: {
    onCreated: (traceId) => {
      logger.info({ traceId, msg: 'Mirador trace started' });
    },
    onClosed: (traceId, reason) => {
      logger.info({ traceId, reason, msg: 'Mirador trace ended' });
    }
  }
});

Error Safety

Callbacks are invoked inside a try-catch — if your callback throws, the SDK logs the error (via the configured logger) and continues normally. Your callbacks will never crash the SDK or interrupt trace delivery.

Next Steps

Custom Logging

Configure SDK logging output

Retry Logic

Network failure handling

Types

Full TraceCallbacks type definition