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

# Tracing

> Implement tracing with the Muxx TypeScript SDK.

Tracing helps you understand the flow of operations in your LLM application.

## Creating Traces

### With Callback

```typescript theme={null}
import { Muxx } from 'muxx';

const muxx = new Muxx();

const result = await muxx.trace('my-operation', async () => {
  // All LLM calls inside are grouped under this trace
  return 'result';
});
```

### With Options

```typescript theme={null}
const result = await muxx.trace(
  'my-operation',
  async () => {
    return 'result';
  },
  {
    metadata: { userId: 'user_123' },
    captureInput: true,
    captureOutput: true,
  }
);
```

## Creating Spans

Spans represent individual operations within a trace.

```typescript theme={null}
await muxx.trace('document-processing', async () => {
  const extracted = await muxx.span('extraction', async () => {
    // Extraction logic
    return extractedData;
  });

  const result = await muxx.span('summarization', async () => {
    // Summarization logic
    return summary;
  });

  return result;
});
```

## Nested Spans

```typescript theme={null}
await muxx.trace('complex-operation', async () => {
  await muxx.span('step-1', async () => {
    await muxx.span('step-1a', async () => {
      // Deeply nested operation
    });

    await muxx.span('step-1b', async () => {
      // Another nested operation
    });
  });
});
```

## Manual Trace Management

For more control, use manual trace management:

```typescript theme={null}
const trace = muxx.startTrace('my-operation');

try {
  // Your code here
  const span = trace.startSpan('sub-operation');
  try {
    // Span code
  } finally {
    span.end();
  }
} finally {
  trace.end();
}
```

## Adding Metadata

```typescript theme={null}
await muxx.trace(
  'user-request',
  async () => {
    // Add metadata to current span
    muxx.getCurrentSpan()?.setMetadata({
      responseLength: response.length,
    });

    return response;
  },
  {
    metadata: {
      userId: 'user_123',
      environment: 'production',
    },
  }
);
```

## Error Handling

Errors are automatically captured:

```typescript theme={null}
await muxx.trace('risky-operation', async () => {
  throw new Error('Something went wrong');
  // Error is captured with stack trace
});
```

Add custom error context:

```typescript theme={null}
await muxx.trace('operation', async () => {
  try {
    await riskyCode();
  } catch (error) {
    muxx.getCurrentSpan()?.setError(error as Error, {
      recoveryAttempted: true,
    });
    throw error;
  }
});
```

## Parallel Operations

Traces handle parallel operations correctly:

```typescript theme={null}
await muxx.trace('parallel-calls', async () => {
  const [result1, result2] = await Promise.all([
    muxx.span('call-1', async () => client.chat.completions.create({ ... })),
    muxx.span('call-2', async () => client.chat.completions.create({ ... })),
  ]);

  return { result1, result2 };
});
```

## Express Middleware

For Express apps, use the middleware:

```typescript theme={null}
import express from 'express';
import { Muxx } from 'muxx';

const app = express();
const muxx = new Muxx();

// Add tracing middleware
app.use(muxx.expressMiddleware());

app.post('/chat', async (req, res) => {
  // Each request automatically gets its own trace
  const response = await client.chat.completions.create({ ... });
  res.json(response);
});
```
