> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mutagent.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tracing Setup

> Configure tracing in your application

# Tracing Setup

This guide covers how to initialize, configure, and shut down the MutagenT tracing system in both TypeScript and Python applications.

## Quick Start

<Steps>
  <Step title="Install the SDK">
    <CodeGroup>
      ```bash TypeScript theme={null}
      npm install @mutagent/sdk
      ```

      ```bash Python theme={null}
      pip install mutagent-sdk
      ```
    </CodeGroup>
  </Step>

  <Step title="Initialize tracing at application startup">
    <CodeGroup>
      ```typescript TypeScript theme={null}
      import { initTracing } from "@mutagent/sdk/tracing";

      initTracing({
        apiKey: process.env.MUTAGENT_API_KEY!,
      });
      ```

      ```python Python theme={null}
      from mutagent.tracing import init_tracing

      init_tracing(
          api_key="mt_xxxxxxxxxxxx",
      )
      ```
    </CodeGroup>
  </Step>

  <Step title="Shut down tracing before process exit">
    <CodeGroup>
      ```typescript TypeScript theme={null}
      import { shutdownTracing } from "@mutagent/sdk/tracing";

      // Flush remaining spans and clean up
      await shutdownTracing();
      ```

      ```python Python theme={null}
      import asyncio
      from mutagent.tracing import shutdown_tracing

      asyncio.run(shutdown_tracing())
      ```
    </CodeGroup>
  </Step>
</Steps>

## `initTracing()` Configuration

The `initTracing()` function accepts a `TracingConfig` object. Call it once at application startup before any traced operations.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { initTracing } from "@mutagent/sdk/tracing";

  initTracing({
    apiKey: process.env.MUTAGENT_API_KEY!,
    endpoint: "https://api.mutagent.io",
    environment: "production",
    batchSize: 10,
    flushIntervalMs: 5000,
    debug: false,
    source: "sdk",
  });
  ```

  ```python Python theme={null}
  from mutagent.tracing import init_tracing

  init_tracing(
      api_key="mt_xxxxxxxxxxxx",
      endpoint="https://api.mutagent.io",
      environment="production",
      batch_size=10,
      batch_interval_ms=5000,
      debug=False,
      source="sdk",
  )
  ```
</CodeGroup>

### Configuration Options

| Option            | Type      | Default                     | Description                                                                                                                                                                                   |
| ----------------- | --------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`          | `string`  | **Required**                | Your MutagenT API key for authentication.                                                                                                                                                     |
| `endpoint`        | `string`  | `"https://api.mutagent.io"` | The MutagenT API endpoint URL.                                                                                                                                                                |
| `environment`     | `string`  | `undefined`                 | Environment label attached to all traces (e.g., `"production"`, `"staging"`, `"development"`).                                                                                                |
| `batchSize`       | `number`  | `10`                        | Number of spans to buffer before triggering an automatic flush.                                                                                                                               |
| `flushIntervalMs` | `number`  | `5000`                      | Maximum time in milliseconds between automatic flushes.                                                                                                                                       |
| `debug`           | `boolean` | `false`                     | When enabled, logs span start/end events to the console for debugging.                                                                                                                        |
| `source`          | `string`  | `"sdk"`                     | Source identifier attached to traces. Integration packages override this automatically. Valid values: `"sdk"`, `"langchain"`, `"langgraph"`, `"vercel-ai"`, `"openai"`, `"otel"`, `"manual"`. |

<Note>
  The Python SDK uses snake\_case parameter names (`api_key`, `batch_size`, `batch_interval_ms`). The TypeScript SDK uses camelCase (`apiKey`, `batchSize`, `flushIntervalMs`).
</Note>

## Environment Variables

You can provide your API key and endpoint via environment variables instead of passing them directly:

```bash theme={null}
# .env
MUTAGENT_API_KEY=mt_xxxxxxxxxxxx
MUTAGENT_API_URL=https://api.mutagent.io
```

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { initTracing } from "@mutagent/sdk/tracing";

  initTracing({
    apiKey: process.env.MUTAGENT_API_KEY!,
    endpoint: process.env.MUTAGENT_API_URL,
  });
  ```

  ```python Python theme={null}
  import os
  from mutagent.tracing import init_tracing

  init_tracing(
      api_key=os.environ["MUTAGENT_API_KEY"],
      endpoint=os.environ.get("MUTAGENT_API_URL", "https://api.mutagent.io"),
  )
  ```
</CodeGroup>

## Lazy Initialization

In TypeScript, if you set the `MUTAGENT_API_KEY` environment variable, you can skip calling `initTracing()` entirely. The SDK will automatically initialize tracing on the first `startSpan()` call using the environment variable.

```typescript theme={null}
// No initTracing() call needed -- just set MUTAGENT_API_KEY in your environment

import { withTrace } from "@mutagent/sdk/tracing";

// Tracing initializes automatically on first use
const result = await withTrace({ kind: "chain", name: "my-pipeline" }, async (span) => {
  return "done";
});
```

This lazy initialization:

* Only attempts once per process lifecycle
* Reads `process.env["MUTAGENT_API_KEY"]` at the time of the first span creation
* Uses the default endpoint (`https://api.mutagent.io`) and default batch settings
* Resets when `shutdownTracing()` is called, allowing re-initialization

<Note>
  Lazy initialization is convenient for development and simple scripts. For production applications, prefer calling `initTracing()` explicitly so you can configure the `environment`, `batchSize`, and `debug` options.
</Note>

## Shutdown and Graceful Cleanup

Always call `shutdownTracing()` before your process exits. This ensures all buffered spans are flushed to the MutagenT API.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { initTracing, shutdownTracing } from "@mutagent/sdk/tracing";

  initTracing({ apiKey: process.env.MUTAGENT_API_KEY! });

  // Your application logic here...

  // Before exit: flush remaining spans
  await shutdownTracing();
  ```

  ```python Python theme={null}
  import asyncio
  from mutagent.tracing import init_tracing, shutdown_tracing

  init_tracing(api_key="mt_xxxxxxxxxxxx")

  # Your application logic here...

  # Before exit: flush remaining spans
  asyncio.run(shutdown_tracing())
  ```
</CodeGroup>

<Tip>
  The Python SDK automatically registers an `atexit` handler, so `shutdown_tracing()` is called when the process exits normally. It is still good practice to call it explicitly for predictable behavior.
</Tip>

### What `shutdownTracing()` Does

1. Stops the background flush timer
2. Flushes all remaining buffered spans to the API
3. Clears all active span state
4. Resets the tracing system completely, including the lazy initialization flag (can be re-initialized with a new `initTracing()` call or via lazy init from `MUTAGENT_API_KEY`)

## Idempotency and Re-initialization

In TypeScript, calling `initTracing()` a second time silently shuts down the previous configuration and replaces it with the new one. This is useful for reconfiguring tracing in tests.

In Python, calling `init_tracing()` a second time logs a warning and is a no-op. Call `shutdown_tracing()` first, then `init_tracing()` again to reconfigure.

## Integration with Framework Packages

If you are using a MutagenT integration package (e.g., `@mutagent/langchain`, `@mutagent/langgraph`, `@mutagent/openai`, `@mutagent/vercel-ai`, `@mutagent/mastra`), the integration handles tracing initialization internally. You typically do **not** need to call `initTracing()` yourself -- the integration configures it when you create its callback handler or wrapper.

However, if you want to customize tracing configuration (e.g., change batch size or enable debug mode), you can call `initTracing()` **before** creating the integration handler, and the integration will use your existing configuration.

<CodeGroup>
  ```typescript TypeScript (with LangChain) theme={null}
  import { initTracing } from "@mutagent/sdk/tracing";
  import { MutagentCallbackHandler } from "@mutagent/langchain";

  // Optional: customize tracing config
  initTracing({
    apiKey: process.env.MUTAGENT_API_KEY!,
    batchSize: 20,
    debug: true,
  });

  // Integration uses the existing tracing setup
  const handler = new MutagentCallbackHandler();
  ```

  ```typescript TypeScript (standalone) theme={null}
  import { initTracing, shutdownTracing, withTrace } from "@mutagent/sdk/tracing";

  initTracing({
    apiKey: process.env.MUTAGENT_API_KEY!,
    environment: "development",
    debug: true,
  });

  const result = await withTrace({ kind: "chain", name: "my-pipeline" }, async (span) => {
    // Your traced code here
    return "done";
  });

  await shutdownTracing();
  ```
</CodeGroup>

## Batch Collection Behavior

The tracing system buffers spans in memory and sends them in batches to minimize network overhead. Understanding the flush behavior helps with tuning:

| Trigger                       | Behavior                        |
| ----------------------------- | ------------------------------- |
| Buffer reaches `batchSize`    | Immediate async flush           |
| `flushIntervalMs` timer fires | Flush whatever is in the buffer |
| `shutdownTracing()` called    | Force flush all remaining spans |

Spans are grouped by `traceId` in the HTTP payload, so spans belonging to the same trace are always sent together (within a single batch).

<Warning>
  If your process exits without calling `shutdownTracing()`, any spans still in the buffer will be lost. In TypeScript, the flush timer uses `unref()` so it does not keep the process alive -- this means you must explicitly flush before exit.
</Warning>

### Retry Behavior

Failed flush attempts are retried with exponential backoff:

* **Max retries**: 3
* **Base delay**: 1000ms (doubles each retry: 1s, 2s, 4s)
* **HTTP timeout**: 10 seconds per request (via `AbortController`)
* If all retries fail, the spans in that batch are dropped and a warning is logged in debug mode

## Checking Initialization Status

Use `isTracingInitialized()` to check whether the tracing module has been initialized. This is useful for conditional tracing logic or verifying setup in tests.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { isTracingInitialized } from "@mutagent/sdk/tracing";

  if (isTracingInitialized()) {
    console.log("Tracing is active");
  }
  ```

  ```python Python theme={null}
  from mutagent.tracing import is_tracing_initialized

  if is_tracing_initialized():
      print("Tracing is active")
  ```
</CodeGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Spans are not appearing in the dashboard">
    1. Verify your API key is correct and has write permissions
    2. Enable `debug: true` in your tracing config to see span start/end logs in the console
    3. Make sure you call `shutdownTracing()` before your process exits -- buffered spans may not have been flushed
    4. Check that the `endpoint` is reachable from your environment
  </Accordion>

  <Accordion title="initTracing throws 'apiKey is required'">
    The `apiKey` field is required and cannot be empty. Make sure your environment variable is set:

    ```bash theme={null}
    echo $MUTAGENT_API_KEY  # Should print your key
    ```
  </Accordion>

  <Accordion title="Duplicate or missing parent-child links">
    Context propagation relies on `AsyncLocalStorage` (TypeScript) or `contextvars` (Python). If you are using worker threads, forked processes, or certain test runners that reset async context, parent-child linking may not work as expected. Use the `parentSpanId` option to manually link spans in these cases.
  </Accordion>

  <Accordion title="High memory usage from span buffering">
    If your application produces a very high volume of spans, reduce `batchSize` to flush more frequently, or reduce `flushIntervalMs` to flush on a shorter timer. The default settings (10 spans / 5 seconds) are designed for moderate throughput.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Tracing API Reference" href="/tracing/api">
    Learn about decorators, wrappers, and low-level span primitives.
  </Card>

  <Card title="Tracing Overview" href="/tracing/overview">
    Understand core concepts, SpanKind taxonomy, and architecture.
  </Card>
</CardGroup>
